Qt 定时器 #

定时器概述 #

Qt 提供了多种定时器实现方式:

text
┌─────────────────────────────────────────────────────────────┐
│                    Qt 定时器类型                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  QTimer                                                     │
│  ├── 最常用的定时器类                                       │
│  ├── 支持单次和重复定时                                     │
│  └── 使用信号槽机制                                         │
│                                                             │
│  QObject::startTimer()                                      │
│  ├── 基于事件的传统定时器                                   │
│  └── 需要重写 timerEvent()                                  │
│                                                             │
│  QBasicTimer                                               │
│  ├── 轻量级定时器                                           │
│  └── 不依赖事件循环                                         │
│                                                             │
│  QElapsedTimer                                             │
│  ├── 高精度计时器                                           │
│  └── 用于测量时间间隔                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

QTimer 基本使用 #

创建和启动定时器 #

cpp
// 创建定时器
QTimer *timer = new QTimer(this);

// 连接超时信号
connect(timer, &QTimer::timeout, []() {
    qDebug() << "Timer triggered";
});

// 启动定时器(毫秒)
timer->start(1000);  // 每 1 秒触发一次

// 或者使用 setInterval
timer->setInterval(1000);
timer->start();

// 停止定时器
timer->stop();

// 检查定时器是否运行
bool running = timer->isActive();

// 获取间隔时间
int interval = timer->interval();

单次定时器 #

cpp
// 方式一:静态函数
QTimer::singleShot(1000, []() {
    qDebug() << "Single shot timer triggered";
});

// 方式二:设置单次属性
QTimer *timer = new QTimer(this);
timer->setSingleShot(true);
timer->start(1000);
connect(timer, &QTimer::timeout, []() {
    qDebug() << "Single shot triggered";
});

定时器精度 #

cpp
// 设置定时器类型
timer->setTimerType(Qt::PreciseTimer);    // 精确计时(1ms精度)
timer->setTimerType(Qt::CoarseTimer);     // 粗略计时(默认,约5%误差)
timer->setTimerType(Qt::VeryCoarseTimer); // 非常粗略(约500ms误差)

// 获取定时器类型
Qt::TimerType type = timer->timerType();

定时器应用示例 #

倒计时器 #

cpp
class CountdownTimer : public QWidget
{
    Q_OBJECT
public:
    CountdownTimer(QWidget *parent = nullptr) : QWidget(parent)
    {
        m_label = new QLabel("60", this);
        m_label->setAlignment(Qt::AlignCenter);
        m_label->setStyleSheet("font-size: 48px;");
        
        m_timer = new QTimer(this);
        connect(m_timer, &QTimer::timeout, this, &CountdownTimer::onTimeout);
        
        QPushButton *startBtn = new QPushButton("Start", this);
        QPushButton *stopBtn = new QPushButton("Stop", this);
        QPushButton *resetBtn = new QPushButton("Reset", this);
        
        connect(startBtn, &QPushButton::clicked, this, &CountdownTimer::start);
        connect(stopBtn, &QPushButton::clicked, this, &CountdownTimer::stop);
        connect(resetBtn, &QPushButton::clicked, this, &CountdownTimer::reset);
        
        QVBoxLayout *layout = new QVBoxLayout(this);
        layout->addWidget(m_label);
        
        QHBoxLayout *btnLayout = new QHBoxLayout;
        btnLayout->addWidget(startBtn);
        btnLayout->addWidget(stopBtn);
        btnLayout->addWidget(resetBtn);
        layout->addLayout(btnLayout);
        
        reset();
    }

private slots:
    void start() { m_timer->start(1000); }
    void stop() { m_timer->stop(); }
    void reset() { m_count = 60; updateDisplay(); }
    
    void onTimeout() {
        if (--m_count <= 0) {
            m_timer->stop();
            m_count = 0;
            emit finished();
        }
        updateDisplay();
    }

signals:
    void finished();

private:
    void updateDisplay() {
        m_label->setText(QString::number(m_count));
    }
    
    QLabel *m_label;
    QTimer *m_timer;
    int m_count;
};

动画效果 #

cpp
class FadeWidget : public QWidget
{
    Q_OBJECT
public:
    FadeWidget(QWidget *parent = nullptr) : QWidget(parent)
    {
        m_timer = new QTimer(this);
        connect(m_timer, &QTimer::timeout, this, &FadeWidget::updateOpacity);
    }
    
    void fadeIn() {
        m_opacity = 0.0;
        m_fadeIn = true;
        m_timer->start(20);
    }
    
    void fadeOut() {
        m_opacity = 1.0;
        m_fadeIn = false;
        m_timer->start(20);
    }

protected:
    void paintEvent(QPaintEvent *) override {
        QPainter painter(this);
        painter.setOpacity(m_opacity);
        painter.fillRect(rect(), Qt::blue);
    }

private slots:
    void updateOpacity() {
        if (m_fadeIn) {
            m_opacity += 0.02;
            if (m_opacity >= 1.0) {
                m_opacity = 1.0;
                m_timer->stop();
            }
        } else {
            m_opacity -= 0.02;
            if (m_opacity <= 0.0) {
                m_opacity = 0.0;
                m_timer->stop();
                hide();
            }
        }
        update();
    }

private:
    QTimer *m_timer;
    double m_opacity = 1.0;
    bool m_fadeIn = true;
};

状态栏时钟 #

cpp
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent)
    {
        // 创建状态栏时钟
        QLabel *timeLabel = new QLabel(this);
        statusBar()->addPermanentWidget(timeLabel);
        
        // 更新时钟
        QTimer *timer = new QTimer(this);
        connect(timer, &QTimer::timeout, [timeLabel]() {
            timeLabel->setText(QTime::currentTime().toString("hh:mm:ss"));
        });
        timer->start(1000);
        
        // 立即显示一次
        timeLabel->setText(QTime::currentTime().toString("hh:mm:ss"));
    }
};

QObject 定时器 #

使用 timerEvent #

cpp
class MyObject : public QObject
{
    Q_OBJECT
public:
    MyObject(QObject *parent = nullptr) : QObject(parent)
    {
        // 启动定时器,返回定时器 ID
        m_timerId = startTimer(1000);  // 1 秒
    }
    
    ~MyObject()
    {
        // 停止定时器
        killTimer(m_timerId);
    }

protected:
    void timerEvent(QTimerEvent *event) override
    {
        if (event->timerId() == m_timerId) {
            qDebug() << "Timer event triggered";
        }
    }

private:
    int m_timerId;
};

多个定时器 #

cpp
class MultiTimer : public QObject
{
    Q_OBJECT
public:
    MultiTimer(QObject *parent = nullptr) : QObject(parent)
    {
        m_timer1 = startTimer(1000);   // 1 秒
        m_timer2 = startTimer(2000);   // 2 秒
        m_timer3 = startTimer(5000);   // 5 秒
    }

protected:
    void timerEvent(QTimerEvent *event) override
    {
        int id = event->timerId();
        
        if (id == m_timer1) {
            qDebug() << "Timer 1 (1s)";
        } else if (id == m_timer2) {
            qDebug() << "Timer 2 (2s)";
        } else if (id == m_timer3) {
            qDebug() << "Timer 3 (5s)";
        }
    }

private:
    int m_timer1, m_timer2, m_timer3;
};

QElapsedTimer 高精度计时 #

基本使用 #

cpp
QElapsedTimer elapsedTimer;

// 开始计时
elapsedTimer.start();

// 执行一些操作
doSomething();

// 获取经过的时间
qint64 elapsedMs = elapsedTimer.elapsed();     // 毫秒
qint64 elapsedNs = elapsedTimer.nsecsElapsed(); // 纳秒

// 检查是否过期
if (elapsedTimer.hasExpired(5000)) {
    qDebug() << "More than 5 seconds passed";
}

// 重新开始
elapsedTimer.restart();

性能测量 #

cpp
void measurePerformance()
{
    QElapsedTimer timer;
    timer.start();
    
    // 执行需要测量的代码
    for (int i = 0; i < 1000000; ++i) {
        // ...
    }
    
    qDebug() << "Elapsed:" << timer.elapsed() << "ms";
    qDebug() << "Elapsed:" << timer.nsecsElapsed() << "ns";
}

定时器最佳实践 #

避免定时器阻塞 #

cpp
// 错误:在定时器槽中执行耗时操作
connect(timer, &QTimer::timeout, []() {
    // 这会阻塞事件循环
    heavyOperation();
});

// 正确:使用工作线程
class Worker : public QObject
{
    Q_OBJECT
public slots:
    void doWork() {
        heavyOperation();
        emit workFinished();
    }
signals:
    void workFinished();
};

// 在工作线程中执行
QThread *thread = new QThread;
Worker *worker = new Worker;
worker->moveToThread(thread);
thread->start();

connect(timer, &QTimer::timeout, worker, &Worker::doWork);

合理设置间隔 #

cpp
// 避免过于频繁的定时器
timer->start(1);  // 太频繁,可能导致性能问题

// 合理的间隔
timer->start(16);   // 约 60 FPS
timer->start(33);   // 约 30 FPS
timer->start(100);  // 10 次/秒
timer->start(1000); // 1 次/秒

动态调整间隔 #

cpp
class AdaptiveTimer : public QObject
{
    Q_OBJECT
public:
    AdaptiveTimer(QObject *parent = nullptr) : QObject(parent)
    {
        m_timer = new QTimer(this);
        connect(m_timer, &QTimer::timeout, this, &AdaptiveTimer::onTimeout);
        m_timer->start(100);
    }

private slots:
    void onTimeout() {
        if (needsMoreFrequent()) {
            m_timer->setInterval(50);
        } else if (needsLessFrequent()) {
            m_timer->setInterval(200);
        }
        
        // 执行任务
        doTask();
    }

private:
    QTimer *m_timer;
};

下一步 #

现在你已经掌握了定时器的使用,接下来学习 文件操作,了解 Qt 的文件处理能力!

最后更新:2026-03-29