QT定时器



在Qt中使用定时器有两种方法,一种是使用QObiect类的定时器;一种是使用QTimer类。定时器的精确性依赖于操作系统和硬件,大多数平台支持20ms的精确度。

1.QObject类的定时器

    QObject是所有Qt对象的基类,它提供了一个基本的定时器。通过QObject::startTimer(),可以把一个一毫秒为单位的时间间隔作为参数来开始定时器,这个函数返回一个唯一的整数定时器的标识符。这个定时器开始就会在每一个时间间隔"触发",直到明确的使用这个定时器的标识符来调用QObject::killTimer()结束。

    当定时器触发时,应用程序会发送一个QTimerEvent。在事件循环中,处理器按照事件队列的顺序来处理定时器事件。当处理器正忙于其它事件处理时,定时器就不能立即处理。

    QObject类还提供定时期的功能。与定时器相关的成员函数有:startTimer()、timeEvent()、killTimer()。QObject基类中的startTimer()和timerEvent()原型及说明如下:

intQObject::startTimer(int interval);

    开始一个定时器并返回定时器ID,如果不能开始一个定时器,将返回0。定时器开始后,每隔interval毫秒间隔将触发一次超时事件,直到killTimer()被调用来删除定时器。如果interval为0,那么定时器事件每次发生时没有窗口系统事件处理。

virtual voidQObject::timerEvent(QTimerEvent *event);

    虚函数timerEvent()被重载来实现用户的超时事件处理函数。如果有多个定时器在运行,QTimerEvent::timerId()被用来查找指定定时器,对其进行操作。

    当定时器事件发生时,虚函数timerEvent()随着QTimerEvent事件参数类一起被调用,重载这个函数可以获得定时器事件。

    定时器的用法如下:

//头文件

class QNewObject : publicQObject

{

    Q_OBJECT

public:

    QNewObject( QObject * parent = 0 );

    virtual ~QNewObject();

protected:

    void timerEvent( QTimerEvent *event );

    int m_nTimerId;

};

//源文件

QNewObject::QNewObject(QObject * parent )

    :QNewObject( parent )

{

    m_nTimerId = startTimer(1000);

}

QNewObject::~QNewObject()

{

    if ( m_nTimerId != 0 )

        killTimer(m_nTimerId);

}

voidQNewObject::timerEvent( QTimerEvent *event )

{

    qDebug( "timer event, id %d",event->timerId() );

}

2.定时器类QTimer

 定时器类QTimer提供当定时器触发的时候发射一个信号的定时器,他提供只触发一次的超时事件,通常的使用方法如下:

//创建定时器

QTimer *testTimer = newQTimer(this);

//将定时器超时信号与槽(功能函数)联系起来

connect( testTimer,SIGNAL(timeout()), this, SLOT(testFunction()) );

//开始运行定时器,定时时间间隔为1000ms

testTimer->start(1000);

...

//停止运行定时器

if (testTimer->isActive() )

    testTimer->stop();

  QTimer还提供了一个简单的只有一次定时的函数singleShot()。 一个定时器在100ms后触发处理函数animateTimeout()并且只触发一次。代码如下:

QTimer::singleShot( 100,this, SLOT(animateTimeout()) );

QTimer类提供了定时器信号和单触发定时器。

它在内部使用定时器事件来提供更通用的定时器。QTimer很容易使用:创建一个QTimer,使用start()来开始并且把它的timeout()连接到适当的槽。当这段时间过去了,它将会发射timeout()信号。

注意当QTimer的父对象被销毁时,它也会被自动销毁。

实例:

        QTimer *timer = new QTimer( myObject );

        connect( timer, SIGNAL(timeout()),myObject, SLOT(timerDone()) );

        timer->start( 2000, TRUE ); // 2秒单触发定时器

你也可以使用静态的singleShot()函数来创建单触发定时器。

作为一个特殊情况,一旦窗口系统事件队列中的所有事件都已经被处理完,一个定时为0的QTimer就会到时间了。

这也可以用来当提供迅速的用户界面时来做比较繁重的工作。

        QTimer *t = new QTimer( myObject );

        connect( t, SIGNAL(timeout()), SLOT(processOneThing()));

        t->start( 0, FALSE );

myObject->processOneThing()将会被重复调用并且应该很快返回(通常在处理一个数据项之后),这样Qt可以把事件传送给窗口部件并且一旦它完成这个工作就停止这个定时器。这是在图形用户界面应用程序中实现繁重的工作的一个典型方法,现在多线程可以在越来越多的平台上使用,并且我们希望无效事件最终被线程替代。

注意QTimer的精确度依赖于底下的操作系统和硬件。绝大多数平台支持20毫秒的精确度,一些平台可以提供更高的。如果Qt不能传送定时器触发所要求的数量,它将会默默地抛弃一些。

另一个使用QTimer的方法是为你的对象调用QObject::startTimer()和在你的类中(当然必须继承QObject)重新实现QObject::timerEvent()事件处理器。缺点是timerEvent()不支持像单触发定时器或信号那样的高级水平。

一些操作系统限制可能用到的定时器的数量,Qt会尽力在限制范围内工作。

### QT 定时器使用方法 #### 基础版实现 通过 `QTimer` 类创建并连接信号槽来实现定时功能。以下是具体代码示例: ```cpp #include <QCoreApplication> #include <QTimer> #include <QDebug> void timerCallback() { qDebug() << "Timer triggered!"; } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QTimer timer; QObject::connect(&timer, &QTimer::timeout, timerCallback); timer.start(1000); // 设置间隔时间为 1 秒 return app.exec(); } ``` 此代码展示了如何利用 `QTimer` 的 `timeout()` 信号触发回调函数[^1]。 --- #### Lambda 版本实现 借助 C++11 中的 Lambda 表达式简化代码结构,无需单独定义全局函数或成员函数作为回调处理逻辑: ```cpp #include <QCoreApplication> #include <QTimer> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QTimer timer; QObject::connect(&timer, &QTimer::timeout, [](){ qDebug() << "Lambda Timer Triggered!"; }); timer.start(2000); // 每隔 2 秒触发一次 return app.exec(); } ``` 这种方式更加简洁明了,并且减少了额外命名的需求[^2]。 --- #### 一次性版本实现 如果只需要执行单次操作,则可以通过设置 `QTimer` 的 `singleShot` 属性或者直接调用静态方法完成任务: ```cpp #include <QCoreApplication> #include <QTimer> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QTimer::singleShot(3000, [&]() { // 3秒后触发 qDebug() << "Single Shot Timer Triggered!"; QCoreApplication::quit(); // 结束程序运行 }); return app.exec(); } ``` 上述例子演示了一次性计时器的功能,在指定时间之后仅触发一次动作。 --- #### 重写定时器事件版实现 对于更复杂的场景,可能需要继承自 `QObject` 并覆盖其虚函数 `timerEvent(QTimerEvent *)` 来响应多个独立的定时器请求: ```cpp #include <QObject> #include <QTimerEvent> #include <QDebug> class MyObject : public QObject { protected: void timerEvent(QTimerEvent *event) override { if (event->timerId() == m_timerId1) { qDebug() << "First Timer Event"; } else if (event->timerId() == m_timerId2) { qDebug() << "Second Timer Event"; } } public: explicit MyObject(QObject *parent = nullptr): QObject(parent), m_timerId1(-1), m_timerId2(-1){} void startTimers() { m_timerId1 = startTimer(1000); // 启动第一个每秒触发的计时器 m_timerId2 = startTimer(2000); // 启动第二个每隔两秒触发的计时器 } private: int m_timerId1; // 记录第一个计时器ID int m_timerId2; // 记录第二个计时器ID }; int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); MyObject myObj; myObj.startTimers(); return app.exec(); } ``` 这里实现了多路定时机制,适合于复杂业务需求下的灵活控制[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值