定时器
定时器图片流水灯案例
实现效果:构建一个界面,点击开始按钮轮流播放文件夹下图片,点击停止按钮停止播放
构建页面,上部是一个没有内容的 label
下面是开始和暂停按钮,各自的名称分别为 startBtn 和 stopBtn
先保持在 UI 设计界面别走
右键点击开始和停止按钮,选择添加槽,各自添加一个 clicked 槽!
此时不需要为槽添加响应内容,我们打开 Widget.h
下图注释部分即为我们需要添加的部分
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
// 第一步:定义轮播间隔时间
#define TIMEOUT 1*1000
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
// 第二步:定义虚函数timerEvent,表示定时器事件,他接受一个QTimerEvent类型的参数
virtual void timerEvent(QTimerEvent *evt);
~Widget();
private slots:
// 第三步:我们为两个按钮添加槽后,这边自动生成的代码
void on_startBtn_clicked();
void on_stopBtn_clicked();
private:
Ui::Widget *ui;
// 第四步:定义定时器ID(保证定时器的唯一性),以及当前图片轮播ID
int myTimerId;
int pixId;
};
#endif // WIDGET_H
头文件已经处理完毕,打开 Widget.cpp
首先在 widget 初始化时,我们就需要为 label 指定显示一张图片
#include "Widget.h"
#include "ui_Widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 下一张图片ID
pixId = 2;
// 默认显示的图片,即第一张图片1.png
QPixmap pix("E:\\singlechip\\Linux\\qt\\qt_demo2\\image\\1.png");
// 将图片绑定到界面内部的label里去
ui->label->setPixmap(pix);
}
为两个信号槽定义代码
// 开始按钮
void Widget::on_startBtn_clicked()
{
// 开启定时器,并且返回定时器编号
myTimerId = this->startTimer(TIMEOUT);
}
// 停止按钮
void Widget::on_stopBtn_clicked()
{
// 杀死指定ID的定时器
this->killTimer(myTimerId);
}
还记得我们之前在头文件中注册的虚函数 timerEvent
吗?
我们需要在这边实现它,定义事件处理函数
void Widget::timerEvent(QTimerEvent *evt)
{
// 如果取得的定时器ID不对应,那么不执行后续代码
if(evt->timerId()!=myTimerId) return;
// 字符串拼接获得图片路径
QString path("E:\\singlechip\\Linux\\qt\\qt_demo2\\image\\");
path+=QString::number(pixId);
path+=".png";
// 将图片路径绑定到label上,以便显示图片
QPixmap pix(path);
ui->label->setPixmap(pix);
// 每次显示完毕后ID都自增一次,直到递增超过文件夹下最大图片数量,就重置为1,从头开始显示
pixId++;
if(pixId==3) pixId=1;
}
这是完整的 Widget.cpp 代码:
#include "Widget.h"
#include "ui_Widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
pixId = 2;
QPixmap pix("E:\\singlechip\\Linux\\qt\\qt_demo2\\image\\1.png");
ui->label->setPixmap(pix);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_startBtn_clicked()
{
// 开启定时器,并且返回定时器编号
myTimerId = this->startTimer(TIMEOUT);
}
void Widget::timerEvent(QTimerEvent *evt)
{
if(evt->timerId()!=myTimerId) return;
QString path("E:\\singlechip\\Linux\\qt\\qt_demo2\\image\\");
path+=QString::number(pixId);
path+=".png";
QPixmap pix(path);
ui->label->setPixmap(pix);
pixId++;
if(pixId==3) pixId=1;
}
void Widget::on_stopBtn_clicked()
{
this->killTimer(myTimerId);
}
大功告成,你现在可以点击左下角的绿色按钮执行测试了
QTimer
QTimer 的使用方式和上面那个差不多,只是稍微流程有些变动
打开 widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
// 导入QTimer
#include <QTimer>
// 设置好间隔时间
#define TIMEOUT 1*1000
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
// 需要手动在此注册超时函数的槽
void timeout_slot();
// 定义开始和停止按钮的点击槽
void on_startBtn_clicked();
void on_stopBtn_clicked();
private:
Ui::Widget *ui;
// 定义QTimer全局变量
QTimer *timer;
// 定义计数器,指示当前数字
int currentNumber;
};
#endif // WIDGET_H
这是对应的 widget.cpp 代码清单
#include "Widget.h"
#include "ui_Widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 实例化计时器
timer = new QTimer;
// 初始值为0,显示在label内部,注意数值和文本之间的类型转换
currentNumber=0;
ui->label->setText(QString::number(currentNumber));
// 使用connect链接信号和槽!
connect(timer,&QTimer::timeout,this,&Widget::timeout_slot);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_startBtn_clicked()
{
// 开启计时器
timer->start(TIMEOUT);
}
// 超时函数,每经过一次计时周期(TIMEOUT的长度),就会执行一次如下槽内的代码
void Widget::timeout_slot()
{
currentNumber++;
ui->label->setText(QString::number(currentNumber));
}
void Widget::on_stopBtn_clicked()
{
// 停止计时器
timer->stop();
}