5、IDL培训应用程序构造篇(PPT)

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

IDL高级培训应用程序构造篇编程篇-建立、管理应用程序IDL有两种应用程序管理方法:主程序和工程主程序:建立与程序名同名的.pro文件,编译执行。protest…end在这种方式下,根据IDL的自动编译规则,所有被调用的子程序或者与主程序写入同一个文件并放置在主程序的上部;或者写成与子程序同名的.pro文件,存储在可搜索的路径下。(子程序指过程或函数)工程:建立若干个.pro文件,每个文件不必与任何子程序同名。指定其中一个过程为主程序,该过程的名字作为工程执行时首先调用的过程(即runcommand)。在这种方式下,由于程序编写未必遵守IDL的自动编译规则,因此在运行前必须编译工程中所有的文件。分发:将源程序编译为.sav文件。•主程序方式,需手工编译、存储为.sav文件.compileapp_proresolve_allsave,/routines,app_pro,app_sav•工程方式,设置工程属性为形成.sav文件,使用工程菜单项下的build选项即可。编程篇-应用程序结构XMangerWidgetCreationRoutine(TLB)callxmanagerEventHandlerCallingRoutineEventstructureOnlyifTLBisdestoryed主程序调用相关子程序编程篇-主程序结构主程序的一般结构:proapp_procompile_optidl2createtoplayoutbase(TLB)createguibaseonTLB(initialapplication)realizeTLBcollectuserinformationcallxmanager[,/NO_BLOCK]endinitialapplication该过程可以在主程序里进行。但更好的办法是编写单独的过程,用TLB的notify_realize关键字指定过程名,当realizeTLB时执行。/NO_BLOCK使用该关键字,主程序运行后,命令行仍然可以使用,主程序自身仍可修改编译,有利于调试。compile_optidl2改变默认编译选项,idl2表示defint32和strictarr编程篇-TLBTLB的三种基本形式standardTLB:tlb_id=widget_base(group_leader=group$,uname=’tlb‘,title=’idlapp‘)适用于一般的应用程序,可以单独运行或被调用。group可以不存在。modalTLB:tlb_id=widget_base(group_leader=group,/modal,uname=’tlb‘,title=’modalapp‘)适用于对话框类的应用程序,通常不可以单独运行,只能被调用。group必须合法。调用该类程序后,调用者暂时挂起,直至该程序返回。floatingTLB:tlb_id=widget_base(group_leader=group,/floating,uname=’tlb‘,title=’floatingapp‘)适用于任务优先类的应用程序,通常不可以单独运行,只能被调用。group必须合法。调用该类程序后,调用者可以继续运行。该程序总在最前面。编程篇-GUI基本组件容器组件:widget_base:任何GUI组件必须在某BASE组件上实现。一个BASE组件可以包含其它的BASE。GUI组件:widget_draw:图形窗口,所有的图形、图像显示均在此实现widget_label:标签,不可编辑的文本,可用于提示、说明widget_button:按钮,分为pushbutton、radiobutton和checkbox。可用于命令、单选以及多选widget_text:文本框,可编辑的文本,可用于用户输入widget_slider:滑动条,分为水平和垂直,可用于调整预设值widget_listbox:列表框,用于项目选择widget_droplist:下拉列表框widget_table:表格,可编辑的二维数据组件标识:每一个组件创建时都会产生一个id,并且可以指定一个uname。这些都是以后检索、操作这个组件的标识。TrueType字体设置:draw:使用device,set_font=fnt_str,/tt_font,输出时使用font=1。通常在与用户交互时使用。其它:使用font=fnt_str。通常在创建时使用编程篇-GUI其他组件CompoundWidgets组合组件是一组完备、自容、可重用的应用程序,使用时与基本组件大致相同,但它们是用IDL编写的。所有组合组件得名称都以cw_开始。组合组件包括一下几类:•Animation(动画)•ColorManipulation(颜色操作)•DataEntryandDisplay(数据输入输出)•ImageManipulation(图像处理)•Orientation(定位操作)•UserInterface(用户界面)组合组件一般目的是扩充了相应的基本组件的功能。Dialogs对话框用于用户界面,可以象组件一样使用,但它不属于组件构造层次。对话框是modal元素,当调用一个对话框时,其他界面元素暂时刮起直至对话框返回。对话框包括以下几种:•FileandDirectorySelection:DIALOG_PICKFILE•MessageDIALOG_MESSAGE•Printing:DIALOG_PRINTJOB、DIALOG_PRINTERSETUP编程篇-GUI的构造层次及实现TLBbasebasebasebasebaseitemitemitemitemGUI层次:EveryGUIelementisoverBASEGUI实现:指GUI第一次在屏幕上显示widget_control,tlb,/realizeTLB实现后,所有层次关系属于TLB的组件均实现。可以使用map=0关键字使某些子层次暂不显示。编程篇-xmanagerXmanager提供事件循环、监视并发送事件至事件处理程序,直至程序结束。xmanager,name,widget_id,/just_reg,/no_block,group_leader=widget_id,event_handler=`event_pro’,cleanup=‘cleanup_pro’name:创建TLB的过程名widget_id:TLB的idjust_reg:登记一个TLB,但并不进入事件循环no_block:在程序运行期间仍然允许IDL环境可以使用group_leader:指定上一层次的widget_idevent_handler:指定事件处理程序。缺省为name_event语法:event_pro,eventcleanup:指定程序退出时执行的程序。若指定,拥有最高优先级语法:clenup_pro,widget_id程序运行了吗?Result=XREGISTERED(name[,/NO_SHOW])编程篇-事件结构事件用户在GUI上的每一个‘认可的’操作都会产生一个事件,xmanager将事件信息打包传给IDL,IDL将事件信息解读后打包成一个结构类型的数据,即事件结构,并把这个事件结构做为唯一的位置参数发送给事件处理程序。事件结构事件结构是一个命名结构。包括一个结构名、三个公共字段和一些个体字段。{event_type,id:,top:,handler,…}even_type:标识事件类型。id:长整数,产生事件的标识符。top:长整数,id所表示的组件所在的TLB。handler:长整数,事件处理程序标识符。事实上,由于事件处理程序总与某一特定的组件相联系,该标识符就是组件标识符。任何前三个字段定义与上述意义相同的命名字段,都可以认为是IDL的一个事件结构。编程篇-事件处理事件处理方式当事件发生时,IDL会从当前组件层次开始,逐层向上查找与该事件相关联的事件处理程序。handler字段记录该组件的标识。TLBABFGDECEventoccurshereEventhandlerTLBABFGDECEventoccurshereEventhandlerEventhandler{,id:G,top:A,handler:A,…}{,id:G,top:A,handler:F,…}编程篇-为组件指定事件处理程序为组件指定事件处理程序1.由xmanager指定的事件处理程序(通常是TLB)处理所有事件。2.使用组件创建时的关键字event_pro或event_func为每一个事件单独指定一个处理程序。注意到:xmanager总会为其直接管理的组件(通常是TLB)指定一个事件处理程序(而且是一个过程),因此,该组件的事件处理程序不能用event_pro或event_func指定。编程篇-事件处理程序事件处理程序事件处理程序可以是过程或函数。过程:事件处理完毕后被中止,程序等待下一个事件。函数:由于函数有返回值,如果返回值是一个结构,又恰恰符合IDL事件结构标准,则IDL会将这个返回值做为一个事件处理。(此乃伪事件,可以用来‘欺骗’IDL)事件处理程序接受并且只接受一个位置参数,event事件处理程序基本结构(TLB结构)proapp_pro_event,eventuname=widget_info(event.id,/uname)caseunameof‘TLB_uname’:beginiftag_names(event,/structure_name)eq'widget_kill_request')thenbegin……(somecleanupwork)widget_control,event.top,/destroyreturnendifend‘uname1’:begin……(dosomething)end‘uname2’:uname2_event_pro,event(如果已经为uname2组件指定了该事件处理程序,则该行略去)else:endcaseend编程篇-数据传递注意到,对于一个应用程序,IDL所做的只是“捕获”各种组件事件,将事件结构做为唯一的位置参数传递给事件处理程序,因此,无法通过通常的参数传递的方法交换数据。IDL提供了user_value,通过为widget_id“绑定”user_value的方法传递数据。方法:widget_control,widget_id,set_uvalue=value[,/NO_COPY]将用户数据绑定到一个组件widget_control,widget_id,get_uvalue=value[,/NO_COPY]从一个组件获取用户数据为TLB绑定用户数据一般地,在主程序中,xmanager之前,会创建一个结构,该结构的各个字段是用户在整个应用程序运行期间所需要相互传递的数据。然后把这个结构绑定给TLB。sState={…}widget_control,TLB_id,set_uvalue=sState当事件发生时,IDL会把事件结构传递给事件处理程序,事件处理程序可以通过事件结构的top字段来获得用户数据。Widget_control,event.top,get_uvalue=sState注意到,用户数据的传递是值引用,这就意味着一旦在事件处理程序里改变了用户数据的值,必须把改变了值的用户数据传回给top才会使改变了的值在其它事件处理程序里生效。Widget_control,event.top,set_uvalue=sState编程篇-数据传递有问题发生事实上,sState是一个局部变量,因此当绑定给TLB_ID时,是copy了一份到全局内存。而当事件处理程序获得用户数据时,又是从全局内存中copy一份到该事件处理程序的局部变量中。于是,一份数据就有了3份copy。指定/NO_COPY关键字,就只使用一份。烦恼:(1)copy一事会给我们带来烦恼。因为一旦no_copy,则当前的用户数据变量就不再有效。这意味着返回用户数据的命令应该是事件处理程序的最后一行,显然这是不现实的。(2)事实

1 / 23
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功