Multithreading 在使用QThread设置主ui线程之外的图形时遇到问题

Multithreading 在使用QThread设置主ui线程之外的图形时遇到问题,multithreading,qt,user-interface,Multithreading,Qt,User Interface,我知道多线程有很多地方可能会出错,这似乎发生在我身上 虽然我有点困惑,因为我使用的信号和插槽应该是线程安全的,但仍然会出现类似于我在网上看到的其他人没有使用信号和插槽的错误 我的情况如下: 从我的主ui线程,我创建一个新线程并将一个对象移动到它 第二个线程启动,对象处理一些数据 处理完成后,对象将向ui线程发出一个我创建的setScene信号,并降落在插槽中 插槽执行:qgraphicscene*scene=newqgraphicscene(sceneIncoming) 然后它会:`ui->gr

我知道多线程有很多地方可能会出错,这似乎发生在我身上

虽然我有点困惑,因为我使用的信号和插槽应该是线程安全的,但仍然会出现类似于我在网上看到的其他人没有使用信号和插槽的错误

我的情况如下:

  • 从我的主ui线程,我创建一个新线程并将一个对象移动到它
  • 第二个线程启动,对象处理一些数据
  • 处理完成后,对象将向ui线程发出一个我创建的
    setScene
    信号,并降落在插槽中
  • 插槽执行:
    qgraphicscene*scene=newqgraphicscene(sceneIncoming)
  • 然后它会:`ui->graphicsView.setScene(场景) 这仍然告诉我不能从另一个线程中的父线程创建子线程。我不知道如何用第二个线程的场景数据更新主线程中的graphicsView,尽管我使用了信号和插槽

    编辑:添加代码段

    mainwindow.cpp构造函数

    ...
    ...
    QThread *thread = new QThread();
    GraphicsWorker *worker = new GraphicsWorker();
    this->worker = worker;
    
    
    this->worker->moveToThread(thread);
    thread->start();
    
    QObject::connect(this, &MainWindow::beginGraphicsWorker, this->worker, &GraphicsWorker::run);
    QObject::connect(worker, &GraphicsWorker::setScene, this, &MainWindow::setScene);
    ...
    ....
    
    GraphicsWorker.cpp运行()

    main window.cpp setScene插槽

    void MainWindow::setScene(QGraphicsScene *sceneIncoming)
    {
        QGraphicsScene *scene = new QGraphicsScene(sceneIncoming);
        ui->graphicsView->setScene(scene);
        ui->graphicsView->show();
    }
    
    以上代码段按操作顺序发布。因此,我想再次移交一些涉及QPainterPath和Qgraphicscene的处理,这些处理非常密集并阻塞GUI,然后在处理完成后将数据传递回主线程,并让主线程使用处理线程中的场景数据更新graphicsView小部件。我认为将
    场景incoming
    复制到一个新对象中会让新对象在主线程中拥有,但从处理线程获得场景数据,但它似乎不那么容易工作

    也许我需要的不是
    emit setScene(scene)
    ,而是scene.moveToThread(mainThread)?
    在这种情况下,我想我需要将对主线程的引用传递给图形工作者

    编辑2:已解决 实际上,我需要这两行代码:

    scene.moveToThread(this->mainThread);
    emit setScene(scene);
    
    我还添加了一个重载构造函数来传递主线程引用


    现在一切都很顺利。我仍然愿意听取关于如何更好地做到这一点的建议,或者这是否仍然是错误的方法。让我知道

    关于您请求更好的方法,我建议您将QPaint对象保留在主线程中。然后,让第二个线程处理数据并向主线程发送信号,以传递它已处理的数据,然后将数据添加到主线程上的QPaint对象中。

    尝试此操作

    scene->moveToThread(QApplication::instance()->thread());
    

    这里有很多可能的问题,但是如果您添加一个代码示例,而不是一个描述,我们将能够更快地帮助您。还要注意的是,除了主线程外,您不能在任何其他线程上执行任何与UI相关的操作。我不是舒尔,但
    QObject::connect()
    需要
    SIGNAL()
    SLOT()
    macro@Zaiborg什么?我的信号/插槽连接一点问题都没有。该部分是正确的。请使用更多信息进行编辑。“仅编码”和“尝试此”答案是错误的,因为它们不包含可搜索的内容,并且没有解释为什么有人应该“尝试此”。
    scene->moveToThread(QApplication::instance()->thread());