6.QObject定时器

91 阅读4分钟

1.设置布局

image.png

2.定义两个变量

private:
    Ui::Widget *ui;
    int myTimerId;
    int picID;
};

int myTimerId;

  • 作用:存储 定时器的唯一标识符(ID)

  • 详细解释

    • 当你调用 startTimer(1000) 时,Qt 会返回一个 唯一的定时器 ID(整数)。

    • 这个 ID 用于在 timerEvent() 中判断是哪个定时器触发了事件。

    • 还调用 killTimer(myTimerId) 停止特定的定时器。

  • 详细解释

    myTimerId = startTimer(1000); // 启动定时器,并存储 ID

    killTimer(myTimerId); // 停止定时器

3.构造函数

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    picID = 2;  // 初始化图片ID,下一张要显示的是2.jpg

    QPixmap pix("E:\\project\\1.jpg");  // 加载第一张图片(1.jpg)
    ui->label->setPixmap(pix);  // 显示在label上
}
  1. ui->setupUi(this):初始化UI界面(由Qt Designer自动生成)。
  2. picID = 2:设置初始图片序号,表示下一次要加载 2.jpg
  3. QPixmap pix("E:\project\1.jpg"):从硬盘加载 1.jpg
  4. ui->label->setPixmap(pix):将图片显示在 QLabel 上。

4.开始按钮设置定时1秒

4.1在widget.h中

#define TIMEOUT 1*1000

4.2在widget.cpp中

void Widget::on_startButton_clicked()
{
    //开启定时器,并返回定时器编号
    myTimerId = this->startTimer(TIMEOUT);
}
  1. startTimer(TIMEOUT):启动一个定时器,每隔 TIMEOUT(1秒)触发一次 timerEvent
  2. myTimerId = ...:存储定时器ID,用于在 timerEvent 中判断事件来源。

5.定义一个虚函数来执行定时器事件

5.1在widget.h中

public:
    Widget(QWidget *parent = nullptr);
    virtual void timerEvent(QTimerEvent *event);//定义的虚函数
    ~Widget();

4.2在widget.cpp中

我们在project文件下有五张图片 image.png

void Widget::timerEvent(QTimerEvent *event)
{
    // 检查是否是我们的定时器触发的
    if(event->timerId() != myTimerId)
        return;  // 如果不是,直接返回

    QString path("E:\\project\\"); //定义路径
    path += QString::number(picID);  // 拼接图片序号(如 2.jpg)
    path += ".jpg";

    QPixmap pix(path);  // 加载图片
    ui->label->setPixmap(pix);  // 更新显示

    picID++;  // 准备下一张图片
    if(6 == picID)  // 如果超过5.jpg,就回到1.jpg
        picID = 1;
}
  1. if(event->timerId() != myTimerId) return;:确保只处理自己的定时器事件。
  2. QString path = "E:\project\" + QString::number(picID) + ".jpg":构造图片路径(如 E:\project\2.jpg)。
  3. QPixmap pix(path):加载图片到内存。
  4. ui->label->setPixmap(pix):更新 QLabel 显示新图片。
  5. picID++:递增图片序号。
  6. if(6 == picID) picID = 1:实现循环轮播(1.jpg → 2.jpg → ... → 5.jpg → 1.jpg → ...)。

6.停止按钮

在widget.cpp

void Widget::on_cancelButton_clicked()
{
    this->killTimer(myTimerId);  // 停止指定的定时器
}
  • killTimer(myTimerId):停止之前由 startTimer 创建的定时器,防止继续触发 timerEvent

7.重要的三个函数

startTimertimerEventkillTimer)是 Qt 定时器系统的核心组成部分

7.1startTimer(int interval)

1. 作用

启动一个定时器,并返回该定时器的唯一 ID(整数)。

  • 参数

    • interval:定时器触发间隔(单位:毫秒,1000ms = 1秒)。
  • 返回值

    • 定时器的唯一标识符(int),用于后续操作(如停止定时器)。

2. 示例

myTimerId = startTimer(1000);  // 启动一个1秒触发一次的定时器,并存储ID

3. 关键点

  • 调用 startTimer 后,Qt 会自动在每次间隔时间到达时触发 timerEvent 事件。
  • 可以同时启动多个定时器(用不同 ID 区分)。

7.2timeTimer(QTimerEvent *event)

作用

定时器触发时的回调函数,所有定时器事件都会进入此函数。

  • 参数

    • event:包含定时器信息的对象,可通过 event->timerId() 获取触发事件的定时器 ID。

示例

void Widget::timerEvent(QTimerEvent *event) {
    if (event->timerId() != myTimerId) return;  // 检查是否是目标定时器
    // 这里是定时任务逻辑(如切换图片)
}

关键点

  • 必须重写(override)此函数来处理定时任务。
  • 通过 event->timerId() 区分不同的定时器(如果你有多个定时器)。

7.3. killTimer(int timerId)

作用

停止指定的定时器,防止继续触发 timerEvent

  • 参数

    • timerId:要停止的定时器 ID(由 startTimer 返回)。

示例

killTimer(myTimerId);  // 停止myTimerId对应的定时器

关键点

  • 停止后,对应的定时器事件不再触发。
  • 如果传递无效的 timerId,Qt 会忽略(不会报错)。

8.完整流程

deepseek_mermaid_20250709_ed0211.png

9.完整代码

9.1在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);
    virtual void timerEvent(QTimerEvent *event);
    ~Widget();

private slots:
    void on_startButton_clicked();
    
    void on_cancelButton_clicked();
    
private:
    Ui::Widget *ui;
    int myTimerId;
    int picID;
};
#endif // WIDGET_H

9.2在widget.cpp中

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    picID = 2;

    QPixmap pix("E:\\project\\1.jpg");
    ui->label->setPixmap(pix);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_startButton_clicked()
{
    //开启定时器,返回定时器编号
    myTimerId = this->startTimer(TIMEOUT);
}

void Widget::timerEvent(QTimerEvent *event)
{
    if(event->timerId() != myTimerId)
        return;
    QString path("E:\\project\\");
    path += QString::number(picID);
    path += ".jpg";

    QPixmap pix(path);
    ui->label->setPixmap(pix);

    picID++;
    if(6 == picID)
        picID = 1;
}

void Widget::on_cancelButton_clicked()
{
    this->killTimer(myTimerId);
}