这两天写了两个实现matlab的gui的程序,其中涉及到不少参数传递的问题,涉及到不同窗口之间、不同控件之间参数的传递,从实现原理方面,又分为guide实现gui时的参数传递问题和编写纯代码实现gui的参数传递问题。网络上没有关于这方面的完整教程,或者不够清晰,因此特地写了这篇教程,总结一下自己摸索出的经验,一是为了留作以后自己参考,二是对刚接触gui的小白提供一些帮助。如有谬误,请多多指正~
在matlab命令行输入guide即可打开matlab的guide界面,然后在guide里可以新建一个窗口,并进行控件的添加修改等操作。再次在命令行输入guide,可以创建多个窗口,关于具体操作的教程有很多,在此不再赘述。
1.1.1控件之间属性的传递
类比C++中类的概念,matlab中的每个控件都有自己的属性,如位置、显示文本等,而这些控件都保存在当前gui的结构体中,如上图所示。那么如何在一个控件中获取或者改变另一个控件中的属性呢(同一窗口中)。下面举例说明:
例如,在下面的example1窗口中,有一个edit控件和一个pushbutton控件。想实现以下功能:用户在edit控件中输入一个数字,点击pushbutton后,使edit中的数字+1。打开对应的example文件,找到点击pushbutton点击的回调函数,输入代码,如图所示。
84行:
a=get(handles.edit1,'String');
其中的get函数表示接收edit1控件的String属性并赋值到变量a中;
第84行将a转换为数字;
85行:
set(handles.edit1,'String',a+1)
其中的set函数表示将edit1控件的String属性设置为a+1。
总结:使用matlab的guide创建的gui,其所有的控件(包括窗口)都被视为这个gui的一个对象,如果想调用某一个对象,就需要用handles.对象名,要调用和设置这个对象某个属性的方式是使用get(handles.对象名,'属性名')和set(handles.对象名,'属性名',属性值)函数。handles代表你当前gui的句柄。
1.1.2控件之间变量的传递
在matlab中,在每一个控件的回调(callback)函数中定义的变量是“私有的”,即作用域仅限于这个函数,其他控件的回调不能直接访问这个变量。
如果在某一个控件的回调函数中定义了一个变量,那么如何在其他控件的回调中访问它呢。
如图所示:
在窗口example创建时定义了一个变量m,但是m不能直接被其他控件访问,改写如下:
将值赋值给handles.变量名,此时变量保存在当前gui的句柄中,也就是保存在其结构体中。如下图所示:
调用方式如下:
在点击pushbutton时,将m变量赋值给a,此时就实现了在不同控件之间传递变量。
注意:在调用handles.变量名之前,要加上一行
guidata(hObject, handles);
这条语句的作用是更新结构体中的所有数据。因此,在函数的最后也应该加上这行语句,以便保存结构体的数据,如行85。
假设有example和example2两个窗口(即两个gui,显然它们的句柄不同),在example中的某一个控件的属性如何传递到example2中去呢。
在example2中编写代码如下:
当按下example2中的pushbutton1时,example的句柄将被传递进来(行106),这样在行107中就可以设置example中的控件edit1的属性了。
例如,编写代码创建一个gui,并为其创建一个pushbutton控件:
% 创建一个空白窗口
w = figure();
% 设置窗口属性
set(w,'Color',[0.9,0.9,0.9]);
set(w,'MenuBar','none');
set(gcf,'Position',[200 200 550 600]);
set(w,'Name','Image Surfer');
% 创建一个按钮控件并设置属性
pushbutton1 = uicontrol('style','pushbutton','String','button1');
set(pushbutton1,'position',[50,50,200,200]);
% 设置控件的回调函数为p1_callback
set(pushbutton1,'Callback',@p1_callback);
新建一个m文件编写回调函数p1_callback:
function p1_callback
msgbox('I am a callback function.')
end
运行并点击button1,效果如图所示:
如何实现向p1_callback传递变量呢,在example3.m中编写代码如下:
% 创建一个空白窗口
w = figure();
% 设置窗口属性
set(w,'Color',[0.9,0.9,0.9]);
set(w,'MenuBar','none');
set(gcf,'Position',[200 200 550 600]);
set(w,'Name','Image Surfer');
% 创建一个按钮控件并设置属性
pushbutton1 = uicontrol('style','pushbutton','String','button1');
set(pushbutton1,'position',[50,50,200,200]);
% 设置控件的回调函数为p1_callback
var1=1;var2=2;var3=3;
set(pushbutton1,'Callback',{@p1_callback,var1,var2,var3});
将回调函数p1_callback的代码改为:
function p1_callback(~,~,v1,v2,v3)
msgbox(v1+v2+v3);
end
这样,变量var1、var2、var3的值就传递到虚参v1、v2、v3中了,类似地,可以向其传入单个或多个变量。
当传入的值是句柄时,回调函数就可以通过句柄名.控件名和set()、get()函数访问其他控件的属性值了。
除了使用以上介绍的方法传递参数外,还可以通过声明全局变量的方式来传递,在任意地方编写如下代码:
global x;
x=10;
那么在所有的工作区所有地方都可以访问x变量,只要在访问前声明一下,如:
global x;
c=2*x;
就实现了对x的访问。如在一个控件函数中声明了global x,那么在其他的控件函数中声明global x后,就可以访问x,即实现了变量在不同控件之间的传递。无论是guide实现的gui,还是纯代码实现的gui,在不同控件、窗口间都可以通过这种方法来传递变量。但是不宜过多使用。
此外,使用setappdata()函数和getappdata()函数也可以实现变量在控件之间的传递,具体使用方法在matlab帮助文档中有详细的说明,这里就不详细介绍了。