我们经常需要将一些耗时的工作在子线程中进行,同时在子线程中又需要用到循环事件时,一种方法使用While()/sleep()进行线程控制。另一种创建一个QTimer对象,使用信号与槽机制将信号timeout()与相应的槽函数相连,然后调用start()函数。接下来,每隔一段时间,定时器便会发出一次timeout()信号,此种方法使用更为灵活,方便,注意:启用计时器时需启动事件循环exec()。
下面我使用一个DEMO进行展示:
自定义一个Button,当点击按钮时,线程启动,输出当前运行的线程ID:
void Widget::on_pushButton_clicked()
{
qDebug()<<"主线程ID:"<start();
}
MyThread::MyThread(QObject *parent):QThread (parent)
{
timer = new QTimer();
}
错误原因:线程类的初始化在主线程中,因此线程构造函数也在主线程中运行
void MyThread::run()
{
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(timerOut()));
timer->start(1000);
exec();
}
错误原因同上
void MyThread::run()
{
timer = new QTimer();
connect(timer,SIGNAL(timeout()),this,SLOT(timerOut()));
startTimer();
exec();
}
void MyThread::startTimer(){
qDebug()<<"当前线程ID:"<start(1000);
}
void MyThread::timerOut()
{
qDebug()<<"当前线程ID:"<
输出线程:
错误原因:run()函数线程为子线程,因此run函数中运行startTimer()为run所处线程,但因为startTimer()初始化时为主线程,因此timer->start()也随之在主线程中开始,计时器槽函数也在主线程中运行
void MyThread::run()
{
timer = new QTimer();
connect(timer,SIGNAL(timeout()),this,SLOT(timerOut()));
timer->start(1000);
exec();
}
void MyThread::timerOut()
{
qDebug()<<"当前线程ID:"<
打印线程:
如果我不想在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:"<start(1000);
}
void MyThread::timerOut()
{
qDebug()<<"当前线程ID:"<
打印线程: