事件和侦听程序语法
要实现的组件
事件和侦听程序的实现涉及以下各部分:
指定句柄类中事件的名称 - 命名事件。
当动作发生时触发事件的函数或方法 - 触发事件。
侦听程序对象执行回调函数以响应触发的事件 - 侦听事件。
事件传递给回调函数的默认或自定义事件数据 - 定义特定于事件的数据。
命名事件
通过在 events
代码块中声明事件名称来定义事件。例如,以下类创建名为 ToggledState
的事件:
classdef ToggleButton < handle properties State = false end events ToggledState end end
触发事件
OnStateChange
方法调用 notify
来触发 ToggledState
事件。将作为事件源的对象的句柄和事件名称传递给 notify
。
classdef ToggleButton < handle properties State = false end events ToggledState end methods function OnStateChange(obj,newState) if newState ~= obj.State obj.State = newState; notify(obj,'ToggledState'); end end end end
侦听事件
在调用 notify
而触发事件后,MATLAB® 向为该事件和源对象定义的所有侦听程序广播消息。创建侦听程序有两种方式:使用句柄类 addlistener
或 listener
方法。
使用 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 会自动将这两个参数传递给回调函数。以下是必需的参数:
事件源 - 即导致调用
addlistener
或event.listener
的obj
。event.EventData
对象或event.EventData
的子类,如定义特定于事件的数据中所述的ToggleEventData
对象。
定义回调函数以接受源对象和事件数据参数。
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,'ToggledState',@RespondToToggle.handleEvnt); end end methods (Static) function handleEvnt(src,~) if src.State disp('ToggledState is true') else disp('ToggledState 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)
ToggledState is true
tb.OnStateChange(false)
ToggledState 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,'ToggledState',@RespondToToggle.handleEvnt); obj.ListenerHandle = hl; % Save listener handle end end methods (Static) function handleEvnt(src,~) if src.State disp('ToggledState is true') else disp('ToggledState 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,'ToggledState',evtdata);