起因
在做一个编译器词法分析的图形展示时用到了多线程,继承了QThread
并重写了run
方法。
基本上就是下面这个意思:
class Thread : public QThread {
void run() {
QObject *obj = new QObject(this);//这里出现了问题
}
};
运行时提示Cannot create children for a parent that is in a different thread
原因
经查阅,由于Qt要求一个QObject
的孩子必须与它们的双亲驻足在同一个线程中。这意味着:
1. 不能使用QObject::moveToThread()
作用于有双亲的对象;
2. 你千万不要在一个线程中创建对象的同时把QThread
对象自己作为它的双亲。
第二条也就是我上面的错误,因为run()
是在一个新的线程中运行的,而QThread
本身是在他自身的双亲线程中。也就是这样导致了QObject
是QThread
的孩子却不在同一个线程中。
关于事件循环
那现在让我们拓展上面的例子
class Thread : public QThread {
void run() {
QObject *obj = new QObject();
connect(obj,&QObject::somesignal,this,&Thread:someslots);
}
};
加了一个connect
函数,这样有时没有什么问题呢?会不会达成我们期待的效果呢?
在Qt4.4之前这是不行的。因为run
内没有开启事件循环。里面的任何信号事件无法得到处理,所以我们需要在run
里面调用QThread::exec()
。这样一个QThread
的局部事件循环就开启了。
然而在Qt4.4之后,QThread::run()
方法不再是一个纯虚函数,它调用了QThread::exec()。