在对象内管理图形用户界面
10196 为本文评分:
暂无评分
在对象内管理图形用户界面
匿名 2016年5月5日,星期四
在许多项目中,对象会包含一个用于显示或操作数据的图形用户界面(GUI)。这里有一个示例——可以作为模板使用——展示了如何实现这一点。更多信息请参阅代码中的方法头和注释。要尝试它:
- 将以下代码保存到名为 myobject__define.pro 的文件中。
- 在 IDL 开发环境中打开并编译该文件。
- 在命令提示符下执行以下操作:
a.
o = obj_new('myobject')b.o->ConstructGUI
;############################################################################## ; 此示例演示了如何从对象管理图形用户界面(GUI)。 ;##############################################################################
;------------------------------------------------------------------------------ ;+ ; 由 XMANAGER 调用的事件处理程序。这由 MYOBJECT::CONSTRUCTGUI 中 WIDGET_BASE 的 ; EVENT_PRO 关键字定义。 ; ; :参数: ; sEvent: 输入,必需,类型="结构体" ; 一个 IDL 微件事件结构体 ;- pro myobject_event, sEvent compile_opt idl2, logical_predicate
; 获取存储在顶级 base 微件的 UVALUE 中的 MYOBJECT 实例 widget_control, sEvent.top, GET_UVALUE=oMyObject
; 将事件结构体发送到对象的事件处理程序 oMyObject->Event, sEvent end
;------------------------------------------------------------------------------ ;+ ; 当对象的 GUI 实现(realized)时,将调用此例程。这由 ; MYOBJECT::CONSTRUCTGUI 中 WIDGET_BASE 的 NOTIFY_REALIZE 关键字定义。 ; ; :参数: ; tlb: 输入,必需,类型="长整型" ; GUI 顶级 base 的微件 ID ;- pro myobject_notifyrealize, tlb compile_opt idl2, logical_predicate
; 获取存储在顶级 base 微件的 UVALUE 中的 MYOBJECT 实例 widget_control, tlb, GET_UVALUE=oMyObject
; 调用对象的 NOTIFYREALIZE 方法 oMyObject->NotifyRealize end
;------------------------------------------------------------------------------ ;+ ; 通过 OBJ_DESTROY 销毁对象时调用的生命周期方法。它简单地 ; 调用处理所有清理工作的析构方法。 ;- pro myobject::Cleanup compile_opt idl2, logical_predicate self->Destruct end
;------------------------------------------------------------------------------ ;+ ; 关闭(销毁)对象的 GUI ;- pro myobject::CloseGUI compile_opt idl2, logical_predicate
; 如果对象的顶级 base ID 不是有效的微件 ID,则不执行任何操作 if ~widget_info(self.tlb, /VALID_ID) then return
self->UpdateText,'Closing the GUI...' wait, 1.0 widget_control, self.tlb, /DESTROY self.tlb = 0 end
;------------------------------------------------------------------------------ ;+ ; 构建图形用户界面 ;- pro myobject::ConstructGUI compile_opt idl2, logical_predicate
if widget_info(self.tlb, /VALID_ID) then begin ; 对象的顶级 base ID 有效。不要构建另一个 GUI。 return endif
self.tlb = widget_base(/COLUMN, $ ; 此关键字定义了 XMANAGER 将使用的事件处理程序名称 EVENT_PRO='myobject_event', $ ; 此关键字定义了 GUI 实现时要调用的例程名称 NOTIFY_REALIZE='myobject_notifyrealize', $ TITLE="My Object's GUI", $ TLB_FRAME_ATTR=1, $ ; 不允许 GUI 调整大小 /TLB_KILL_REQUEST_EVENTS)
xSize = 300 wDraw = widget_draw(self.tlb, /BUTTON_EVENTS, /MOTION_EVENTS, $ XSIZE=xSize, YSIZE=200) wText = widget_text(self.tlb, SCR_XSIZE=xSize, /SCROLL, UNAME='text', $ YSIZE=10) wBase = widget_base(self.tlb, /ALIGN_RIGHT, /ROW) wButton = widget_button(wBase, UNAME='ok', VALUE='OK') wButton = widget_button(wBase, UNAME='close', VALUE='Close')
ss = get_screen_size() wGeom = widget_info(self.tlb, /GEOMETRY) widget_control, self.tlb, XOFFSET=(ss[0]-wGeom.scr_xSize)/2, $ YOFFSET=(ss[1]-wGeom.scr_ySize)/2
; 将顶级 base 的 UVALUE 设置为对象的实例。这样, ; 我们可以在事件处理程序中访问对象,并将事件发送到对象方法中 widget_control, self.tlb, SET_UVALUE=self widget_control, self.tlb, /REALIZE end
;------------------------------------------------------------------------------ ;+ ; 此方法用于在对象销毁时进行清理(例如清理堆变量) ;- pro myobject::Destruct compile_opt idl2, logical_predicate self->CloseGUI end
;------------------------------------------------------------------------------ ;+ ; 对象的主要事件处理方法。这将在 MYOBJECT_EVENT 中被调用。 ; ; :参数: ; sEvent: 输入,必需,类型="结构体" ; 一个 IDL 微件事件结构体 ;- pro myobject::Event, sEvent compile_opt idl2, logical_predicate
; 为每种类型的微件事件定义了一个方法。将事件发送到正确的处理程序。 case tag_names(sEvent, /STRUCTURE_NAME) of 'WIDGET_BUTTON': self->EventButton, sEvent 'WIDGET_DRAW': self->EventDraw, sEvent 'WIDGET_KILL_REQUEST': begin self->UpdateText,'[X] was pressed' self->CloseGUI end else: help, sEvent endcase end
;------------------------------------------------------------------------------ ;+ ; 此方法处理按钮微件事件 ; ; :参数: ; sEvent: 输入,必需,类型="结构体" ; 一个 IDL {WIDGET_BUTTON} 结构体 ;- pro myobject::EventButton, sEvent compile_opt idl2, logical_predicate
case widget_info(sEvent.id, /UNAME) of 'close': begin self->UpdateText,'Close button pressed' self->CloseGUI end 'ok': self->UpdateText,'OK button pressed' else: endcase end
;------------------------------------------------------------------------------ ;+ ; 此方法处理绘图微件事件。 ; ; :参数: ; sEvent: 输入,必需,类型="结构体" ; 一个 IDL {WIDGET_DRAW} 结构体 ;- pro myobject::EventDraw, sEvent compile_opt idl2, logical_predicate
case sEvent.type of 0: begin case sEvent.press of 1: str = 'Left mouse button pressed' 2: str = 'Middle mouse button pressed' 4: str = 'Right mouse button pressed' else: endcase end 1: begin case sEvent.release of 1: str = 'Left mouse button released' 2: str = 'Middle mouse button released' 4: str = 'Right mouse button released' else: endcase end 2: str = 'Mouse motion' else: endcase
if (n_elements(str) EQ 0) then return str += ' [' + strtrim(sEvent.x, 2) + ',' + strtrim(sEvent.y, 2) + ']' self->UpdateText, str end
;------------------------------------------------------------------------------ ;+ ; 此方法用于访问微件 ID ; ; :返回: ; 如果输入了有效的 NAME (uname) 则返回微件 ID,否则返回 0 ; ; :参数: ; name: 输入,必需,类型="字符串" ; 要返回其 ID 的微件的 uName ; ; :关键字: ; PARENT: 输入,可选,类型="整数" ; 要搜索其子微件的父微件的 ID。如果未设置,将使用 GUI 的顶级 base。 ;- function myobject::GetWID, name, $ PARENT=wParent compile_opt idl2, logical_predicate
if (n_elements(wParent) EQ 0) then wParent = self.tlb return, widget_info(wParent, FIND_BY_UNAME=name) end
;------------------------------------------------------------------------------ ;+ ; 用于初始化对象实例的生命周期方法 ; ; :返回: ; 如果对象初始化成功则返回 1,否则返回 0。 ;- function myobject::Init compile_opt idl2, logical_predicate ; 在此处初始化任何成员变量 return, 1 end
;------------------------------------------------------------------------------ ;+ ; 在 GUI 实现后由 MYOBJECT_NOTIFYREALIZE 调用。 ;- pro myobject::NotifyRealize compile_opt idl2, logical_predicate ; 启动事件处理程序 xmanager, 'myobject', self.tlb end
;------------------------------------------------------------------------------ ;+ ; 该方法将字符串或字符串数组添加到文本微件 ; ; :参数: ; strNew: 输入,必需,类型="字符串" ; 要添加到文本微件的字符串 ;- pro myobject::UpdateText, strNew compile_opt idl2, logical_predicate
wText = self->GetWID('text') ySize = (widget_info(wText, /GEOMETRY)).ySize widget_control, wText, /APPEND, SET_VALUE=strNew widget_control, wText, GET_VALUE=str widget_control, wText, SET_TEXT_TOP_LINE=(n_elements(str)-ySize+2)>0 end
;------------------------------------------------------------------------------ ;+ ; 类结构定义 ; ; :字段: ; tlb: GUI 的顶级 base 的微件 ID。这可用于访问 GUI 中的所有微件。 ;- pro myobject__define compile_opt idl2, logical_predicate void = {myobject $ , tlb: 0L $ } end