在 GUIDE 中编写回调
注意
在以后的版本中将会删除 GUIDE 环境。在删除 GUIDE 后,使用 GUIDE 创建的现有 App 可以继续在 MATLAB® 中运行,但不能在 GUIDE 中对其进行编辑。
要继续编辑使用 GUIDE 创建的现有 App,请参阅 GUIDE 迁移策略,了解有关如何帮助保持该 App 与未来 MATLAB 版本的兼容性的信息。要以交互方式创建新 App,请改用使用 App 设计工具开发 App。
不同用户操作的回调
UI 和图形组件具有特定的属性,可以将这些属性与特定的回调函数相关联。其中每个属性对应于一项特定的用户操作。例如,某个 uicontrol 包含名为 Callback
的属性。可以将此属性的值设为某个回调函数或匿名函数的句柄,或包含 MATLAB 表达式的字符向量。通过设置此属性,您的 App 可在用户与该 uicontrol 交互时做出响应。如果 Callback
属性没有指定值,则当用户与该 uicontrol 交互时不会发生任何操作。
下表列出了可用的回调属性、触发回调函数的用户操作,以及使用这些属性的常见 UI 和图形组件。
回调属性 | 用户操作 | 使用此属性的组件 |
---|---|---|
ButtonDownFcn | 最终用户在指针位于组件或图窗上时按下鼠标按键。 | |
Callback | 最终用户触发组件。例如:选择菜单项、移动滑块或按下普通按钮。 | |
CellEditCallback | 最终用户在可编辑单元格的表中编辑值。 | |
CellSelectionCallback | 最终用户选中表中的单元格。 | |
ClickedCallback | 最终用户使用鼠标左键点击按钮工具或切换工具。 | |
CloseRequestFcn | 图窗关闭。 | |
CreateFcn | 在 MATLAB 创建对象后且在该对象显示之前,执行回调。 |
|
DeleteFcn | 在 MATLAB 即将删除图窗之前执行回调。 |
|
KeyPressFcn | 最终用户在指针位于对象上时按下键盘键。 | |
| 最终用户在指针位于对象上时松开键盘键。 | |
OffCallback | 在切换工具的 | |
OnCallback | 在切换工具的 | |
| 最终用户调整 | |
SelectionChangedFcn | 最终用户选择按钮组内的另一个单选按钮或切换按钮。 | |
WindowButtonDownFcn | 最终用户在指针位于图窗窗口中时按下鼠标按键。 | |
WindowButtonMotionFcn | 最终用户在图窗窗口内移动指针。 | |
WindowButtonUpFcn | 最终用户松开鼠标按键。 | |
WindowKeyPressFcn | 最终用户在指针位于图窗或其任何子对象上时按下按键。 | |
WindowKeyReleaseFcn | 最终用户在指针位于图窗或其任何子对象上时松开按键。 | |
| 最终用户在指针位于图窗上时滚动鼠标滚轮。 |
GUIDE 生成的回调函数和属性值
GUIDE 如何管理回调函数和属性
在将 uicontrol
、uimenu
或 uicontextmenu
组件添加到 UI 之后,但在保存 UI 之前,GUIDE 会使用值 %automatic
来填充 Callback
属性。此值指示 GUIDE 将为回调函数生成名称。
在保存 UI 时,GUIDE 将在您的代码文件中添加一个空的回调函数定义,并将控件的 Callback
属性设为匿名函数。以下函数定义是 GUIDE 为一个普通按钮生成的回调函数示例。
function pushbutton1_Callback(hObject,eventdata,handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) end
myui
保存此 UI,则 GUIDE 会将普通按钮的 Callback
属性设为以下值:@(hObject,eventdata)myui('pushbutton1_Callback',hObject,eventdata,guidata(hObject))
pushbutton1_Callback
函数的引用。此匿名函数具有四个输入参量。第一个参量是回调函数的名称。最后三个参量由 MATLAB 提供,将在GUIDE 回调语法部分进行讨论。注意
GUIDE 不会自动生成其他 UI 组件(例如表、面板或按钮组)的回调函数。如果希望以上任意组件执行回调函数,则必须通过右键点击布局中的组件,然后在上下文菜单的查看回调下面选择一个项,来创建回调。
GUIDE 回调语法
所有回调必须接受至少三个输入参量:
hObject
- 触发回调的 UI 组件。eventdata
- 包含关于特定鼠标或键盘操作的详细信息的变量。handles
- 包含 UI 中所有对象的struct
。GUIDE 使用guidata
函数存储和维护此结构体。
要使回调函数接受更多参量,必须在函数定义中的参量列表末尾放置更多参量。
eventdata 参量
eventdata
参量为某些回调函数提供详细信息。例如,如果最终用户触发了 KeyPressFcn
,则 MATLAB 将会提供关于最终用户所按的特定键(或组合键)的信息。如果 eventdata
不可用于回调函数,则 MATLAB 会将其作为空数组传递。下表列出了使用 eventdata
的回调和组件。
回调属性名称 | 组件 |
---|---|
WindowKeyPressFcn WindowKeyReleaseFcn WindowScrollWheel | figure |
KeyPressFcn | figure , uicontrol , uitable |
KeyReleaseFcn | figure , uicontrol , uitable |
SelectionChangedFcn | uibuttongroup |
CellEditCallback CellSelectionCallback | uitable |
在 GUIDE 回调之间共享数据
要在 App 中创建相互依赖的控件、菜单和图形对象,您必须显式与 App 中需要访问组件的部分共享数据。
方法 | 描述 | 要求和取舍 |
---|---|---|
共享 UserData | 直接通过组件对象获取或设置属性值。 所有 UI 组件都有一个可存储任意 MATLAB 数据的 |
|
共享应用程序数据 | 使用 |
|
使用 guidata | 使用 |
|
在使用 GUIDE 创建的 App 中共享 UserData
UI 组件在其属性中包含了有用的信息。例如,可以通过查询滑块的 Value
属性来查找滑块的当前位置。此外,所有组件都有 UserData
属性,其中可存储任意 MATLAB 变量。所有回调函数只要能够访问组件,就能访问存储在 UserData
属性中的值。
要设置使用 GUIDE 创建的 App,以通过 UserData
属性共享滑块数据,请执行以下步骤:
在命令行窗口中,键入
guide
以打开新的空白 GUI。在组件选项板中显示 UI 组件的名称:
选择文件 > 预设 > GUIDE。
选择在组件选项板中显示名称。
点击确定。
从布局编辑器左侧的组件选项板中选择普通按钮工具,并将其拖到布局区域内。
从布局编辑器左侧的组件选项板中选择滑块工具,并将其拖到布局区域内。
选择文件 > 另存为。将 UI 另存为
myslider.fig
。MATLAB 随即在编辑器中打开代码文件。在打开操作函数
myslider_OpeningFcn
中设置UserData
属性的初始值。此函数在即将向用户显示 UI 之前执行。在
myslider_OpeningFcn
中,紧跟命令handles.output = hObject
后面插入以下命令。添加命令后,data = struct('val',0,'diffMax',1); set(handles.slider1,'UserData',data);
myslider_OpeningFcn
应类似如下所示。请注意,function myslider_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to junk (see VARARGIN) % Choose default command line output for myslider handles.output = hObject; data = struct('val',0,'diffMax',1); set(handles.slider1,'UserData',data); % Update handles structure guidata(hObject, handles); % UIWAIT makes myslider wait for user response % uiwait(handles.figure1);
handles
是myslider_OpeningFcn
的输入参量。handles
变量是包含 UI 中所有组件的结构体。此结构体中的每个字段对应于一个单独的组件。每个字段名称与相应组件的Tag
属性相匹配。因此,handles.slider1
是此 UI 中的滑块组件。命令set(handles.slider1,'UserData',data)
在滑块的UserData
属性中存储变量data
。在用于修改数据的滑块回调中添加代码。将以下命令添加到函数
slider1_Callback
的末尾。添加命令后,maxval = get(hObject,'Max'); sval = get(hObject,'Value'); diffMax = maxval - sval; data = get(hObject,'UserData'); data.val = sval; data.diffMax = diffMax; % Store data in UserData of slider set(hObject,'UserData',data);
slider1_Callback
应类似如下所示。请注意,% --- Executes on slider movement. function slider1_Callback(hObject, eventdata, handles) % hObject handle to slider1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider maxval = get(hObject,'Max'); sval = get(hObject,'Value'); diffMax = maxval - sval; data = get(hObject,'UserData'); data.val = sval; data.diffMax = diffMax; % Store data in UserData of slider set(hObject,'UserData',data);
hObject
是slider1_Callback
函数的输入参量。hObject
始终是触发回调的组件(在此示例中为滑块)。因此,set(hObject,'UserData',data)
在滑块的UserData
属性中存储data
变量。在用于检索数据的普通按钮回调中添加代码。将以下命令添加到函数
pushbutton1_Callback
的末尾。添加命令后,% Get UserData from the slider data = get(handles.slider1,'UserData'); currentval = data.val; diffval = data.diffMax; display([currentval diffval]);
pushbutton1_Callback
应类似如下所示。% --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get UserData from the slider data = get(handles.slider1,'UserData'); currentval = data.val; diffval = data.diffMax; display([currentval diffval]);
此代码使用句柄结构体访问滑块。命令
data = get(handles.slider1,'UserData')
获取滑块的UserData
属性。然后,display
函数显示存储的值。通过按编辑器工具条中的保存,保存您的代码。
在使用 GUIDE 创建的 App 中共享应用程序数据
要存储应用程序数据,请调用 setappdata
函数:
setappdata(obj,name,value);
obj
是用于存储数据的组件对象。第二个输入 name
是描述值的友好名称。第三个输入 value
是需要存储的值。要检索应用程序数据,请使用 getappdata
函数:
data = getappdata(obj,name);
obj
必须是包含数据的组件对象。第二个输入 name
必须与用于存储数据的名称相匹配。UserData
属性仅保存一个变量,而使用 setappdata
可以存储多个变量。要设置使用 GUIDE 创建的 App 以共享应用程序数据,请执行以下步骤:
在命令行窗口中,键入
guide
以打开新的空白 GUI。在组件选项板中显示 UI 组件的名称:
选择文件 > 预设 > GUIDE。
选择在组件选项板中显示名称。
点击确定。
从布局编辑器左侧的组件选项板中选择普通按钮工具,并将其拖到布局区域内。
从布局编辑器左侧的组件选项板中选择滑块工具,并将其拖到布局区域内。
选择文件 > 另存为。将 UI 另存为
myslider.fig
。MATLAB 随即在编辑器中打开代码文件。在打开函数
myslider_OpeningFcn
中设置应用程序数据的初始值。此函数在即将向用户显示 UI 之前执行。在myslider_OpeningFcn
中,紧跟命令handles.output = hObject
后面插入以下命令。添加命令后,setappdata(handles.figure1,'slidervalue',0); setappdata(handles.figure1,'difference',1);
myslider_OpeningFcn
应类似如下所示。请注意,function myslider_OpeningFcn(hObject,eventdata,handles,varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to junk (see VARARGIN) % Choose default command line output for junk handles.output = hObject; setappdata(handles.figure1,'slidervalue',0); setappdata(handles.figure1,'difference',1); % Update handles structure guidata(hObject, handles); % UIWAIT makes junk wait for user response (see UIRESUME) % uiwait(handles.figure1);
handles
是myslider_OpeningFcn
的输入参量。handles
变量是包含 UI 中所有组件的结构体。此结构体中的每个字段对应于一个单独的组件。每个字段名称与相应组件的Tag
属性相匹配。在本例中,handles.figure1
为图窗对象。因此,setappdata
可使用此图窗对象来存储数据。在用于更改数据的滑块回调中添加代码。将以下命令添加到函数
slider1_Callback
的末尾。添加命令后,maxval = get(hObject,'Max'); currval = get(hObject,'Value'); diffMax = maxval - currval; % Store application data setappdata(handles.figure1,'slidervalue',currval); setappdata(handles.figure1,'difference',diffMax);
slider1_Callback
应类似如下所示。此回调函数可访问function slider1_Callback(hObject, eventdata, handles) % hObject handle to slider1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider maxval = get(hObject,'Max'); currval = get(hObject,'Value'); diffMax = maxval - currval; % Store application data setappdata(handles.figure1,'slidervalue',currval); setappdata(handles.figure1,'difference',diffMax);
handles
结构体,因此setappdata
命令会将数据存储在handles.figure1
中。在用于检索数据的普通按钮回调中添加代码。将以下命令添加到函数
pushbutton1_Callback
的末尾。添加命令后,% Retrieve application data currentval = getappdata(handles.figure1,'slidervalue'); diffval = getappdata(handles.figure1,'difference'); display([currentval diffval]);
pushbutton1_Callback
应类似如下所示。此回调函数可访问% --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Retrieve application data currentval = getappdata(handles.figure1,'slidervalue'); diffval = getappdata(handles.figure1,'difference'); display([currentval diffval]);
handles
结构体,因此getappdata
命令将会从handles.figure1
检索数据。通过按编辑器工具条中的保存,保存您的代码。
使用 guidata
在使用 GUIDE 创建的 App 中存储和共享数据
GUIDE 使用 guidata
函数存储包含所有 UI 组件的名为 handles
的结构体。MATLAB 将 handles
数组传递给每个回调函数。如果想要使用 guidata
来共享更多数据,则可在打开函数中向 handles
结构体添加字段。打开函数是在代码文件顶部附近定义的函数,其名称中包含 _OpeningFcn
。
要修改回调函数中的数据,可修改 handles
结构体,然后使用 guidata
函数存储该结构体。以下滑块回调函数显示了如何在 GUIDE 回调函数中修改和存储 handles
结构体。
function slider1_Callback(hObject, eventdata,handles) % hObject handle to slider1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range handles.myvalue = 2; guidata(hObject,handles); end
GUIDE 示例:使用 guidata 共享滑块数据
以下是一个使用 guidata
函数在滑块与文本字段之间共享数据的预置 GUIDE App。当您移动滑块时,文本字段中显示的数字将会更改,以显示新的滑块位置。
GUIDE 示例:在两个 App 之间共享数据
以下是一个使用应用数据和 guidata
函数在两个对话框之间共享数据的预置 GUIDE App。当您在第二个对话框中输入文本并点击确定后,第一个对话框中的按钮标签将会更改。
在 changeme_main.m
中,buttonChangeMe_Callback
函数将会执行以下命令,以显示第二个对话框:
changeme_dialog('changeme_main', handles.figure)
handles.figure
输入参量是 changeme_main 对话框的 Figure
对象。
changeme_dialog
函数从 Figure
对象检索 handles
结构体。因此,changeme_main 对话框中的全套组件都可供第二个对话框使用。
GUIDE 示例:在三个 App 之间共享数据
以下是一个使用 guidata
和 UserData
在三个 App 窗口之间共享数据的预置 GUIDE App。大窗口为图标编辑器,它接受来自工具选项板和调色板窗口的信息。
在 guide_inconeditor.m
中,函数 guide_iconeditor_OpeningFcn
包含以下命令:
colorPalette = guide_colorpalette('iconEditor', hObject)
参量如下:
'iconEditor'
指定 guide_iconEditor 窗口中的回调触发了函数的执行。hObject
是表示 guide_iconEditor 窗口的Figure
对象。colorPalette
是表示 guide_colorPalette 窗口的Figure
对象。
类似地,guide_iconeditor_OpeningFcn
使用相似的输入和输出参量调用 guide_toolpalette
函数。
通过在这些函数之间传递 Figure
对象,guide_iconEditor 窗口可以访问其他两个窗口的 handles
结构体。同样,其他两个窗口也能访问 guide_iconEditor 窗口的 handles
结构体。
重命名和删除 GUIDE 生成的回调
重命名回调
GUIDE 通过组合组件的 Tag
属性和回调属性名称,创建回调函数的名称。如果更改了组件的 Tag
值,则 GUIDE 将会在您下次保存 GUI 时更改回调的名称。
如果决定在保存 GUI 之后更改 Tag
值,则 GUIDE 将会更新以下项(假定所有组件都具有唯一的 Tag
值)。
组件的回调函数定义
组件的回调属性值
代码文件中对
handles
结构体内相应字段的引用
要重命名回调函数而不更改组件的 Tag
属性,请执行以下操作:
在回调函数定义中更改名称。
通过更改传递到匿名函数的第一个参量来更新组件的回调属性。例如,某个普通按钮的原始回调属性可能类似以下所示:
@(hObject,eventdata)myui('pushbutton1_Callback',... hObject,eventdata,guidata(hObject))
在此示例中,必须将
'pushbutton1_Callback'
更改为新的函数名称。在代码文件中,将对旧函数名称的其他所有引用更改为新函数名称。
删除回调
当您想要删除或更改在最终用户执行特定操作时执行的函数,可以删除回调函数。要删除回调函数,请执行以下操作:
搜索并替换代码中所有引用该回调函数的实例。
在 GUIDE 中打开 UI,并在属性检查器中替换所有引用该回调函数的实例。
删除回调函数。