Qt里出现 Cannot create children for a parent that is in a different thread

源码操作如下
#include "mythread.h"
#include 
#include 

MyThread::MyThread()
    : QThread()
{

}

MyThread::~MyThread()
{

}

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

void MyThread::slot_time()
{
    QTime mytime = QTime::currentTime() ;
    emit sendtime(mytime.toString()) ;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

当进行connect(m_timer , SIGNAL(timeout()) , this , SLOT(slot_time())) ;

时会报错:Cannot create children for a parent that is in a different thread。

其根本原因是this是MyThread的对象,而MyThread是在主线程中创建的。m_timer 是在子线程中,this在主线程中。信号和槽没有在同一个线程,因此报错

解决办法:

connect(m_timer , SIGNAL(timeout()) , this , SLOT(slot_time()),Qt::DirectConnection);

绑定的时候添加Qt::DirectConnection。


Qt::DirectConnection(直连方式)

当信号发出后,相应的槽函数将立即被调用。emit语句后的代码将在所有槽函数执行完毕后被执行。(信号与槽函数关系类似于函数调用,同步执行)

Qt::QueuedConnection(排队方式)

当信号发出后,排队到信号队列中,需等到接收对象所属线程的事件循环取得控制权时才取得该信号,调用相应的槽函数。emit语句后的代码将在发出信号后立即被执行,无需等待槽函数执行完毕。

(此时信号被塞到信号队列里了,信号与槽函数关系类似于消息通信,异步执行)

Qt::AutoConnection(自动方式)

Qt的默认连接方式,如果信号的发出和接收这个信号的对象同属一个线程,那个工作方式与直连方式相同;否则工作方式与排队方式相同



总结:Qt里的信号和槽是其特色,使用的时候特别注意发送信号的线程和接收线程之间的关系。当发送消息的线程和接收消息的线程是同一个线程,无需注意反应速度。

当这两个线程不是同一个线程时,一定要在connect的第五个参数中添加Qt::DirectConnection。此bug会在socket等信号绑定的时候遇到

你可能感兴趣的:(Qt里出现 Cannot create children for a parent that is in a different thread)