QObject :: setParent:无法设置父级,新父级位于不同的线程中

时间:2016-03-08 13:28:30

标签: c++ multithreading qt qthread qtwebkit

问候语

我有以下课程。

class MyClass : public QObject
{
    Q_OBJECT

public:
    Q_INVOKABLE QVariant status();

public:
    MyClass(ClassX * classX);

public slots:
    void slotA();
    void slotB();

signals:
    void signalA();
    void signalB();

private:
    void init();
    void doSomething();

private:
    ClassX * classX;
    ClassA classA;
    ClassB classB;
};

MyClass的构造函数中,我将classX设置为this.classX,将init()设置为connect classX部分MyClass发信号到someFunction()个广告位,反之亦然,classA我使用classBcontroller

在主线程中的MyClass类中,我创建了MyClass * myClass = new MyClass(classX); connect(&myClassThread, SIGNAL(started()), myClass, SLOT(init())); myClass->moveToThread(&myClassThread); myClassThread.start(); 对象并在不同的线程中运行它。

qDebugger

我在QObject::setParent: Cannot set parent, new parent is in a different thread 中看到以下警告。

classX

谁能告诉我为什么会收到警告?

先谢谢

PS 1:主线程中创建的javascript

PS 2:记住,一切正常,我没有任何问题,我只是想知道这个警告的原因以及如何解决它。

PS 3:我还在主线程中使用以下命令来公开webFrame->addToJavaScriptWindowObject("myClassObject", myClass); 中的对象。

MyClass

编辑1:QThread myClassThread是类成员。

编辑2:我相信缺乏信息,让你们感到困惑,我很抱歉。

MyClass::MyClass(ClassX * classX) { this.classX = classX; } 的构造函数是这样的:

var now = new Date();

// Copying the date is actually pointless, but hey...
var expireDate = new Date(+now);

// Add 3 days
expireDate.setDate(expireDate.getDate() + 3);

// Show date and month, note that the month is zero indexed so add 1
// when displaying it
document.write(expireDate.getDate() + '/' + (expireDate.getMonth() + 1));

2 个答案:

答案 0 :(得分:3)

我们要清楚。 您的代码无法正常工作。这就是框架告诉您的内容。

  

QObject :: setParent:无法设置父级,新父级是不同的   螺纹

这意味着某个对象(疑似myClass)的所有插槽和信号都不会在与预期相同的线程中执行。此处的问题围绕myClassclassX对象的父级

可能性I:myClass-> moveToThread(& myClassThread);失败

原因: myClass已设置父级。这是被禁止的。

这意味着init()将由线程对象myClassThread的线程触发。线程和事件方式,这几乎与你做的一样

MyClass * myClass = new MyClass(classX);
QMetaObject::invokeMethod(myClass, "init", Qt::QueuedConnection);

可能性II:init()违反了线程关联

原因: `classX``或一个神秘的相关对象已经设置了父级或者不能移动到另一个线程。想想小部件。

moveToThread成功,您在一个帖子中有MyClass,在另一个帖子中有classX。您在构建classX时提供了myClassmyClass现在正在操纵另一个线程中的对象,如果没有其他代码,我们就不能假设线程安全或正确的子父亲缘关系。仔细检查MyClass :: MyClass`和MyClass :: init。

发生了哪一个?

在控制器代码中中断调试器并查看线程ID。然后在init方法中打破调试器。

  • 如果是同一个帖子,我就是
  • 否则是案例II

答案 1 :(得分:1)

这在很多方面都是错误的:

QThread myClassThread;
MyClass * myClass = new MyClass(classX);
connect(&myClassThread, SIGNAL(started()), myClass, SLOT(init()));
myClass->moveToThread(&myClassThread);
myClassThread.start();
  1. 您正在堆栈上创建线程对象而不是堆上!这意味着当这段代码结束时,myClassThread对象将被销毁。
  2. myClass有父母。移动到线程的对象不能有任何父对象。只有三个对象可以移动到线程