1.Qt单次定时器使用全攻略
在Qt框架中,QTimer::singleShot 是实现延迟执行函数的常用方法。以下是具体实现步骤和代码示例:
核心代码
cpp
// 在某个类(如MyClass)的头文件中声明槽函数
class MyClass : public QObject {
Q_OBJECT
public:
explicit MyClass(QObject *parent = nullptr);
private slots:
void delayedFunction(); // 声明延迟执行的槽函数
};
// 在源文件中实现
MyClass::MyClass(QObject *parent) : QObject(parent) {}
void MyClass::delayedFunction() {
qDebug() << "1秒后执行此函数";
// 这里添加需要延迟执行的逻辑
}
// 触发延迟调用
QTimer::singleShot(1000, this, &MyClass::delayedFunction); // 1000毫秒=1秒
关键点说明
- 时间单位:
singleShot的第一个参数是毫秒,1秒需写为1000 - 槽函数要求:
- 必须是类的成员函数
- 使用
slots关键字声明(Qt5+ 支持新语法) - 参数需与调用时匹配(本例无参数)
- 连接方式:
- 现代Qt推荐使用函数指针语法
&ClassName::functionName - 传统方式可用
SLOT(delayedFunction())(需配合signals:声明)
- 现代Qt推荐使用函数指针语法
完整示例(主函数)
cpp
#include <QCoreApplication>
#include <QTimer>
#include <QDebug>
class Worker : public QObject {
Q_OBJECT
public:
Worker() {
QTimer::singleShot(1000, this, [this]() {
qDebug() << "Lambda表达式延迟执行";
// 可直接使用成员变量
});
}
};
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
Worker w;
return a.exec();
}
// 必须包含以下宏以启用信号槽
#include "main.moc"
注意事项
- 作用域:确保调用
singleShot的对象(如this)在延迟期间未被销毁 - 线程安全:在非主线程使用时需配合
QThread和事件循环 - 取消操作:Qt5.15+ 可通过
QDeadlineTimer实现取消,旧版本需自定义标记位 - 参数传递:使用Lambda表达式可方便传递参数:
cppQString data = "参数"; QTimer::singleShot(1000, this, [=]() { qDebug() << "收到参数:" << data; });
替代方案(Qt6推荐)
cpp
// 使用QDeadlineTimer(更精确的时间控制)
QDeadlineTimer deadline(1000);
QTimer::singleShot(deadline, this, &MyClass::myFunction);
此方法适用于Qt5及以上版本,在GUI和非GUI程序中均可使用。实际开发中建议将延迟操作封装在独立类中,避免直接使用Lambda导致代码分散。
2.QTimer::singleShot 一共有几种重载
根据搜索结果,QTimer::singleShot 共有 7种主要重载形式,以下以表格形式对比说明:
| 重载函数签名 | 参数类型 | 用途说明 | 版本引入 | 注意事项 |
|---|---|---|---|---|
void QTimer::singleShot(int msec, const QObject *receiver, const char *member) | 毫秒数、接收对象、成员函数名 | 调用接收对象的槽函数 | Qt 4.x | 需确保接收对象在超时前未销毁 |
template<typename Func> void QTimer::singleShot(int msec, Func func) | 毫秒数、可调用对象(Lambda/函数指针) | 执行任意可调用对象 | Qt 5.3+ | 支持Lambda,需C++11及以上 |
void QTimer::singleShot(std::chrono::milliseconds msec, const QObject *receiver, const char *member) | C++11时间库、接收对象、成员函数 | 使用标准时间库指定时长 | Qt 5.8+ | 需包含<chrono>头文件 |
void QTimer::singleShot(const QTime &time, const QObject *receiver, const char *member) | 绝对时间点、接收对象、成员函数 | 在指定绝对时间触发 | Qt 5.14+ | 需确保系统时间准确 |
void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member) | 毫秒数、定时器类型、接收对象、成员函数 | 指定定时器精度类型 | Qt 5.x | Qt::PreciseTimer精度更高,CoarseTimer资源消耗低 |
void QTimer::singleShot(int msec, const QObject *context, Functor functor) | 毫秒数、上下文对象、Functor | 绑定上下文对象执行回调 | Qt 5.x | Functor需为可调用对象类型 |
void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor) | 毫秒数、定时器类型、上下文对象、Functor | 结合定时器类型与上下文 | Qt 5.x | 适用于需要精确控制场景 |
补充说明:
- 线程安全:当
receiver属于主线程时,回调会在主线程执行;若在子线程调用,需确保接收对象线程事件循环运行。 - 版本差异:
- Qt 6中,部分重载返回类型从
QTimer*改为void(如基于信号的重载)。 std::chrono参数需Qt 5.8+,QTime参数需Qt 5.14+。
- Qt 6中,部分重载返回类型从
- 最佳实践:
- 优先使用Lambda表达式(C++11+),避免定义额外槽函数。
- 短延迟(<2000ms)建议用
Qt::PreciseTimer,长延迟用Qt::CoarseTimer。 - 跨线程操作时,使用
Qt::QueuedConnection确保线程安全。
如需具体代码示例或进一步解释某类重载,可随时补充提问。
1万+

被折叠的 条评论
为什么被折叠?



