独立的回调函数 建立GU函数的一个有效方法是编写独立的回调函数,专门执行一个或多个回调。函数使 用的对象句柄和其它变量可以作为参量传递,必要时回调函数可返回值。 考虑先前的一个例子,建立一个方位角的滑标,以脚本文件来实现 setview. m script file vw=get(gca, 'View); Hc azuicontrol(gcf,' Style,slider Position',[10514020] Min",-90,'Max',90," Value',w(1), Callback’,[ set(Hc cur,'String, num2str(get(Hc az,'Value)) set(gca, 'View, [get(Hc az,'Value ')vw(2)D D): He min=uncontrol(gcf, 'style,'text Position',[10254020], String, num2str(get(Hc az, Min)): He max=uncontrol(gcf,' Style,text Position',[110254020 He cur=uncontrol(gcf,'Style,text Position',[60254020], i Value 下面是同样的例子。作为一个函数,采用’Tag’属性来辨别控制框,并使用独立的M文件来执 行回调 vw=get(gca, 'View): He azuicontrol(gcf,'Style,'Slider Position'",[10514020 Min',-90,.Max, 90, valu w(1), ) He min=uncontrol(gcf, 'style,'text String, num2str( get(Hc az,Min): He max=uncontrol(gcf, Style,text Position',[110254020]
独立的回调函数 建立GUI函数的一个有效方法是编写独立的回调函数,专门执行一个或多个回调。函数使 用的对象句柄和其它变量可以作为参量传递,必要时回调函数可返回值。 考虑先前的一个例子,建立一个方位角的滑标,以脚本文件来实现。 % setview.m script file vw=get(gca, ' View ' ); Hc_az=uicontrol(gcf, ' Style ' , ' slider ' ,... ' Position ' ,[10 5 140 20],... ' Min ' ,-90, ' Max ' ,90, ' Value ' ,vw(1),... ' Callback ' ,[... ' set(Hc_cur, ' String ' ,num2str(get(Hc_az, ' Value ' ))), ' ... ' set(gca, ' View ' ,[get(Hc_az, ' Value ' ) vw(2)]) ' ]); Hc_min=uicontrol(gcf, ' style ' , ' text ' ,... ' Position ' ,[10 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Min ' ))); Hc_max=uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[110 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Max ' ))); Hc_cur=uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[60 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Value ' ))); 下面是同样的例子。作为一个函数,采用 ' Tag ' 属性来辨别控制框,并使用独立的M文件来执 行回调。 funtion setview( ) vw=get(gca, ' View ' ); Hc_az=uicontrol(gcf, ' Style ' , ' Slider ' ,... ' Position ' ,[10 5 140 20],... ' Min ' ,-90, ' Max ' ,90, ' Value ' ,vw(1),... ' Tag ' , ' Azslider ' ,... ' Callback ' , ' svcback ' ); Hc_min=uicontrol(gcf, ' style ' , ' text,... ' Position ' ,[10 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Min ' ))); Hc_max=uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[110 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Max ' )));
He cur=uncontrol(gcf, ' Style,text Position',[60254020, Tag",’ Azur String, num2str(get(Hc az,'Value D)) 调函数本身如下 function svcbacko ww=get(gca,'View) He az=findobj(gcf, 'Tag,'AZslider): He cur= findobj(gcf, 'Tag,' AZcur') str =num2str(get( Hc az, 'Value)): eview=get(Hc az, 'Value ')vw(2)] set(He cur,'String,str t(gca,View, newview) 上面的例子并不节省很多代码,但却得到了用函数而不用脚本文件的优点:回调函数可以利用 临时变量,而不使命令窗口工作空间拥挤;不需要eva所需的引号和字符串;在回调函数中命 令的句法变得十分简单。使用独立回调函数技术,越复杂的回调(函数)越简单 独立回调函数的缺点是:需要很大数目的M文件以实现一个含有若干控制框和菜单项的 GU函数,所有这些M文件必须在 MATLAB路径中可得,且每一个文件又必须要有一个不同的 文件名。在对文件名大小有限制且对大小写不敏感的平台上,如Ms- windows,文件冲突的机 会就增加了。而且回调函数只能被GUI函数调用而不能被用户调用 递归函数调用 利用单独的M文件并递归地调用该文件,既可以避免多个M文件的复杂性,又可以利用函 数的优点。使用开关 switches或 if elseif语句,可将回调函数装入调用函数内。通常这样一种函 数调用的结构为 function guifunc(switch) 其中 switch确定执行哪一个函数开关的参量,它可以是字符串' startup','cose',' sectolor 等等,也可以是代码或数字。如 switch是字符串,则可如下面所示的M文件片段那样将开关编 程 if nargin<1, switch=startup: end if-isstr(switch), error('Invalid argument), end if strcmp(switch, 'startup') <statement to create controls or menus> <statements to implement the GUI function> elseif strcmp(switch, 'setcolor) <statements to perform the Callback associated with set elseif strcmp(switch, 'close) <statements to perform the Callback associated with close>
Hc_cur=uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[60 25 40 20],... ' Tag ' , ' Azcur ' ,... ' String ' ,num2str(get(Hc_az, ' Value ' ))); 回调函数本身如下: function svcback( ) vw = get(gca, ' View ' ); Hc_az = findobj(gcf, ' Tag ' , ' AZslider ' ); Hc_cur = findobj(gcf, ' Tag ' , ' AZcur ' ); str = num2str(get(Hc_az, ' Value ' )); newview =[get(Hc_az, ' Value ' ) vw(2)]; set(Hc_cur, ' String ' ,str) set(gca, ' View ' ,newview) 上面的例子并不节省很多代码,但却得到了用函数而不用脚本文件的优点:回调函数可以利用 临时变量,而不使命令窗口工作空间拥挤;不需要eval所需的引号和字符串;在回调函数中命 令的句法变得十分简单。使用独立回调函数技术,越复杂的回调(函数)越简单。 独立回调函数的缺点是:需要很大数目的M文件以实现一个含有若干控制框和菜单项的 GUI函数,所有这些M文件必须在MATLAB路径中可得,且每一个文件又必须要有一个不同的 文件名。在对文件名大小有限制且对大小写不敏感的平台上,如MS-windows,文件冲突的机 会就增加了。而且回调函数只能被GUI函数调用而不能被用户调用。 递归函数调用 利用单独的M文件并递归地调用该文件,既可以避免多个M文件的复杂性,又可以利用函 数的优点。使用开关 switches或if elseif语句,可将回调函数装入调用函数内。通常这样一种函 数调用的结构为 function guifunc(switch)。 其中switch确定执行哪一个函数开关的参量,它可以是字符串 ' startup ' , ' close ' , ' sectolor ' 等等,也可以是代码或数字。如switch是字符串,则可如下面所示的M文件片段那样将开关编 程。 if nargin < 1, switch = ' startup ' ; end; if ~isstr(switch), error( ' Invalid argument ' ), end; if strcmp(switch, ' startup ' ), <statement to create controls or menus> <statements to implement the GUI function> elseif strcmp(switch, ' setcolor ' ), <statements to perform the Callback associated with setcolor> elseif strcmp(switch, ' close ' ), <statements to perform the Callback associated with close>
如果是代码或字符串,开关也可以相同方式编程。 if nargin< 1, switch=0: end: if isst(switch), error(' Invalid argument), end SWI <statements to create controls or menus> <statements to implement the GUI function> elseif switch==l, <statements to perform the Call back associated with setcolor> elseif switch =2 statements to perform the Callback associated with close> 下面的例子说明了方位角滑标如何可作为单独的函数M文件来实现: function setview(switch ifr startup if -isstr(switch), error(Invalid argument. ): end vw=get(gca, 'view): This information is needed in both sections if strcmp(switch, '')% Define the controls and tag them He az= uncontrol(gcf, 'Style','slider, Position’,[10514020], Min',-90,'Max,90, 'Value'vw(1), i Tag',' AZslider Callback,'setview('set)); He min=uncontrol(gcf, Style,text Position'",[10254020] String, num2str(get(Hc az, 'Min )) He max=uncontrol(gcf,' Style,text Position',[0254020], String, num2str(get( Hc az,' Max )) He cur =uncontrol(gcf, 'Style,text Position',[60254020] Tag',' AZcur string, num2str(get(Hc az, 'Value ' )) elseif strcmp(switch,'set)% Execute the Callback He azfindobj(gcf, Tag,' AZslider'): He cur-findobj(gcf, 'Tag,'AZcur')
end 如果是代码或字符串,开关也可以相同方式编程。 if nargin < 1, switch = 0; end; if isstr(switch), error( ' Invalid argument ' ), end; if switch = = 0, <statements to create controls or menus> <statements to implement the GUI function> elseif switch = =1, <statements to perform the Callback associated with setcolor> elseif switch ==2, <statements to perform the Callback associated with close> end 下面的例子说明了方位角滑标如何可作为单独的函数M文件来实现: function setview(switch) if nargin < 1, switch = ' startup ' ; end; if ~isstr(switch), error( ' Invalid argument. ' ); end; vw = get(gca, ' view ' ); % This information is needed in both sections if strcmp(switch, ' startup ' ) % Define the controls and tag them Hc_az = uicontrol(gcf, ' Style ' , ' slider ' ,... ' Position ' ,[10 5 140 20],... ' Min ' ,-90, ' Max ' ,90, ' Value ' vw(1),... ' Tag ' , ' AZslider ' ,... ' Callback ' , ' setview( ' set ' ) ' ); Hc_min=uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[10 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Min ' ))); Hc_max = uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[110 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Max ' ))); Hc_cur =uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[60 25 40 20],... ' Tag ' , ' AZcur ' ,... ' string ' ,num2str(get(Hc_az, ' Value ' ))); elseif strcmp(switch, ' set ' ) % Execute the Callback Hc_az=findobj(gcf, ' Tag ' , ' AZslider ' ); Hc_cur-findobj(gcf, ' Tag ' , ' AZcur ' );
str=num2str(get(Hc az, 'Value ') newview-Iget( Hc az, ' Value')vw(2)] set(Hc cur,'String set(gca,'View, newview) 上述的两个例子均设置了’tag'属性,利用该属性和函数 findobj寻找回调函数所需对象的句 柄。另外两种方法将在下章描述 全局变量 全局变量可用在函数中,使某些变量对GUI函数的所有部分都可用,全局变量是在函数的 公共区说明,因此整个函数以及所有对函数的递归调用都可以利用全局变量,下面的例子说明 如何利用全局变量将方位角滑标编程 function seaview(switch) global HC AZ HC CUR Create global variables if nargin < 1, switch=startup: end if-isstr(switch, error('Invalid argument ' ):end vw=get(gca, 'View): %This information is needed in both sections if strcmp(switch, '')% Define the controls Hc az=uncontrol(gcf, 'style,'slider Position',[10514020 Min',-90,'Max",90," Value',w(1) Callback,'setview( 'set)): He min=uncontrol(gcf, 'Style,text String, num2str(get(Hc-AZ, 'Min',)) HcMax-uicontrol(gcf, 'Style','text, Position',[10254020], String, num2str(get(Hc AZ,'Max)): He cur=uncontrol(gcf, 'style,text Position',[60254020, String, num2str(get(HC AZ, 'Value)) elseif strcmp(switch, 'set)% Execute the Callback str=num2str(get(HC AZ, Value)); newview=[get(HC AZ, ' Value')vw(2)] set(HC CUR,' String, str)
str = num2str(get(Hc_az, ' Value ' )); newview - [get(Hc_az, ' Value ' ) vw(2)]; set(Hc_cur, ' String ' , str) set(gca, ' View ' ,newview) end 上述的两个例子均设置了 ' tag ' 属性,利用该属性和函数findobj寻找回调函数所需对象的句 柄。另外两种方法将在下章描述。 全局变量 全局变量可用在函数中,使某些变量对GUI函数的所有部分都可用,全局变量是在函数的 公共区说明,因此整个函数以及所有对函数的递归调用都可以利用全局变量,下面的例子说明 如何利用全局变量将方位角滑标编程。 function setview(switch) global HC_AZ HC_CUR % Create global variables if nargin < 1, switch = ' startup ' ; end; if ~isstr(switch, error( ' Invalid argument. ' ); end; vw = get (gca, ' View ' ); % This information is needed in both sections if strcmp(switch, ' startup ' ) % Define the controls Hc_AZ=uicontrol(gcf, ' style ' , ' slider ' ,... ' Position ' ,[10 5 140 20],... ' Min ' ,-90, ' Max ' ,90, ' Value ' ,vw(1),... ' Callback ' , ' setview( ' set ' ) ' ); Hc_min=uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[10 25 40 20],... ' String ' ,num2str(get(Hc-AZ, ' Min ' ,))); HcMax=uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[110 25 40 20],... ' String ' ,num2str(get(Hc_AZ, ' Max ' ))); Hc_cur=uicontrol(gcf, ' style ' , ' text ' ,... ' Position ' ,[60 25 40 20],... ' String ' ,num2str(get(HC_AZ, ' Value ' ))); elseif strcmp(switch, ' set ' ) % Execute the Callback str=num2str(get(HC_AZ, ' Value ' )); newview= [get(HC_AZ, ' Value ' ) vw(2)]; set(HC_CUR, ' String ' ,str)
全局变量遵循 MATLAB的规定,变量名要大写。不需要’tag'属性,且不使用它,另外因为对 象句柄存在的,不需要用函数 findobj去获取,故回调代码比较简单,全局变量通常使一个函数 更有效。 不过有一点要注意,尽管一个变量在函数内说明为全局的,变量并不能自动地在命令窗口 工作空间中利用,也不能在回调字符串内使用。但是,如果用户发命令:> clear global,则 所有全局变量则都被破坏,包括在函数内定义的那些变量。 当单独的一个图形或有限个变量要被所有的回调函数)利用时,全局变量使用和递归性函 数调用都是有效的技术。对于包含多个图形的更复杂的函数,或用独立对象回调函数实现的情 况,' UserData'属性更合适。另外,只要可获得对象句柄,对象' UserData'的属性值在命令 窗口工作空间中是存在的。 用户数据属性 同属性’Iag,一样, UserData’属性可在函数之间或递归函数的不同部分之间传递信 息。如果需要多个变量,这些变量可以在一个容易辨识的对象的属性' UserData’中传递。如 前面所述,对与句柄图形对象在一起的单个数据矩阵' User Data'提供了存储。下面的程序 利用了当前图形的' UserData'属性来实现方位角滑标。 function setview(switch 1, switch='startup: end: vw=get(gca, 'View): %This information is needed in both sections if strcmp(switch, 'startup')% Define the controls He az=uncontrol(gcf, 'Style,'slider Position',[10514020] Min,-90,'Max, 90,'Value, vw(1) Callback,' setview("set")): He min= uncontrol(gcf, 'Style,'text, Position’,[10254020], String,num2str(get(Hc az,' Min')); He max=uncontrol(gcf,' Style,text Position',[0254020] String, num2str(get( Hc az,' Max)): He cur=uncontrol(gcf,' Style,text Position',[60254020], String, num2str(get( Hc az,'Value)) set(gcf,'User Data,[Hc az Hc cur): % Store the object handles
set(gca, ' View ' ,newview) end 全局变量遵循MATLAB的规定,变量名要大写。不需要 ' tag ' 属性,且不使用它,另外因为对 象句柄存在的,不需要用函数findobj去获取,故回调代码比较简单,全局变量通常使一个函数 更有效。 不过有一点要注意,尽管一个变量在函数内说明为全局的,变量并不能自动地在命令窗口 工作空间中利用,也不能在回调字符串内使用。但是,如果用户发命令:>> clear global,则 所有全局变量则都被破坏,包括在函数内定义的那些变量。 当单独的一个图形或有限个变量要被所有的回调(函数)利用时,全局变量使用和递归性函 数调用都是有效的技术。对于包含多个图形的更复杂的函数,或用独立对象回调函数实现的情 况, ' UserData ' 属性更合适。另外,只要可获得对象句柄,对象 ' UserData ' 的属性值在命令 窗口工作空间中是存在的。 用户数据属性 同属性 ' Tag ' 一样, ' UserData ' 属性可在函数之间或递归函数的不同部分之间传递信 息。如果需要多个变量,这些变量可以在一个容易辨识的对象的属性 ' UsetData ' 中传递。如 前面所述, 对与句柄图形对象在一起的单个数据矩阵' UserData ' 提供了存储。下面的程序 利用了当前图形的 ' UserData ' 属性来实现方位角滑标。 function setview(switch) if nargin < 1, switch = ' startup ' ; end; vw = get(gca, ' View ' ); % This information is needed in both sections if strcmp(switch, ' startup ' ) % Define the controls Hc_az = uicontrol(gcf, ' Style ' , ' slider ' ,... ' Position ' ,[10 5 140 20],... ' Min ' ,-90, ' Max ' ,90, ' Value ' ,vw(1),... ' Callback ' , ' setview("set") ' ); Hc_min = uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[10 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Min ' ))); Hc_max = uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[110 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Max ' ))); Hc_cur = uicontrol(gcf, ' Style ' , ' text ' ,... ' Position ' ,[60 25 40 20],... ' String ' ,num2str(get(Hc_az, ' Value ' ))); set(gcf, ' UserData ' ,[Hc_az Hc_cur]); % Store the object handles