|||
在博文《Matlab:学习GUI(一个简单的例子)》(http://blog.sciencenet.cn/blog-200199-870822.html) 中介绍的方法是完全用代码来建立一个GUI,实际上Matlab本身有一个设计GUI的交互系统——GUIDE,用户可以使用该系统更方便的建立自己的GUI.
本文将介绍使用GUIDE时常常遇到的几个问题。本文将通过一个简单的例子来说明问题,读者朋友们可以边看边操作。在command line输入guide回车,打开Layout Editor. 建立一个空白的模板(Blank GUI),建立一个push button,将“String”改为“Close”,save并将文件名命名为test,如下图:
save后,Matlab会生成两个文件test.M 和test.fig,打开test.M,如下:
function varargout = test(varargin)
% Begin initializationcode - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @test_OpeningFcn,...
'gui_OutputFcn', @test_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback =str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] =gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code- DO NOT EDIT
% --- Executes justbefore test is made visible.
function test_OpeningFcn(hObject,eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
% --- Outputs from thisfunction are returned to the command line.
function varargout = test_OutputFcn(hObject,eventdata, handles)
varargout{1} = handles.output;
% --- Executes on buttonpress in pushbutton1.
functionpushbutton1_Callback(hObject,eventdata, handles)
生成的M文件的结构主要由三个子函数构成:_OpeningFcn,这个函数是在GUI界面出现以前Matlab在后台运行的,GUI设计者可以在这个函数内完成数据初始化设置、GUI的界面的控制和调整等工作。_OutputFcn函数是M文件最后运行的函数,主要是为了输出运行结果。_Callback函数用于控制component的触发行为,比如说用户按下界面的按钮后,该按钮应该执行什么命令。我们这个例子设计的是按下“Close”按钮后,GUI界面关闭,因此需要在
function pushbutton1_Callback(hObject, eventdata, handles)
后面加上:
delete(handles.figure1);
下面我们开始借助这个简单的例子,讲一讲新手在应用GUIDE时常见的三个问题:
问题一:figure Name和figure tag 弄混了。
Figure Name指的是M文件和Fig文件的name,即本例中的test. Tag指的是设计GUI界面时为每个component所指定的标签,也是程序中唯一的可以识别component的名字,GUI的面板也是一个component,有自己的tag,即本例中默认的figure1. 弄混figure tag和figure name的例子如下:
错误代码:
function pushbutton1_Callback(hObject, eventdata, handles)
delete(handles.test);
当运行错误代码时,Matlab会提示找不到handles中的test变量,因为handles只是存储component的句柄,每个句柄是以tag来命名的:
??? Reference to non-existentfield 'test'.
Error in ==>test>pushbutton1_Callback at 81
delete(handles.test);
问题二:uiwait 在逻辑上与uiresume不配对。
还是上面的例子,如果再增加一个功能,等用户按下“Close”按钮后,在屏幕输出“OK”,否则不输出。为实现该功能,在test_OpeningFcn的guidata 语句后增加:
% UIWAIT makes test waitfor user response (see UIRESUME)
uiwait(handles.figure1);
在test_OutputFcn的varargout{1}语句后添加:
delete(handles.figure1);
将pushbutton1_Callback中的delete(handles.figure1)删除,并添加:
disp('OK');
uiresume(handles.figure1);
运行后,用户点击“Close”按钮,一切正常。可是,当用户不点击“Close”而是直接关闭窗口时,程序提示OutputFcn输出错误:
出现该错误的原因是:当用户直接关闭窗口时,所有在内存中的变量都被清楚,程序在执行到OutputFcn是已没有变量可以赋值给结构变量varargout{1}了。为了改正该错误,需要添加_CloseRequestFcn函数:
% Executes when userattempts to close figure1.
function figure1_CloseRequestFcn(hObject, eventdata, handles)
% hObject handle to figure1 (see GCBO)
% eventdata reserved - to be defined in a future versionof MATLAB
% handles structure with handles and user data (seeGUIDATA)
if isequal(get(hObject, 'waitstatus'), 'waiting')
% TheGUI is still in UIWAIT, us UIRESUME
uiresume(hObject);
else
% TheGUI is no longer waiting, just close it
delete(hObject);
end
可是,如果直接将上述代码复制到test.m文件中,保存,运行,关闭窗口时,同样会出现上述OutputFcn输出错误,这个就涉及到下面第三个问题。
问题三:Layout Editor的设置和M文件不同步。
为解决上述问题,可打开figure1的Property Inspector, 注意到CloseRequestFcn一栏,显示的是closereq,点击以下旁边的图片,变为:
这说明两者已经同步,此时可以放心的运行程序了。
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-11-1 07:35
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社