|||
界面程序下的数据传递包括下面三种:(1)系统变量;(2)Common;(3)组件的uValue。经常用的是第三种方法,界面程序利用最顶级组件的uValue传递各种类型数据,一般用结构体或指针进行。
附界面传递的示例代码,注意代码中的注释和鼠标在界面中移动时鼠标信息如何在对话框中显示的。
;+ ; 《IDL语言程序设计》 ; --数据快速可视化与ENVI二次开发(配盘) ; ; 示例源代码 ; ; 作者: 董彦卿 ; ; 联系方式:sdlcdyq@sina.com ; ;- ;界面关闭响应程序 PRO WIDGET_EXAMPLES_CLEANUP, tlb ;获取uValue WIDGET_CONTROL,tlb,get_uvalue=pstate ;因是指针,故需要销毁 PTR_FREE, pState END ;界面事件响应程序 PRO WIDGET_EXAMPLES_EVENT, event
;获得顶base的uvalue,即组件信息指针结构体 WIDGET_CONTROL,event.TOP,get_uvalue=pstate
CASE TAG_NAMES(event,/STRUCTURE_NAME) OF ;关闭事件 'WIDGET_KILL_REQUEST': BEGIN ;提示是否关闭 tmp = DIALOG_MESSAGE('确认关闭?',$ title ='关闭系统',/question) IF tmp EQ 'Yes' THEN BEGIN ;注意销毁之前创建的指针 PTR_FREE, pState ;销毁界面 WIDGET_CONTROL,event.TOP,/destroy RETURN ENDIF RETURN END ;draw区域 'WIDGET_DRAW': BEGIN
CASE event.TYPE OF ;注意不同的类型对应的不同的事件 ;键盘和鼠标等各自事件的结构体内容 0: BEGIN CASE event.PRESS OF 1: value = '左键按下' 2: value = '中键按下' 4: BEGIN value = '右键按下' ;弹出右键菜单 WIDGET_DISPLAYCONTEXTMENU, event.ID, event.X, $ event.Y, (*pState).CONTEXTBASE END ELSE: PRINT,event.PRESS ENDCASE END 1: BEGIN CASE event.RELEASE OF 1: value = '左键释放' 2: value = '中键释放' 4: value = '右键释放' ELSE: PRINT,event.RELEASE ENDCASE END 2: value = '鼠标移动' 7: BEGIN IF event.CLICKS GT 0 THEN value='滚轮前滚' $ ELSE value='滚轮后滚' END 4: BEGIN value = '暴露事件' ;设置显示组件的大小 drawSize = WIDGET_INFO((*pState).MYDRAW,/Geom) ;适应性显示 TVSCL,CONGRID(DIST(400),drawSize.XSIZE,drawSize.YSIZE) END 5: value = 'key = ' +STRTRIM(STRING(event.CH),2) 6: value = 'key = ' +STRTRIM(STRING(event.CH),2) ELSE:PRINT,event.TYPE ENDCASE ; WIDGET_CONTROL,(*pstate).TEXT1,set_value= value END ELSE: ENDCASE
;获取当前组件的uName uName = WIDGET_INFO(event.ID,/uname) ;点击了界面上按钮 IF uName EQ 'button' THEN BEGIN tmp = DIALOG_MESSAGE((*pState).TESTSTR,/Infor) ENDIF ;点击了右键菜单中的按钮 IF uName EQ 'contexButton1' THEN tmp = DIALOG_MESSAGE('右键菜单1',/infor) IF uName EQ 'contexButton2' THEN tmp = DIALOG_MESSAGE('右键菜单2',/infor) ;修改界面大小 IF uName EQ 'tlb' THEN BEGIN ;显示组件大小适应程序大小 drawXSize = event.X -(*pState).DRAWSPACE[0] drawYSize = event.Y -(*pState).DRAWSPACE[1] ;设置tlb大小(可忽略,因Draw组件后面已经设置了大小) WIDGET_CONTROL,event.TOP,xSize = event.X,ySize = event.Y ;设置显示组件的大小 WIDGET_CONTROL,(*pState).MYDRAW,xsize = drawXSize, ySize = drawYSize ;适应性显示 TVSCL,CONGRID(DIST(400),drawXSize,drawYSize) ENDIF END ; PRO WIDGET_EXAMPLES
; 创建一个主Base窗体 base1 = WIDGET_BASE(TITLE='界面程序示例', $ mBar = mBar , $ uname ='tlb', $ ;按行排列 /COLUMN, $
;重设置大小时产生事件 /TLB_SIZE_EVENTS,$ ;关闭时产生事件 /TLB_KILL_REQUEST_EVENTS) ;创建系统菜单 wFile = WIDGET_BUTTON(mbar,value = '文件(&F)') wOpen = WIDGET_BUTTON(wFile, value = '打开(&O)') wExit = WIDGET_BUTTON(wFile, value = '退出(&E)', $ ;添加分隔线 /Separator) ;创建一个按钮 base2=WIDGET_BASE(base1,/row) label1=WIDGET_LABEL(base2,$ value='当前事件:') text1=WIDGET_TEXT(base2, $ xSize =10) button = WIDGET_BUTTON(base2,$ value ='按钮', $ uName ='button') mydraw=WIDGET_DRAW(base1,$ retain=0,$ ;设置大小 xsize=400,$ ysize=400,$ ;滚轮时产生事件 /wheel_events,$ ;点击按钮时产生事件 /button_events,$ ;暴露(从遮挡到最前显示时)时产生事件 /expose_events,$ ;鼠标移动时产生事件 /motion_events,$ ;键盘敲击时事件 /keyboard_events,$ ;设置组件的uName,即名字。 uname='mydraw') ;例示 WIDGET_CONTROL, base1, /REALIZE ;创建右键菜单界面 contextBase = WIDGET_BASE(mydraw, /CONTEXT_MENU) ;右键菜单中菜单选项 button1 = WIDGET_BUTTON(contextBase, $ VALUE='右键菜单1', $ uname = 'contexButton1') button2 = WIDGET_BUTTON(contextBase, $ VALUE='右键菜单2', $ uname = 'contexButton2')
;获取系统初始化颜色模式 DEVICE, Get_Decomposed = oriD ;显示伪彩色图像 DEVICE, decomposed =0 ;载入系统颜色表 LOADCT,23 ;显示一个400*400的方形图像 imgData = DIST(400) TVSCL,imgData
;获取组件的大小信息 sz = WIDGET_INFO(base1,/geom) drawSZ = WIDGET_INFO(myDraw,/geom) ;显示区域与主界面的边界间隔 drawSpace = [sz.XSIZE,sz.YSIZE] - [drawSZ.XSIZE,drawSZ.YSIZE]
;创建结构体,包含各个组件ID和参数 state={label1:label1,$ contextBase: contextBase, $ text1:text1,$ oriD: oriD, $ imgData : imgData , $ drawSpace: drawSpace, $ testStr : '初始字符串!',$ mydraw:mydraw} ;创建指针 pstate=PTR_NEW(state,/no_copy) ;将指针信息存到tlb的uvalue中保存 WIDGET_CONTROL,base1,set_uvalue=pstate ;关联产生事件
XMANAGER, 'WIDGET_EXAMPLES', base1, $ cleanup = 'WIDGET_EXAMPLES_CLEANUP',/NO_BLOCK ;也可用这个方式:直接指定事件程序,event_handler ='abc'
END |
另外对象使用时也可以用uValue,应用情形:如以浮点型数组,用IDLgrImage显示时数据会自动拉伸到byte型,再通过IDLgrImage的getProperty获取后为byte型数组,与浮点型相比的话精度会有所丢失。为了获取原数组值,可以用IDLgrImage的uValue关键字对数据进行备份,当然,这种方式占用的内存对增大,如为了节省保存内存,可以将转换系数存储到uValue中,应用前后进行存储和读取运算。示例代码如下:
IDL> oriArr = dist(200) % Compiled module: DIST. IDL> print,max(oriArr,min = minV) 141.421 IDL> print,minV 0.000000 IDL> oImage = Obj_New('IDLgrImage') IDL> oImage.SetProperty,data = oriArr IDL> oImage.GetProperty,data = storeArr IDL> print,max(storeArr) 141 IDL> help,storeArr STOREARR BYTE = Array[200, 200] IDL> ;解决方法 IDL> oImage.SetProperty,data= oriArr,uValue = oriArr IDL> oImage.GetProperty,data = storeArr,uValue = uArr IDL> help,uArr UARR FLOAT = Array[200, 200] IDL> print,max(uArr) 141.421 IDL> ;解决方法2,按线性函数公式y = k*x+b的格式,这样节省对象占用内存。 IDL> maxV = max(oriArr,min = minV) IDL> ;计算转换系数 IDL> k = 255/(maxV-minV) IDL> b = -minV/(maxV-minV) IDL> ;存储原数组到oImage对象,系数到uvalue中 IDL> oImage.SetProperty,data= oriArr,uValue = [k,b] IDL> ;获取oImage对象中的数据和系数数组 IDL> oImage.GetProperty,data = storeArr,uValue = uArr IDL> ;转换回初始数组 IDL> readData = uArr[0]*storeArr+uArr[1]
|
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-9-1 14:28
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社