Main Content

在 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

最终用户在指针位于组件或图窗上时按下鼠标按键。

axes, figure, uibuttongroup, uicontrol, uipanel, uitable,

Callback

最终用户触发组件。例如:选择菜单项、移动滑块或按下普通按钮。

uicontextmenu, uicontrol, uimenu

CellEditCallback

最终用户在可编辑单元格的表中编辑值。

uitable

CellSelectionCallback

最终用户选中表中的单元格。

uitable

ClickedCallback

最终用户使用鼠标左键点击按钮工具或切换工具。

uitoggletool, uipushtool

CloseRequestFcn

图窗关闭。

figure

CreateFcn

在 MATLAB 创建对象后且在该对象显示之前,执行回调。

axes, figure, uibuttongroup, uicontextmenu, uicontrol, uimenu, uipushtool, uipanel, uitable, uitoggletool, uitoolbar

DeleteFcn

在 MATLAB 即将删除图窗之前执行回调。

axes, figure, uibuttongroup, uicontextmenu, uicontrol, uimenu, uipushtool, uipanel, uitable, uitoggletool, uitoolbar

KeyPressFcn

最终用户在指针位于对象上时按下键盘键。

figure, uicontrol, uipanel, uipushtool, uitable, uitoolbar

KeyReleaseFcn

最终用户在指针位于对象上时松开键盘键。

figure, uicontrol, uitable

OffCallback

在切换工具的 State 更改为 'off' 时执行。

uitoggletool

OnCallback

在切换工具的 State 更改为 'on' 时执行。

uitoggletool

SizeChangedFcn

最终用户调整 Resize 属性为 'on' 的按钮组、图窗或面板的大小。

figure, uipanel, uibuttongroup

SelectionChangedFcn

最终用户选择按钮组内的另一个单选按钮或切换按钮。

uibuttongroup

WindowButtonDownFcn

最终用户在指针位于图窗窗口中时按下鼠标按键。

figure

WindowButtonMotionFcn

最终用户在图窗窗口内移动指针。

figure

WindowButtonUpFcn

最终用户松开鼠标按键。

figure

WindowKeyPressFcn

最终用户在指针位于图窗或其任何子对象上时按下按键。

figure

WindowKeyReleaseFcn

最终用户在指针位于图窗或其任何子对象上时松开按键。

figure

WindowScrollWheelFcn

最终用户在指针位于图窗上时滚动鼠标滚轮。

figure

GUIDE 生成的回调函数和属性值

GUIDE 如何管理回调函数和属性

在将 uicontroluimenuuicontextmenu 组件添加到 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
KeyPressFcnfigure, uicontrol, uitable
KeyReleaseFcnfigure, uicontrol, uitable
SelectionChangedFcnuibuttongroup
CellEditCallback
CellSelectionCallback
uitable

在 GUIDE 回调之间共享数据

要在 App 中创建相互依赖的控件、菜单和图形对象,您必须显式与 App 中需要访问组件的部分共享数据。

方法描述要求和取舍
共享 UserData

直接通过组件对象获取或设置属性值。

所有 UI 组件都有一个可存储任意 MATLAB 数据的 UserData 属性。

  • 需要访问组件以设置或检索属性。

  • UserData 一次仅保存一个变量,但可以将多个值作为 struct 数组或元胞数组进行存储。

共享应用程序数据

使用 setappdata 函数将数据与特定组件关联。可以稍后使用 getappdata 函数来访问它。

  • 要求访问组件以设置或检索应用程序数据。

  • 可以共享多个变量。

使用 guidata

使用 guidata 函数与图窗窗口共享数据。

  • 通过任意 UI 组件存储或检索数据。

  • 一次仅存储一个变量,但可以将多个值作为 struct 数组或元胞数组进行存储。

在使用 GUIDE 创建的 App 中共享 UserData

UI 组件在其属性中包含了有用的信息。例如,可以通过查询滑块的 Value 属性来查找滑块的当前位置。此外,所有组件都有 UserData 属性,其中可存储任意 MATLAB 变量。所有回调函数只要能够访问组件,就能访问存储在 UserData 属性中的值。

要设置使用 GUIDE 创建的 App,以通过 UserData 属性共享滑块数据,请执行以下步骤:

  1. 在命令行窗口中,键入 guide 以打开新的空白 GUI。

  2. 在组件选项板中显示 UI 组件的名称:

    1. 选择文件 > 预设 > GUIDE

    2. 选择在组件选项板中显示名称

    3. 点击确定

  3. 从布局编辑器左侧的组件选项板中选择普通按钮工具,并将其拖到布局区域内。

  4. 从布局编辑器左侧的组件选项板中选择滑块工具,并将其拖到布局区域内。

  5. 选择文件 > 另存为。将 UI 另存为 myslider.fig。MATLAB 随即在编辑器中打开代码文件。

  6. 在打开操作函数 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);
    
    请注意,handlesmyslider_OpeningFcn 的输入参量。handles 变量是包含 UI 中所有组件的结构体。此结构体中的每个字段对应于一个单独的组件。每个字段名称与相应组件的 Tag 属性相匹配。因此,handles.slider1 是此 UI 中的滑块组件。命令 set(handles.slider1,'UserData',data) 在滑块的 UserData 属性中存储变量 data

  7. 在用于修改数据的滑块回调中添加代码。将以下命令添加到函数 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);
    
    请注意,hObjectslider1_Callback 函数的输入参量。hObject 始终是触发回调的组件(在此示例中为滑块)。因此,set(hObject,'UserData',data) 在滑块的 UserData 属性中存储 data 变量。

  8. 在用于检索数据的普通按钮回调中添加代码。将以下命令添加到函数 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 函数显示存储的值。

  9. 通过按编辑器工具条中的保存,保存您的代码。

在使用 GUIDE 创建的 App 中共享应用程序数据

要存储应用程序数据,请调用 setappdata 函数:

setappdata(obj,name,value);
第一个输入 obj 是用于存储数据的组件对象。第二个输入 name 是描述值的友好名称。第三个输入 value 是需要存储的值。

要检索应用程序数据,请使用 getappdata 函数:

data = getappdata(obj,name);
组件 obj 必须是包含数据的组件对象。第二个输入 name 必须与用于存储数据的名称相匹配。UserData 属性仅保存一个变量,而使用 setappdata 可以存储多个变量。

要设置使用 GUIDE 创建的 App 以共享应用程序数据,请执行以下步骤:

  1. 在命令行窗口中,键入 guide 以打开新的空白 GUI。

  2. 在组件选项板中显示 UI 组件的名称:

    1. 选择文件 > 预设 > GUIDE

    2. 选择在组件选项板中显示名称

    3. 点击确定

  3. 从布局编辑器左侧的组件选项板中选择普通按钮工具,并将其拖到布局区域内。

  4. 从布局编辑器左侧的组件选项板中选择滑块工具,并将其拖到布局区域内。

  5. 选择文件 > 另存为。将 UI 另存为 myslider.fig。MATLAB 随即在编辑器中打开代码文件。

  6. 在打开函数 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);
    
    请注意,handlesmyslider_OpeningFcn 的输入参量。handles 变量是包含 UI 中所有组件的结构体。此结构体中的每个字段对应于一个单独的组件。每个字段名称与相应组件的 Tag 属性相匹配。在本例中,handles.figure1 为图窗对象。因此,setappdata 可使用此图窗对象来存储数据。

  7. 在用于更改数据的滑块回调中添加代码。将以下命令添加到函数 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 中。

  8. 在用于检索数据的普通按钮回调中添加代码。将以下命令添加到函数 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 检索数据。

  9. 通过按编辑器工具条中的保存,保存您的代码。

使用 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 之间共享数据

以下是一个使用 guidataUserData 在三个 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 属性,请执行以下操作:

  1. 在回调函数定义中更改名称。

  2. 通过更改传递到匿名函数的第一个参量来更新组件的回调属性。例如,某个普通按钮的原始回调属性可能类似以下所示:

    @(hObject,eventdata)myui('pushbutton1_Callback',...
                               hObject,eventdata,guidata(hObject))

    在此示例中,必须将 'pushbutton1_Callback' 更改为新的函数名称。

  3. 在代码文件中,将对旧函数名称的其他所有引用更改为新函数名称。

删除回调

当您想要删除或更改在最终用户执行特定操作时执行的函数,可以删除回调函数。要删除回调函数,请执行以下操作:

  1. 搜索并替换代码中所有引用该回调函数的实例。

  2. 在 GUIDE 中打开 UI,并在属性检查器中替换所有引用该回调函数的实例。

  3. 删除回调函数。

相关主题