Qt多线程中使用QTimer(常见问题汇总)

我们经常需要将一些耗时的工作在子线程中进行,同时在子线程中又需要用到循环事件时,一种方法使用While()/sleep()进行线程控制。另一种创建一个QTimer对象,使用信号与槽机制将信号timeout()与相应的槽函数相连,然后调用start()函数。接下来,每隔一段时间,定时器便会发出一次timeout()信号,此种方法使用更为灵活,方便,注意:启用计时器时需启动事件循环exec()

下面我使用一个DEMO进行展示:

自定义一个Button,当点击按钮时,线程启动,输出当前运行的线程ID:

void Widget::on_pushButton_clicked()
{
    qDebug()<<"主线程ID:"<<QThread::currentThreadId();
    myThread->start();
}

 

常见错误1:在线程构造函数中初始化QTimer:

MyThread::MyThread(QObject *parent):QThread (parent)
{
    timer = new QTimer();
}

错误原因:线程类的初始化在主线程中,因此线程构造函数也在主线程中运行

常见错误2:在线程中为QTimer指定父类:

void MyThread::run()
{
    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(timerOut()));
    timer->start(1000);
    exec();
}

错误原因同上

常见错误3:计时器虽在线程中初始化,但在子线程非run()函数中开始start()。

void MyThread::run()
{
    timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(timerOut()));
    startTimer();
    exec();
}
 
void MyThread::startTimer(){
    qDebug()<<"当前线程ID:"<<QThread::currentThreadId();
    timer->start(1000);
}
 
void MyThread::timerOut()
{
    qDebug()<<"当前线程ID:"<<QThread::currentThreadId();
}

输出线程:

错误原因:run()函数线程为子线程,因此run函数中运行startTimer()为run所处线程,但因为startTimer()初始化时为主线程,因此timer->start()也随之在主线程中开始,计时器槽函数也在主线程中运行

正确用法1:

void MyThread::run()
{
    timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(timerOut()));
    timer->start(1000);
    exec();
}
 
void MyThread::timerOut()
{
    qDebug()<<"当前线程ID:"<<QThread::currentThreadId();
}

打印线程:

 

正确用法2:

如果我不想在run()函数中就开始计时器,而是在线程运行过程中根据实际情况开启(之前错误3的情况)时要怎么办呢?

解决办法为:信号与槽连接中使用Qt::DirectConnection

信号与槽连接默认方式为:Qt::AutoConnection,因此会根据函数所处的线程自动跳转,导致错误3中的情况

oid MyThread::run()
{
    timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(timerOut()),Qt::DirectConnection);
    startTimer();
    exec();
}
 
void MyThread::startTimer(){
    qDebug()<<"当前线程ID:"<<QThread::currentThreadId();
    timer->start(1000);
}
 
void MyThread::timerOut()
{
    qDebug()<<"当前线程ID:"<<QThread::currentThreadId();
}

 打印线程:

 

 

  • 23
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵喵叫的猴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值