QObject::startTimer: Timers cannot be started from another thread

您可能会这么做:

子类化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()方法可以在里面放肆的使用定时器了,推荐使用。

你可能感兴趣的:(Qt)