You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++ Qt中实现可暂停/恢复且保留剩余时间的定时器?

Qt 可暂停恢复且保留剩余时间的定时器实现

你的两种尝试都存在关键缺陷:

  • 直接调用start(_interval)会重置定时器剩余时间为原间隔,无法保留暂停时的剩余时长。
  • 调用start(remainingTime)会将定时器的永久间隔修改为剩余时间,导致后续触发都按该短间隔执行,不符合“恢复后仍按原间隔触发”的需求。

解决方案:封装自定义可暂停定时器

通过封装一个继承自QObject的自定义类,内部管理原始间隔、剩余时间和定时器状态,实现暂停时保留剩余时间、恢复后先走完剩余时长再回归原间隔的逻辑:

#include <QObject>
#include <QTimer>

class PauseableTimer : public QObject
{
    Q_OBJECT
public:
    explicit PauseableTimer(QObject *parent = nullptr) : QObject(parent) {
        _timer = new QTimer(this);
        connect(_timer, &QTimer::timeout, this, &PauseableTimer::onInternalTimeout);
    }

    // 设置定时器的原始重复间隔
    void setInterval(int msec) {
        _originalInterval = msec;
    }

    // 首次启动定时器(按原始间隔重复触发)
    void start() {
        _remainingTime = -1;
        _isResuming = false;
        _timer->setSingleShot(false);
        _timer->start(_originalInterval);
    }

    // 暂停定时器,记录当前剩余时间
    void pause() {
        if (_timer->isActive()) {
            _remainingTime = _timer->remainingTime();
            _timer->stop();
        }
    }

    // 恢复定时器:先走完剩余时间,再回归原始间隔重复触发
    void resume() {
        if (!_timer->isActive()) {
            if (_remainingTime != -1) {
                _isResuming = true;
                _timer->setSingleShot(true);
                _timer->start(_remainingTime);
            } else {
                start();
            }
        }
    }

    // 切换定时器的启停状态(暂停/恢复)
    void toggle() {
        if (_timer->isActive()) {
            pause();
        } else {
            resume();
        }
    }

    // 判断定时器是否处于运行状态
    bool isActive() const {
        return _timer->isActive();
    }

signals:
    // 对外暴露的timeout信号,与QTimer行为一致
    void timeout();

private slots:
    void onInternalTimeout() {
        if (_isResuming) {
            // 剩余时间触发后,切换回原始间隔的重复定时器
            _isResuming = false;
            _remainingTime = -1;
            _timer->setSingleShot(false);
            _timer->start(_originalInterval);
        }
        emit timeout();
    }

private:
    QTimer* _timer;
    int _originalInterval = 0;
    int _remainingTime = -1;
    bool _isResuming = false;
};

使用示例

在你的业务代码中,可以像使用普通QTimer一样使用这个自定义类:

// 创建定时器实例
PauseableTimer* timer = new PauseableTimer(this);
// 设置原始间隔为1000ms
timer->setInterval(1000);
// 连接timeout信号到你的处理槽函数
connect(timer, &PauseableTimer::timeout, this, &YourClass::handleTimerTimeout);

// 实现切换启停的函数
void togglePlay() {
    timer->toggle();
}

// 定时器触发后的业务处理
void handleTimerTimeout() {
    // 这里编写你的timeout逻辑
}

这个实现完全满足你的需求:

  1. 暂停时会记录当前剩余时间
  2. 恢复后先等待剩余时间触发一次timeout
  3. 后续触发将严格按照原始间隔(1000ms)执行

内容的提问来源于stack exchange,提问作者Allen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:32:13