IDL(数据分析和图像化应用程序及编程语言)培训_第1页
IDL(数据分析和图像化应用程序及编程语言)培训_第2页
IDL(数据分析和图像化应用程序及编程语言)培训_第3页
IDL(数据分析和图像化应用程序及编程语言)培训_第4页
IDL(数据分析和图像化应用程序及编程语言)培训_第5页
已阅读5页,还剩106页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、IDL 高级培训基础篇基础篇 语法基础1. 变量及其属性 整型为短整型,注意使用L 变量的属性是动态改变的 var=5 为整型 var=var*2.0 变为浮点 NaN:!VALUES.F_NAN、!VALUES.D_NAN var=!VALUES.F_NAN,则finite(var)=1基础篇 语法基础2. 数组 IDL是面向矩阵的语言,几乎所有运算都可以在数组上使用。 数组表达:arrayn,m 表示n列m行(与其他语言有别),按行排列, 0为下标起点 数组引用:arraysubscript,或(array)subscript 下标语法:e、e0:e1、e:*、*、array。 array

2、=make_array(10,10,/integer),sub=indgen(12) 合法的下标表示:array5,5、array2:3,5、array*,4、array*,5:8、array4,4:*、 arraysub、A1,3,5,7:9 reform():array4,4:*为1列4行(列向量),reform(array4,4:*)则为4列1行(行向量) 常数的数组表示:var=5,则var0=5(合法!) 赋值:array2, 4, 6,5=4, 16, 36 where():arraywhere(array lt 0)=-999 数学运算:与普通变量基本相同。 * 和 / :表示两

3、个同维数数组对应元素运算 arr1=indgen(5)+1,arr2=arr1。则:arr1*arr2=1,4,9,16,25,arr1/arr2=1,1,1,1 # 和 #:矩阵运算 arr1(n1,m)#arr2(m,n2)=arr(n1,n2),arr1(n,m1)#arr2(m2,n)=arr(m2,m1) 数组串连:arr1(5,6),arr2(5,2)。则:arr3=arr1,arr2为(5,8) 注意: arr3=arr1,arr2不合法!(一维除外)其他常用函数:array_equal、rebin()、congrid()、expand()、reverse()数组常用函数:基础篇

4、 语法基础基础篇 语法基础3. 结构 一种复合变量,它可以将多种类型的数据存储在一个变量中,对于表示意义相关的数据、程序间交换数据均非常有意义。 类型及定义 命名结构:dot=PIXEL ,x:128 ,y:236 ,color:bytarr(3),定义后可使用FIXEL定义其他结构 dot1=PIXEL ,x:58 ,y:46 ,color:255,0,255、 dot2=PIXEL ,58 ,46 ,255,0,255、dot3= PIXEL 匿名结构:person=name:jack ,id:123456L,定义后无固定结构,可任意改变 person=name:jack ,id:1234

5、56L ,phone:123-4567 引用 变量引用:使用变量名或变量在结构中的位置索引。如:dot.x或dot.(0) 数组变量:s=arr:indgen(10),则s.arr=10将数组所有元素赋值为10。 结构数组 定义:dotarr=replicate(PIXEL ,10),或dotarr=replicate(dot ,10) 引用:dotarr1.x=10、dotarr.x=10将所有结构的x赋值为10、dotarr.y=indgen(10) 结构中的变量的类型和(数组)大小 结构定义后,各变量的数据类型以及数组变量的维数均不可改变。当使用中出现不一致时向原类型转换,不能转换时报错

6、。 var=dot.x*1.0=128.0,为浮点,而dot.x=dot仍为整型。 s.arr=-indgen(8)会改变s.arr中前8个元素的值,而s.arr=-indgen(11)会出错。 结构继承 dot3d=POINT ,INHERITS PIXEL ,z:0 常用函数 creat_struct()、n_tags()、tag_names()、struct_assign()基础篇 语法基础4. 指针 建立动态数据结构的有效工具,是实现IDL面向对象编程和Widget编程的基本要素之一。 IDL 的指针与其他语言的指针有很大的不同,它不是指向存储的地址而仅仅是一个轻型的指向一个堆变量的引

7、用(指针变量)。堆变量可以动态分配(数据类型和数组维数),这意味着传递指针变量就相当于传递动态数据。Pointer ReferencePointer DataPointer in Heap Variables指针基本操作 创建:ptr=ptr_new( initexpr , /allocate_heap , /no_copy ) 释放:ptr_free ,ptr标量数组结构基础篇 语法基础 标量指针 创建:v=5.5,p=ptr_new(v) 引用:print , p ,*p;p1=p,*p1=20,print ,*p 数组指针 创建:arr=findgen(10),p=ptr_new(arr

8、) 引用:print ,(*p)5 结构指针 创建:s=name:joe ,age:40 ,height:180 ,p=ptr_new(s) 引用:print , (*p).name 结构内指针 创建:rec=lon:120 ,lat:20 ,data:ptr_new(findgen(2,10) ,p=ptr_new(rec) 引用:* (*p).data=findgen(2,20) 特殊指针 Null指针:nptr=ptr_new(),仅定义一个指针,并不指向一个堆变量。引用时需重新定义指针。 Empty指针:eptr=ptr_new(/allocate_heap),定义一个指向一个堆变量的

9、指针,但并未定义变量,引用时可以直接定义变量 指针释放 ptr_free ,ptr 相关函数 ptr_valid():ptr_valid(nptr)=0, ptr_valid(eptr)=1 heap_gc:释放没有引用的堆变量 指针数组 ptrarr( d1, . , d8 , /allocate_heap )基础篇 编程基础 IDLDE是IDL的集成开发环境,可以使用IDL命令进行交互式命令运行,编写、调试、运行IDL程序,使用GUI Builer开发用户界面,使用项目管理器管理工程项目等。1. IDL程序 批处理:由一系列IDL命令组成,以IDL-batchfile方式运行。批处理文件运

10、行时并不编译,因此使用控制结构时必须大量使用续行符($),给书写、理解造成困难。 主程序:与批处理相似,但以end结束,以IDL-.run profile方式运行。主程序运行时先编译,因此可以正常使用控制结构。 过程:与主程序相似,但以pro proname开始,以end结束。以IDL-proname方式运行(也可以先运行IDL-.compile proname,编译但不运行)。 函数:与过程相似,但以function fnname开始,以end结束,并以return语句返回一个IDL变量。以IDL-ret=fnname(para_list)方式运行。 在IDL系统中,一个过程或函数即为一个新

11、的IDL命令。 变量作用范围:批处理和主程序方式的变量为全局变量,可以在IDL开发环境中使用。过程和函数的变量为局部变量,只在过程和函数运行过程中有效。基础篇 编程基础2. 参数传递 位置参数:在参数列表中按位置列出参数名,严格的顺序限制。通常用于必选参数。 定义:pro batch ,para1 ,para2 ,. 调用:IDL-batch ,para1 ,para2 , 关键字参数:关键字参数与位置无关,且可以与位置参数混合位置。通常放在位置参数之后,用于可选参数。 定义:pro batch ,keywordname=keywordsymbol ,. 调用:IDL-batch ,keywo

12、rdname=keywordsymbol , IDL-batch ,/keywordname 注意:keywordname用于定义,keywordsymbol用于调用。 引用传递和值传递:所有变量为引用传递,其值会被修改。系统变量、下标变量、表达式和常量均为值传递,原变量的值不被修改。 参数传递了吗?传递了什么? n_params():返回位置参数的个数 keyword_set():关键字参数为不为0常量或已定义的引用传递时返回1,否则返回0 arg_present():关键字参数为引用传递时返回1(无论是否定义),否则返回0 n_elements():关键字参数未传递或未定义返回0,否则返回

13、非0数 基础篇 编程基础3. 错误处理 on_ioerror:当出现I/O错误时,跳转指定的语句。两种用途:跳过错误返回或跳过错误继续。 注意:使用on_ioerror ,null on_error:当程序运行出错时,并不执行一个新的语句,而是指明IDL应该怎样做。 可以设置on_error ,1,或在命令行使用retall catch:格式:catch ,error_var。当程序执行到catch语句时,IDL为改模块记录一个错误处理语句,并将error_var赋值为0。若程序执行出错,则给error_var赋值相应的错误码,然后跳转到catch后第一条语句。注意:使用catch ,/can

14、celError or Exception is GeneratedIs it an I/O error?Is there an error handler defined by the CATCH routine?Is ON_IOERROR routine in use?Handle error as indicated by setting of ON_ERROR routine or use default error handling.Handle error as indicated by ON_IOERROR setting.Handle error with CATCH-defi

15、ned error handler and continue program execution.YesYesYesNoNoNo基础篇 编程基础IDL出错处理示意基础篇 编程基础4. 编译与运行 批处理:bacthfile,运行 主程序:.run,编译、运行 过程和函数:.compile,编译;-proname,编译、运行。 编译规则:(1)编译到主程序后,编译停止 (2)编译到与文件同名的程序模块时,停止编译 (3)编译到文件末尾或适合其他规则时,停止编译 自动编译规则:当过程或函数出现在命令或代码中时,会自动被编译执行。 (1)过程或函数所在的文件应在当前工作路径和 !Path指定的路径中

16、 (2)过程或函数名与文件名相同 编译函数:resolve_routine、resove_all。可用于程序模块中。 .sav:IDL-save,编译后存储为.sav文件,便于发布。但版本间不兼容。基础篇 输入输出1.常用概念 文件操作:openr,openw,openu,close 逻辑设备号:199,直接使用 100128,使用get_lun获取,free_lun释放 常用函数:dilog_pickfile,findfile,filepath2.文本文件的格式处理 自由格式:readf,printf,strsplit readf中只接收变量引用,不接收值引用 format语法:format

17、=(),括号内为格式符及其组合 A:naw,n为重复次数,w为输出宽度 I:niw或nIw.m,缺省w=7,特殊用法:i0 F:nfw.d,缺省w=15 X:nX,空格 /:换行符 ::其后的格式不用于最后一项。如每个输出项后加一个,时,最后一项不加。 C:c(),表示日期,接受julian日期。有丰富的子集基础篇 输入输出3.二进制文件的关连变量处理 基本命令:readu,writeu 关联变量:大型重复单元二进制文件的有效读取手段,可以随机读取。 一个文件可建立多个关联,解决重复单元不一致的情况。 assoc():result=assoc(unit,array_structure ,off

18、set ,/packed)4.使用与机器无关的数据格式 IDL 高级培训直接图形篇直接图形篇 色彩控制1. 基本概念 颜色构成:(r,g,b),每个颜色值在0255之间,所以IDL可以表现256*256*256种颜色 颜色表:一个颜色表由一个3列的数组构成,各列分别表示r、g、b值,通常256行。 索引号:颜色表中的索引位置。可以用来获得颜色的r、g、b值 8位显示器和24位显示器:8位显示器只能显示256色,24位则可以显示256*256*256色2. 索引颜色模式和RGB颜色模式 索引颜色模式:通过颜色表的索引号获得颜色的r、g、b值,用于8位显示器。 RGB颜色模式:直接指定颜色的r、g

19、、b值,用于24位显示器。IDL使用一个长整数表示所有颜色的索引号,c=r+g*256L+b*256L*256L。 3. 动态显示和静态显示 动态显示:索引模式将索引号与颜色表中的特定位置连接,称为动态颜色显示。改变颜色表会影响当前索引号所对应的颜色。通常,8位显示是动态显示 静态显示:RGB模式直接指定颜色本身,称为静态颜色显示。通常24位显示是静态显示。直接图形篇 色彩控制4. device ,decomposed=0|1 decomposed=0:关闭颜色分解,使用索引颜色模式。适用于8位显示和24位显示,但24位时仍是静态显示。此时,可以使用IDL预设的41个颜色表。 decompos

20、ed=1:IDL缺省模式,打开颜色分解,使用RGB颜色模式。只适用于24位显示。此时,只能使用长整数的全索引。5. tvlct ,r ,g ,b ,start ,/get :(RGB模式) tvlct ,r ,g ,b ,/get可以获取当前的颜色表。 tvlct ,r ,g ,b ,start可以加载一个颜色表到start指定的入口处。6. loadct ,table 加载IDL预设的41各颜色表之一7. 创建自己的颜色表 根据颜色表的原理,可以很容易地创建一个3*n数组作为自己的颜色表,用tvlct加载使用。直接图形篇 坐标系 data:数据单位(缺省) dvice:像素单位 normal

21、:归一化坐标,x:01,y:01 一般来说,在输出图形时,3个坐标系同时存在并都可以使用。 例:对于一个一维数组,在未指定坐标系时,IDL会把数组的下标值作为data坐标系下x轴的值,数组的值作为y值画出曲线。直接图形篇 2D图形创建自己的标注直接图形篇 2D图形多坐标系数据集显示画真正的圆直接图形篇 2D图形直接图形篇 2D图形在背景上叠加等值线直接图形篇 2D图形等值线图填充中的“黑洞”直接图形篇 添加文本给图形加文本标注 xyouts ,x ,y ,string ,font= TrueType字体设置: (1)DEVICE ,SET_FONT=font_str ,/TT_FONT ,输出

22、时,使用font=-1|0|1 (2)fontfnont_str Windows环境下TrueType字体设置: font_str=font*modifier1*modifier2*.modifiern For font weight: THIN, LIGHT, BOLD, HEAVY For font quality: DRAFT, PROOF For font pitch: FIXED, VARIABLE For font angle: ITALIC For strikeout text: STRIKEOUT For underlined text: UNDERLINE 注意:并非所有选项

23、在两种方式下均合法!直接图形篇 添加文本 使用汉字:font_str=“中文TrueType字体名称”device ,set_font=隶书 ,/tt_fontxyouts ,x ,y , ,font=1 使自己的字体成为IDL的系统字体:编辑 RSIIDL54resourcefontsttttfont.map直接图形篇 3D图形建立三维坐标系 IDL使用变换矩阵与三维空间的点相乘,实现在二维显示上模拟三维坐标系。该变换矩阵装入!P.T。实现时,先装入正确的变换矩阵,然后在图形显示前,保证图形命令已经被变换矩阵乘过。常用方法:(1)带save关键字的surface命令 surface ,dat

24、a ,/nodata ,/save (2)在surface后,使用surfr命令 surface ,data surfr (3)scale3命令(scale3d:单位立方体) scale3 ,xrange=vector ,yrange=vector ,zrange=vector ,ax=degrees ,az=degrees (4)t3d命令 严格、完整、复杂的方法直接图形篇 3D图形三维散点图直接图形篇 3D图形曲面图阴影曲面图图中色彩变化表示光源的方向直接图形篇 3D图形用颜色表现另一个数据集的信息上图为属性数据集右上、下图为用颜色表示的属性分布信息直接图形篇 3D图形用彩色图形叠加表现另

25、一个数据集的信息左图为属性数据集右图为用叠加在阴影曲面上的彩色曲面表示属性分布信息直接图形篇 3D图形等值线叠加直接图形篇 3D图形三维实体创建: shade_volume, volume, value, vertex, polygons scale3 image=polyshade( vertex, polygons) tv, image直接图形篇 图形定位图形定位: !p.region=x0,x1,y0,y1(归一化坐标) !p.position=x0,x1,y0,y1(归一化坐标) !x|y|z.margin=p1,p2(字符个数,会随charsize改变) 多数图形命令中都带有marg

26、in和position关键字,优先级较!变量高图形位置:指被坐标轴包围的区域可以使用!X|Y|Z.margin、 !p.position设置图形区域包括图形标题其它注释的区域可以使用!P.region设置图形边缘直接图形篇 图形组合显示如何在一个窗口里显示多个具有不同坐标系的图形?(1)position=x0,y0,x1,y1(2)!Multi=p1,p2,p3,p4,p5 p1:页面上剩余的部分的数目。通常为0,表示擦除窗口开始输出 p2:页面上图形的列数 p3:页面上图形的行数 p4:页面上Z方向上叠加的数目 p5:0,按行显示;1,按列显示直接图形篇 图形组合显示!Y.omargin=0

27、,4!p.multi=0,2,2,0,0直接图形篇 图形组合显示!Y.omargin=0,4!p.multi=0,2,2,0,0 . . .!p.multi=1,1,2,0,0直接图形篇 图形文件读写 作为一个数据分析和可视化的工具,IDL支持大量的图形格式。包括:bmp,geo tiff,interfile, jpeg,pict,png,ppm,srf,tiff,x11 bitmap,xwd。但从v5.4起,不再支持gif。 PNG格式:支持最多4个通道的8位或16位数据 单通道数据时,支持调色板 wirte_png ,filename ,image ,r,g,b:将图形数据写入PNG文件

28、其中:(1)如果image为2维数组,并且提供r、g、b值,则转换为byte以8位数据写入,否则转换为16位无符号整数。 (2)对单通道数据, r、g、b值必须提供,对多通道数据, r、g、b值被忽略 ok=query_png(filename ,s):获取PNG文件的属性。 其中:ok=0,不是合法的PNG文件。 s为一个结构,包含PNG文件的属性。若s.has_palette=1,为单通道数据,否则为多通道数据。 image=read_png(filename ,r,g,b):读出PNG文件的数据 其中:r,g,b对单通道数据,读出调色板,否则忽略。 常见用法:write_png ,fil

29、ename ,tvrd(true=1) (作为3通道数据写入) ok=query_png(filename ,s) . . image=read_png(filename) tv image ,/true直接图形篇 图像处理 图像:任何一个二维数组都可以视为一幅图像。 8位图像:总表示为一个二维数组。 24位(真彩色)图像:总表示为一个3维数组,其中一维为3。 m*n*3:隔波段扫描(band-interleaved ,true=3) m*3*n:隔行扫描( row-interleaved ,true=2) 3*m*n:隔象素扫描( pixel-interleaved,true=1) 在8位显

30、示设备上,所有数据要转换位字节类型;在24位显示设备上,24位图像的r、g、b值必须转换位字节类型。直接图形篇 图像处理1. 基本操作 显示:tv和tvscl。两个命令几乎一样,包括可以使用的关键字。都不删除当前窗口的内容。 tvscl:将图像数据调整为与运行时刻所有可用颜色数目相同的字节数据。通常用于8位图像 tv:取图像数据本身,作为字节数据显示。如果图像数据以整形和更多位数表示,则被截断以适合字节类型。因此,图形可能会显示不正确。 在24位设备上显示图像一般方法: device ,decomposed=0 loadct ,ct tvtvscl ,image(8位图像) tv ,image

31、 ,true=1|2|3(24位图像))直接图形篇 图像处理2. 调整数据为字节类型并可以使用统一的颜色集 bytscl(image ,min= ,max= ,top=) 如:scaleImage=bytscl(image ,min=5 ,max=30) 3. 改变图像尺寸 IDL提供了两个改变图像大小的命令:rebin和congrid rebin:新建的图象的大小必须是原始尺寸的整数比例。缺省放大时采用双线性插值,缩小时采用邻近平均法。sample关键字指定最近邻近采样法。 congrid:新建的图象的大小可以是原始尺寸的任意比例。缺省对三维以下数据采用最近邻近采样法,三维采用线性插值法。i

32、nterp关键字指定线性插值法4. 在窗口中定位图像 (1) tv ,image ,index:根据图像尺寸,从窗口左上角开始计算位置,逐行至右下角。 (2) tv ,image ,x ,y:指定左下角开始计算的坐标(devic|data|normal)。 利用!d.x_vsize和!d.y_vsize(象素值)计算归一化坐标以确定图像位置和大小。5. 从窗口中读取图像 8位显示:image=tvrd() 24位显示:image=tvrd(true=1) tvrd命令支持读取指定区域的图像直接图形篇 图像处理6. 基本图像处理 上图:原始图中图:hist_equal函数下图:adapt_his

33、t_equal函数 直方图均衡化:观察图像中的象素值分布,往往会发现象素值分布趋于一个较狭窄的数值范围内。如果将象素值分散开,使象素值得每个子范围都有与这些象素值大约相同的象素,则该图像的信息内容有可能增加。将象素分布道整个颜色范围的过程称为直方图均衡化。直接图形篇 图像处理 负片:将原始图像的显示色板翻转,象素的字节值不变所得到的图像。直接图形篇 图像处理 消除噪声:噪声来自多方面,影响对图像质量。噪声的一般表现形式是随机的具有极端值的象素(黑白噪声)。 median:计算相邻象素的中间值。这样既可以消除极端值,又不会使大于邻域的部分图像边缘或特征模糊。 平滑:通过将每个象素值与它周围相邻象

34、素值进行平均来平滑图像。称为均值或核状平滑。 smooth:在给定的奇数宽度的范围内通过等加权值实现平滑。 convol:使用给定的方形滤波核通过卷积实现平滑。 晕光蒙片:将原始图像减去平滑后的图像。可以定位图像上的边缘或象素值突然变化的地方直接图形篇 图像处理上图:smooth,w=5中图:smooth,w=3下图:convol,k=1,2,1 2,8,2 1,2,1 边缘增强:通过锐化或微分以增强边缘。 roberts: sobel: convol:使用给定的方形滤波核通过卷积实现。直接图形篇 图像处理右图:原始图像下图:自左至右依次为roberts、sobel、convol直接图形篇 图

35、像处理7. 频域滤波 频域滤波是图像 和信号处理的常规手段。可以用于平滑图像、锐化图像、降低图像的模糊程度和恢复图像。 基本步骤:(1)用快速傅立叶变换(FFT)将图像从空间域转换为频率域 (2)将转换后的图像与一个频率滤波器相乘 (3)将滤波后的图像逆变换转换为空间域 方法:filtered_img=fft( fft(img,-1)*filter ,1) img可以是一维矢量,也可以是二维图像 filter为滤波器,用于滤波图像中某些特定频率的一维矢量和二维数组。 创建滤波器: 欧氏距离图(频率图像):r=dist(n ,m),n和m与实际图像相同 Butterworth频率滤波器: 低通滤

36、波:filter=1/1+c*(r/r0)2n 高通滤波:filter=1/1+c*(r0/r)2n 其中:c=1.0或0.414(即当r=r0时,滤波幅度为0.5或1/sqrt(2)) r0为滤波器截止频率(实际中使用象素宽度) n为滤波器阶数,通常n=1 通常,低频项代表图像的一般形状,高频项对应图像的细节 直接图形篇 图像处理东海海表面温度图NOAA12 2000.9.23 20:40左图:原始图中图:低通(w=10)右图:高通(w=10)直接图形篇 图形窗口输出 IDL支持多种设备输出,并可以简单地在设备之间切换。 set_plot ,option:option=win|ps|prin

37、ter,大小写不敏感。 !:当前设备名。 一般用法: cDevName=! set_plot ,printer help ,/device set_plot ,cDevName 常用关键字: close_document:刷新输出缓冲区后关闭图形文档,用于从打印机排出打印页。 close_file:刷新输出缓冲区后关闭图形输出文件。 Filename:当输出为文件时地文件名,默认idl.option landscape:横向输出 portrait:纵向输出,缺省值 xoffset:确定纵向模式下输出窗口左下角(横向模式下ps和printer算法不同) yoffset:确定纵向模式下输出窗口左下

38、角(横向模式下ps和printer算法不同) xsize:确定输出窗口宽度 ysize :确定输出窗口长度 inches:以英寸为单位,缺省为厘米直接图形篇 图形窗口输出 ps 输出的一般方法: img=tvrd(true=1) set_plot ,ps device, filename= .ps ,color=1 device ,xsize= ,ysize= ,xoffset= ,yoffset= tvscl, img ,/true device, /close_file set_plot ,win printer输出的一般方法: ok=dialog_printersetup() img=t

39、vrd(true=1) ratio=float(!d.y_vsize)/!d.x_vsize (printer设备不能自动保持纵横比) set_plot,printer device,get_page_size=spagesize spagesize=spagesize/!d.x_px_cm,!d.x_px_cm device ,xoffset= ,yoffset= tvscl ,img ,/true ,/centimeters ,xsize= ,ysize= *ratio device ,/close_document set_plot ,winIDL 高级培训应用程序构造篇编程篇 建立、管

40、理应用程序 IDL有两种应用程序管理方法:主程序和工程 主程序:建立与程序名同名的 .pro文件,编译执行。 pro test end 在这种方式下,根据IDL的自动编译规则,所有被调用的子程序或者与主程序写入同一个文件并放置在主程序的上部;或者写成与子程序同名的 .pro文件,存储在可搜索的路径下。(子程序指过程或函数) 工程:建立若干个 .pro文件,每个文件不必与任何子程序同名。指定其中一个过程为主程序,该过程的名字作为工程执行时首先调用的过程(即 run command)。 在这种方式下,由于程序编写未必遵守IDL的自动编译规则,因此在运行前必须编译工程中所有的文件。 分发:将源程序编

41、译为.sav文件。 主程序方式,需手工编译、存储为.sav文件 .compile app_pro resolve_all save, /routines, app_pro ,app_sav 工程方式,设置工程属性为形成 .sav文件,使用工程菜单项下的build选项即可。编程篇 应用程序结构XMangerWidgetCreationRoutine(TLB)call xmanagerEventHandlerCalling RoutineEvent structureOnly if TLB is destoryed主程序调用相关子程序编程篇 主程序结构主程序的一般结构: pro app_pro c

42、ompile_opt idl2 create top layout base(TLB) create gui base on TLB (initial application) realize TLB collect user information call xmanager ,/NO_BLOCK endinitial application 该过程可以在主程序里进行。但更好的办法是编写单独的过程,用TLB的notify_realize关键字指定过程名,当realize TLB时执行。/NO_BLOCK 使用该关键字,主程序运行后,命令行仍然可以使用,主程序自身仍可修改编译,有利于调试。co

43、mpile_opt idl2 改变默认编译选项,idl2表示defint32和strictarr 编程篇 TLBTLB的三种基本形式 standard TLB: tlb_id=widget_base( group_leader=group $ ,uname=tlb ,title=idl app ) 适用于一般的应用程序,可以单独运行或被调用。group可以不存在。 modal TLB: tlb_id=widget_base( group_leader=group ,/modal ,uname=tlb ,title=modal app ) 适用于对话框类的应用程序,通常不可以单独运行,只能被调用

44、。group必须合法。调用该类程序后,调用者暂时挂起,直至该程序返回。 floating TLB: tlb_id=widget_base( group_leader=group ,/floating ,uname=tlb ,title=floating app ) 适用于任务优先类的应用程序,通常不可以单独运行,只能被调用。group必须合法。调用该类程序后,调用者可以继续运行。该程序总在最前面。编程篇 GUI基本组件容器组件: widget_base:任何GUI组件必须在某BASE组件上实现。一个BASE组件可以包含其它的BASE。GUI 组件: widget_draw:图形窗口,所有的图形

45、、图像显示均在此实现 widget_label:标签,不可编辑的文本,可用于提示、说明 widget_button:按钮,分为push button、radio button和checkbox。 可用于命令、单选以及多选 widget_text:文本框,可编辑的文本,可用于用户输入 widget_slider:滑动条,分为水平和垂直,可用于调整预设值 widget_listbox:列表框,用于项目选择 widget_droplist:下拉列表框 widget_table:表格,可编辑的二维数据组件标识: 每一个组件创建时都会产生一个id,并且可以指定一个uname。这些都是以后检索、操作这个组

46、件的标识。TrueType字体设置: draw:使用device ,set_font=fnt_str ,/tt_font,输出时使用font=1。通常在与用户交互时使用。 其它:使用font=fnt_str。通常在创建时使用编程篇 GUI其他组件Compound Widgets 组合组件是一组完备、自容、可重用的应用程序,使用时与基本组件大致相同,但它们是用IDL编写的。所有组合组件得名称都以cw_开始。 组合组件包括一下几类: Animation(动画) Color Manipulation(颜色操作) Data Entry and Display(数据输入输出) Image Manipul

47、ation(图像处理) Orientation(定位操作) User Interface(用户界面) 组合组件一般目的是扩充了相应的基本组件的功能。Dialogs 对话框用于用户界面,可以象组件一样使用,但它不属于组件构造层次。对话框是modal元素,当调用一个对话框时,其他界面元素暂时刮起直至对话框返回。 对话框包括以下几种: File and Directory Selection:DIALOG_PICKFILE MessageDIALOG_MESSAGE Printing:DIALOG_PRINTJOB、DIALOG_PRINTERSETUP编程篇 GUI的构造层次及实现TLBbaseb

48、asebasebasebaseitemitemitemitemGUI层次:Every GUI element is over BASEGUI实现:指GUI 第一次在屏幕上显示 widget_control ,tlb ,/realize TLB实现后,所有层次关系属于TLB的组件均实现。可以使用map=0关键字使某些子层次暂不显示。编程篇 xmanagerXmanager提供事件循环、监视并发送事件至事件处理程序,直至程序结束。xmanager ,name ,widget_id ,/just_reg ,/no_block ,group_leader=widget_id ,event_handle

49、r=event_pro ,cleanup=cleanup_proname:创建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_S

50、HOW )编程篇 事件结构事件 用户在GUI上的每一个认可的 操作都会产生一个事件,xmanager将事件信息打包传给IDL,IDL将事件信息解读后打包成一个结构类型的数据,即事件结构,并把这个事件结构做为唯一的位置参数发送给事件处理程序。事件结构 事件结构是一个命名结构。包括一个结构名、三个公共字段和一些个体字段。 event_type ,id: ,top: ,handler , even_type:标识事件类型。 id:长整数,产生事件的标识符。 top:长整数, id所表示的组件所在的TLB。 handler:长整数,事件处理程序标识符。事实上,由于事件处理程序总与某一特定的组件相联系,

51、该标识符就是组件标识符。 任何前三个字段定义与上述意义相同的命名字段,都可以认为是IDL的一个事件结构。编程篇 事件处理事件处理方式 当事件发生时,IDL会从当前组件层次开始,逐层向上查找与该事件相关联的事件处理程序。handler字段记录该组件的标识。TLBABFGDECEvent occurs hereEventhandlerTLBABFGDECEvent occurs hereEventhandlerEventhandler , id: G ,top: A ,handler: A , , id: G ,top: A ,handler: F , 编程篇 为组件指定事件处理程序为组件指定事件

52、处理程序 1. 由 xmanager 指定的事件处理程序(通常是TLB)处理所有事件。 2. 使用组件创建时的关键字event_pro或event_func为每一个事件单独指定一个处理程序。 注意到:xmanager总会为其直接管理的组件(通常是TLB)指定一个事件处理程序(而且是一个过程),因此,该组件的事件处理程序不能用event_pro或event_func指定。编程篇 事件处理程序事件处理程序 事件处理程序可以是过程或函数。 过程:事件处理完毕后被中止,程序等待下一个事件。 函数:由于函数有返回值,如果返回值是一个结构,又恰恰符合IDL事件结构标准,则IDL会将这个返回值做为一个事件处

53、理。(此乃伪事件,可以用来欺骗IDL) 事件处理程序接受并且只接受一个位置参数,event事件处理程序基本结构(TLB结构)pro app_pro_event ,event uname=widget_info(event.id ,/uname) case uname of TLB_uname: begin if tag_names(event ,/structure_name) eq widget_kill_request ) then begin (some cleanup work) widget_control ,event.top ,/destroy return endif end

54、uname1: begin (do something) end uname2: uname2_event_pro ,event (如果已经为uname2组件指定了该事件处理程序,则该行略去) else: endcaseend编程篇 数据传递 注意到,对于一个应用程序,IDL所做的只是“捕获”各种组件事件,将事件结构做为唯一的位置参数传递给事件处理程序,因此,无法通过通常的参数传递的方法交换数据。 IDL提供了user_value,通过为widget_id“绑定”user_value的方法传递数据。方法: widget_control ,widget_id ,set_uvalue=value

55、,/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 ,eve

56、nt.top ,get_uvalue=sState 注意到,用户数据的传递是值引用,这就意味着一旦在事件处理程序里改变了用户数据的值,必须把改变了值的用户数据传回给top才会使改变了的值在其它事件处理程序里生效。 Widget_control ,event.top ,set_uvalue=sState编程篇 数据传递有问题发生 事实上,sState是一个局部变量,因此当绑定给TLB_ID时,是copy了一份到全局内存。而当事件处理程序获得用户数据时,又是从全局内存中copy一份到该事件处理程序的局部变量中。于是,一份数据就有了3份copy。 指定/NO_COPY关键字,就只使用一份。烦恼: (

57、1)copy一事会给我们带来烦恼。因为一旦no_copy,则当前的用户数据变量就不再有效。这意味着返回用户数据的命令应该是事件处理程序的最后一行,显然这是不现实的。 (2)事实上,必须返回用户数据才会使修改有效这件事也会给我们带来烦恼,这要求我们必须时刻保持警惕!是不是精神会有点紧张?:)编程篇 数据传递解决的方法 用一个指针变量可以解决这个问题! (我们不必等IDL把用户数据copy到全局内存,我们有能力自己干!) TLB: sState= pState=ptr_new(sState ,/no_copy) widget_control ,TLB_id ,set_uvalue=pState E

58、H: widget_control ,ebent.top ,get_uvalue=pState 这时,*pState 就是 sState有了指针,我们方便多了! (1)任何修改立即生效,免去返回的烦恼。 (2)由于指针仅仅是“指针”,我们可以在sState里也设置一些必要的指针,比如数组指针,这样又可以免去结构数据不能更改数组维数的烦恼。编程篇 数据传递没有免费的午餐! 指针仍然有一个小小的问题。必须在cleanup里将指针释放,否则会引起内存泄漏。最后 没有证据证明传递 sState 和 pState 哪一个更好。 由于用户数据是值传递,这就带给我们可以在愿意的时候随便传递一个“什么”给TL

59、B的便利。这时,使用pState未必就比使用sState更方便。你需要ptr_free() ! 再者,太多的 * 仍然带来麻烦。编程篇 数据传递widget_list 和 widget_droplist 的 uvalue 通常我们在 list 里放置的是带有说明性的字符串数组,然而一旦进入事件循环我们就再也不会得到这个数组,我们只能得到这个数组的 index 值,即数组下标。 通过绑定字符串数组到 list_id 就可以在需要的时候仍然得到特定的字符串 TLB: widget_control ,list.id ,set_value = aStr widget_control ,list.id

60、,set_uvalue = aStr EH: index = widget_info( list_id ,/droplist_select ) OR index = widget_info( list_id ,/list_select ) widget_control ,list.id ,get_uvalue = aStr string = aStrindex编程篇 操作组件操作组件分为两个部分:获取组件属性和设置组件属性 widget_info函数用来获取组件属性,widget_control函数用来设置组件属性result=widget_info(widget_id , ) general

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论