您可能会这么做:
子类化QThread,在线程类中定义一个定时器,然后在run()方法中调用定时器的start()方法。
checkProcess::checkProcess()
{
}
checkProcess::~checkProcess()
{
}
void checkProcess::checkFun()
{
qDebug() << "myFirst";
}
void checkProcess::run()
{
myTimer = new QTimer();
connect(myTimer,SIGNAL(timeout()),this,SLOT(checkFun()));
myTimer->start(1000);
this->exec();
}
看似十分自然,没有什么不妥,然而,编译器将通知下面的错误信息:
QObject::startTimer: Timers cannot be started from another thread
——定时器不能被其它线程start。
我们来分析一下:
刚开始只有主线程一个,checkProcess的实例是在主线程中创建的,定时器在checkProcess的构造函数中,所以也是在主线程中创建的。
当调用checkProcess的start()方法时,这时有两个线程。定时器的start()方法是在另一个线程中,也就是checkProcess中调用的。
创建和调用并不是在同一线程中,所以出现了错误。
Qt使用计时器的线程关系(thread affinity)来决定由哪个线程发出timeout()信号。正因如此,你必须在它所处的线程中start或stop该定时器,在其它线程中启动定时器是不可能的。
正确用法:
myTimer = new QTimer();
connect(myTimer,&QTimer::timeout,this,&checkProcess::checkFun);
myTimer->start(1000);
this->exec();
有些地方需要注意:
1.不能像下面这样给定时器指定父对象
myTimer = new QTimer(this);
会出现
QObject: Cannot create children
for
a parent that is in a different
thread
.
(Parent is TestThread(0x709d88), parent's
thread
is QThread(0x6e8be8), current
thread
is TestThread(0x709d88)
因为checkProcess对象是在主线程中创建的,它的QObject子对象也必须在主线程中创建。所以不能指定父对象为
checkProcess。
2.必须要加上事件循环exec()
否则线程会立即结束,并发出finished()信号。
综上,子类化线程类的方法可行,但是不太友好。
现在通过moveToThread()方法可以在里面放肆的使用定时器了,推荐使用。