QObject::set parent:无法设置父级,新父级在其他线程中

2024-10-06 12:38:44 发布

您现在位置:Python中文网/ 问答频道 /正文

问候语

我有一个跟班。

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()中,我使用classAclassB

在主线程中的controller类中,我创建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

有人能告诉我为什么我会收到那个警告吗?

提前感谢

PS 1:在主线程中创建的classX

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

PS 3:我还在主线程中使用以下命令来公开javascript中的对象。

webFrame->addToJavaScriptWindowObject("myClassObject", myClass);

编辑1:QThread myClassThread是类成员。

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

MyClass的构造函数如下:

MyClass::MyClass(ClassX * classX)
{
     this.classX = classX;
}

Tags: 警告initmyclassprivatepublicthis主线void
2条回答

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

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

我们说清楚。您的代码没有按预期工作。框架就是这样告诉您的。

QObject::setParent: Cannot set parent, new parent is in a different thread

这意味着某个对象(可疑的myClass)的所有插槽和信号将不会在预期的线程中执行。这里的问题是关于myClassclassX对象的父对象

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

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

这意味着init()将由线程对象myClassThread的线程触发。从线程和事件角度看,这几乎与

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

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

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

moveToThread成功,一个线程中有MyClass,另一个线程中有classX。在构造myClass时提供了classXmyClass现在正在处理另一个线程中的对象,如果没有进一步的代码,我们就无法假定线程安全或正确的子父关联。仔细检查MyClass::MyClass`和MyClass::init。

哪一个正在发生?

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

  • 如果是同一根线,第一种情况
  • 否则就是第二种情况

相关问题 更多 >