Main Content

事件和侦听程序语法

要实现的组件

事件和侦听程序的实现涉及以下各部分:

命名事件

通过在 events 代码块中声明事件名称来定义事件。例如,以下类创建名为 ToggleState 的事件:

classdef ToggleButton < handle
   properties
      State = false
   end
   events
      ToggleState
   end
end

事件不能与定义该事件的类具有相同名称。

触发事件

OnStateChange 方法调用 notify 来触发 ToggleState 事件。将作为事件源的对象的句柄和事件名称传递给 notify

classdef ToggleButton < handle
   properties
      State = false
   end
   events
      ToggleState
   end
   methods
      function OnStateChange(obj,newState)
         if newState ~= obj.State
            obj.State = newState;
            notify(obj,'ToggleState');
         end
      end
   end
end

侦听事件

在调用 notify 而触发事件后,MATLAB® 向为该事件和源对象定义的所有侦听程序广播消息。创建侦听程序有两种方式:使用句柄类 addlistenerlistener 方法。

使用 addlistener 创建持久侦听程序

如果您希望侦听程序在通常的变量作用域外持久存在,请使用 addlistener 创建它。事件源对象中包含对侦听程序对象的引用。当销毁事件源对象时,MATLAB 会同时销毁对应的侦听程序。

以下代码定义 ToggleState 事件的侦听程序:

lh = addlistener(obj,'ToggleState',@RespondToToggle.handleEvnt);

addlistener 有以下参量:

  • obj - 作为事件源的对象

  • ToggleState - 作为 char 向量传递的事件名称

  • @RespondToToggle.handleEvnt - 回调函数的函数句柄(请参阅以下定义定义侦听程序)。

使用 handle.listener 来分离侦听程序和源

如果您要管理侦听程序的生命周期,并且不希望事件源和侦听程序对象互相耦合,请使用 listener 方法创建侦听程序。当销毁事件源时,MATLAB 不会同时销毁由 listener 创建的侦听程序。但是,当使用 listener 创建侦听程序时,代码必须使侦听程序对象句柄保持在作用域内。

listener 方法需要的参量与 addlistener 相同:事件命名对象、事件名称和回调函数句柄。listener 返回侦听程序对象的句柄。

lh = listener(obj,'EventName',@callbackFunction)

例如,以下代码使用前面讨论过的 ToggleState 事件:

lh = listener(obj,'ToggleState',@RespondToToggle.handleEvnt)

回调函数

侦听程序回调函数必须接受至少两个参量,MATLAB 会自动将这两个参量传递给回调函数。以下是必需的参量:

定义回调函数以接受源对象和事件数据参量。

function callbackFunction(src,evtdata)
   ...
end

有关回调语法的详细信息,请参阅Listener Callback Syntax

定义侦听程序

RespondToToggle 类定义侦听 ToggleButton 类中定义的 ToggleState 事件的对象。

classdef RespondToToggle < handle
   methods
      function obj = RespondToToggle(toggle_button_obj)
         addlistener(toggle_button_obj,'ToggleState',@RespondToToggle.handleEvnt);
      end
   end
   methods (Static)
      function handleEvnt(src,~)
         if src.State
            disp('ToggleState is true')
         else
            disp('ToggleState is false')
         end
      end
   end
end

RespondToToggle 在其构造函数中添加侦听程序。在这种情况下,类将回调 (handleEvnt) 定义为接受两个必需参量的静态方法:

  • src - 触发事件的对象(即 ToggleButton 对象)的句柄

  • evtdata - event.EventData 对象

例如,以下代码段创建两个类的对象:

tb = ToggleButton;
rtt = RespondToToggle(tb);

每当您调用 ToggleButton 对象的 OnStateChange 方法时,notify 都会触发事件。在本例中,回调显示 State 属性的值:

tb.OnStateChange(true)
ToggleState is true
tb.OnStateChange(false)
ToggleState is false

删除侦听程序

通过对侦听程序对象的句柄调用 delete 来删除侦听程序对象。例如,如果类 RespondToToggle 将侦听程序句柄保存为属性,则您可以删除该侦听程序。

classdef RespondToToggle < handle
   properties
      ListenerHandle % Property for listener handle
   end
   methods
      function obj = RespondToToggle(toggle_button_obj)
         hl = addlistener(toggle_button_obj,'ToggleState',@RespondToToggle.handleEvnt);
         obj.ListenerHandle = hl; % Save listener handle
      end
   end
   methods (Static)
      function handleEvnt(src,~)
         if src.State
            disp('ToggleState is true')
         else
            disp('ToggleState is false')
         end
      end
   end
end

通过更改此代码,您可以从 RespondToToggle 类的实例中删除侦听程序。例如:

tb = ToggleButton;
rtt = RespondToToggle(tb); 

对象 rtt 正在侦听由对象 tb 触发的 ToggleState 事件。要删除侦听程序,请对包含侦听程序句柄的属性调用 delete

delete(rtt.ListenerHandle)

要临时停用侦听程序,请参阅Temporarily Deactivate Listeners

定义特定于事件的数据

假设您要将切换按钮的状态作为事件的结果传递给侦听程序回调。通过子类化 event.EventData 类并添加属性来包含相关信息,您可以向默认事件数据中添加更多数据。然后,您可以将此对象传递给 notify 方法。

注意

要保存和加载作为 event.EventData 的子类的对象,如 ToggleEventData,请为该子类启用 ConstructOnLoad 类属性。

classdef (ConstructOnLoad) ToggleEventData < event.EventData
   properties
      NewState
   end
   
   methods
      function data = ToggleEventData(newState)
         data.NewState = newState;
      end
   end
end

notify 的调用可以使用 ToggleEventData 构造函数来创建必要的参量。

evtdata = ToggleEventData(newState);
notify(obj,'ToggleState',evtdata);

相关主题