目录
一、项目介绍
本文中将实现两个Demo,第一个Demo是实时呈现系统时间,它的功能实现的是:每间隔1秒钟时间,执行一次获取系统时间并呈现在窗口的编辑框中的操作一次。
第二个Demo是实现倒计时功能,它的功能实现的是:从5开始,每隔一秒钟减一,减到0为止。
二、timer函数介绍
timer
调度 MATLAB 命令的执行
使用 timer 调度由 MATLAB回调函数组成的任务的一次或多次执行。如果您调度一个计时器多次执行命令,您可以通过调整该计时器的属性,指定各次执行之间的时间间隔以及如何处理排队冲突。
当计时器启动 (StartFcn)、执行 (TimerFcn)、停止 (StopFcn) 或遇到错误 (ErrorFcn) 时,计时器对象支持回调函数。
t = timer(Name,Value)
创建一个空的 timer 对象,以排定 MATLAB 命令的执行。 指定使用一个或多个 Name-Value 参数的其他选项。
该函数的属性主要包括四种,分别是:回调函数属性、计时属性、标签属性和只读属性。
2.1 回调函数属性
2.1.1 TimerFcn—计时器回调函数
计时器回调函数,指定为字符向量、字符串标量、函数句柄或元胞数组。必须定义此属性,才能启动计时器。
- 如果使用函数句柄指定此属性,当 MATLAB 执行回调时,它会将 timer 对象和事件结构体传递给回调函数。事件结构体的 Type 字段中包含事件的类型,Data 字段中包含事件的时间。
- 如果使用字符向量或字符串标量指定此属性,则当 MATLAB 执行回调时,它会对字符向量中包含的 MATLAB 代码求值。不建议将回调定义为字符向量。将函数指定为函数句柄的用法可以让 MATLAB 为回调函数提供重要信息。
如果回调函数接受除 timer 对象和事件数据以外的参数,请将此属性指定为包含函数句柄和其他参数的元胞数组。
示例: t = timer(‘TimerFcn’,{@timerCallback, handles.text1});
其中’TimerFcn’指向一个函数,这个函数一般的写法是用@指向一个函数。像以上代码中写的@timerCallback,它表示的意思是,这个Timer控件指向的是一个叫做timerCallback的函数。有时候光是执行某个函数还不够,有时候函数还需要一个或者N个输入参数,像这个timerCallback函数就需要输入文本框的句柄handles.text1,方便每次执行函数时候在函数的内部对编辑框中的字符串内容进行修改。具体的实现,需要用到 {} 大括号,第一个填写函数名,第二个填写输入参数(我们管这个参数叫做实参,这里的实参,我们写的是 handles.text1)。
2.1.2 StartFcn—计时器启动回调函数
2.1.3 StopFcn—计时器停止回调函数
计时器停止回调函数,指定为字符向量、字符串标量、函数句柄或元胞数组。
计时器会在以下情况下停止:
- 调用计时器 stop 方法。
- 计时器完成执行 TimerFcn。换句话说,TasksExecuted 的值达到 TasksToExecute 设置的限值。
- 出现错误。首先调用 ErrorFcn 回调,然后调用 StopFcn 回调。
2.2 计时属性
2.2.1 Period—各次执行之间的延迟
单位为秒,默认值为1。Period = 1.0表示的是timerCallback函数每间隔1秒时间就执行一次。
各次执行之间的延迟,以秒为单位,指定为大于 0.001 的数字。要使计时器使用 Period,您必须设置 ExecutionMode 和 TasksToExecute 以排定多个计时器对象回调事件的执行。
示例: t = timer(‘Period’,5)
2.2.2 StartDelay—计时器启动和第一次执行之间的延迟
计时器启动和第一次执行之间的延迟,以秒为单位,指定为大于或等于 0 的数字。如果 Running = ‘on’,则 StartDelay 是只读的。
示例:
t = timer(‘StartDelay’,2)
上述代码表示启动后延迟2秒计时器开始执行
2.2.3 ExecutionMode—计时器函数回调调度
ExecutionMode 执行的模式就是确定TimerFcn执行周期计算的始末点。
计时器函数回调调度,指定为下表中的值之一。当 Running=‘on’ 时,ExecutionMode 为只读。下表概述了执行模式。
执行模式时间Period起点‘singleShot’计时器回调函数只执行一次。因此Period属性没有任何作用。**(默认)‘fixedRate’在将计时器回调函数添加到MATLAB执行队列后立即启动【即前后两次被加入到执行语句队列时刻之间的间隔】‘fixedDelay’在计时器回调函数经过一段时滞(因MATLAB执行队列中出现延迟)后重新开始执行时启动 【即上一次开始执行到下一次被加入队列之间的间隔】(常用)**‘fixedSpacing’在计时器回调函数完成执行时启动【即上一次TimerFcn执行完毕时刻到下一次TimerFcn加入队列时刻之间的间隔】
‘singleShot’ 是 timer 类的单次执行模式,并且是默认值。
‘fixedDelay’、‘fixedRate’ 和 ‘fixedSpacing’ 是三个受支持的多次执行模式。这些模式定义 Period 属性的起点。Period 属性指定执行之间的间隔时间(保持不变)。只有执行起点是不同的。
一般我们设置Timer控件,都是要每间隔一个固定的时间运行函数一次,所以我们都会选’fixedDelay’。
三、GUI界面设计
GUI界面中放入一个静态文本控件,并将其Tag属性设置为text1,如下图所示:
四、Demo1——实时呈现系统时间代码实现
4.1 创建并开启时间控制器
我们需要在程序初始化的时候(OpeningFcn函数用于GUI的初始化),创建并开启这个时间控制器。
在该函数中编写如下代码:
% 创建 timer 对象对象的代码
timePeriod =1.0;
t =timer('TimerFcn',{@timerCallback, handles.text1},'ExecutionMode','fixedDelay','Period', timePeriod);% 绑定机制:设置窗口关闭的回调函数
set(handles.figure1,'DeleteFcn',{@DeleteFcn, t});% 启动定时器
start(t);
解释:
(1)第一个’TimerFcn’指向一个函数,这个函数一般的写法是用@指向一个函数。像以上代码中写的@timerCallback,它表示的意思是,这个Timer控件指向的是一个叫做timerCallback的函数。有时候光是执行某个函数还不够,有时候函数还需要一个或者N个输入参数,像这个timerCallback函数就需要输入编辑框的句柄,方便每次执行函数时候在函数的内部对编辑框中的字符串内容进行修改。具体的实现,需要用到 {} 大括号,第一个填写函数名,第二个填写输入参数(我们管这个参数叫做实参,这里的实参,我们写的是 handles.text1)。
(2)ExecutionMode 执行的模式就是确定TimerFcn执行周期计算的始末点。一般我们设置Timer控件,都是要每间隔一个固定的时间运行函数一次,所以我们都会选’fixedDelay’。
(3)Period属性对应的变量的单位为秒。timePeriod = 1.0表示的是timerCallback函数每间隔1秒时间就执行一次。把timePeriod提前了,就是因为这个参数修改的频率比较高,经常需要调整,对这样的参数提前到函数前一行的位置,这会让参数修改的过程更方便。
(4)关闭并删除时间控制器语句,这个将在下文介绍
(5)start(t);用于启动定时器
4.2 TimerFcn的回调函数
接下来是TimerFcn自身的回调函数,相当于在间隔 timePeriod 时间调用一次这个函数,以下代码是在timer回调函数中实现每次都显示从系统获取的时间的功能:
function timerCallback(obj, event, hEdit)set(hEdit,'String',datestr(now,'HH:MM:SS'));
now函数返回表示当前时间的日期序列值,datestr函数将日期和时间now转换为字符串格式。
4.3 关闭并删除时间控制器
一旦创建了Timer控件,一定要记得在窗口关闭退出的时候把Timer时间控制器给关掉。然而,整个窗口关闭的函数DeleteFcn默认并没有存在在.m文件的代码中。我们需要手动输入一段代码,或者在属性窗口中点击一个按钮,把这个删除函数DeleteFcn补充完整,然后在函数中关闭并删除时间控件。
set(handles.figure1,'DeleteFcn',{@DeleteFcn, t});
这是一种绑定机制,将窗口的关闭函数指向一个DeleteFcn。其代码如下:
% 窗口关闭的响应函数-停止并删除
function DeleteFcn(hObject, eventdata, t)stop(t);delete(t);
五、Demo2——倒计时功能代码实现
Demo2的GUI界面与Demo1略有不同,在Demo1的基础上增加了一个按钮,用于控制倒计时的启动,如下图所示:
5.1 创建并开启时间控制器
初始化函数中的代码如下:
set(handles.text1,'String','5');%将文本框中的字符串设置为'5'% 时间间隔设置为 1 秒
timePeriod =1.0;
t =timer('timerFcn',{@timerCallback, handles.text1},'ExecutionMode','fixedDelay','Period',timePeriod,'StartDelay',1);
handles.t = t;
handles.State =0;set(handles.figure1,'DeleteFcn',{@DeleteFcn});% Update handles structure
guidata(hObject, handles);
这里设置StartDelay为1秒,表示延迟1秒开始执行。
假如你是从5开始倒计时,界面初始化,timer函数一运行完,我们在界面上首先看到的不是5,而是4。如果想在一开始看到5,就需要主动延迟一段时间(1秒)。
handles.t 和handles.State = 0在GUI中表示声明t和State为全局变量,当然也可以用global t代替,这里两种方案都可以,看个人选择了。
handles.State = 0; 这句话的功能是用来标记当前timer的开关状态的,一开始的时候,timer是关闭的状态,就标记为0,关于其详细内容可以参考下文。
最后利用guidata(hObject, handles);语句更新handles结构体。
5.2 点击按钮的回调函数
在点击按钮的回调函数中添加如下代码:
if handles.State ==0start(handles.t);
handles.State =1;elsestop(handles.t);
handles.State =0;
end
% Update handles structure
guidata(hObject, handles);
点击按钮,会切换状态:
- 如果当前的状态是0, 表示的是timer处于关闭状态,这个时候要开启start这个timer控件;
- 如果当前的状态是1,表示的是timer处于打开的状态,这个时候要关闭stop这个timer控件。
最后更新handles结构体。
5.3 TimerFcn的回调函数
代码如下:
function timerCallback(obj, event, hEdit)
tmpStr =get(hEdit,'String');
tmpNumber =str2num(tmpStr);%转为数值类型
if tmpNumber <1stop(handles.t);else
tmpNumber = tmpNumber -1;
tmpDigitString =num2str(tmpNumber);set(hEdit,'String',tmpDigitString);
end
解释:从文本框中取出字符串,转换为数值,如果这个值小于1,那么就停止timer;反之,这个值如果大于或者等于1,那么这个值就减1,再转回为字符串,输出到编辑框中。
5.4 关闭并删除时间控制器
一旦创建了Timer控件,一定要记得在窗口关闭退出的时候把Timer时间控制器给关掉。然而,整个窗口关闭的函数DeleteFcn默认并没有存在在.m文件的代码中。我们需要手动输入一段代码,或者在属性窗口中点击一个按钮,把这个删除函数DeleteFcn补充完整,然后在函数中关闭并删除时间控件。
set(handles.figure1,'DeleteFcn',{@DeleteFcn});
这是一种绑定机制,将窗口的关闭函数指向一个DeleteFcn。其代码如下:
% 窗口关闭的响应函数-停止并删除
function DeleteFcn(hObject, eventdata, handles)stop(handles.t);delete(handles.t);
六、运行效果
Demo1——实时呈现系统时间代码实现的运行效果如下:
Demo2——倒计时功能代码实现的运行效果如下:
Demo1和Demo2的代码可以参考:Demo资源
ok,以上便是本文的全部内容了,如果对你有所帮助,记得点个赞哟~
参考:
https://ww2.mathworks.cn/help/matlab/ref/timer.html
https://ww2.mathworks.cn/help/matlab/matlab_prog/timer-callback-functions.html
https://zhuanlan.zhihu.com/p/56480845
版权归原作者 wendy_ya 所有, 如有侵权,请联系我们删除。