マルチスレッドでうまくいかないことがたくさんあることは知っていますが、ここでそれが起こっているようです。
スレッドセーフであると思われるシグナルとスロットを使用しているにもかかわらず、シグナルとスロットを使用していないWeb上の他の人が取得しているのと同様のエラーが発生するため、少し困惑しています。
これが私の状況です:
- メインの UI スレッドから、新しいスレッドを作成し、オブジェクトをそこに移動します
- 2 番目のスレッドが開始され、オブジェクトがデータを処理します。
- 処理が完了すると、オブジェクトは
setScene
作成したシグナルを UI スレッドに送信し、スロットに到達します。 - スロットは次のことを行います。
QGraphicsScene *scene = new QGraphicsScene(sceneIncoming);
- 次に実行します: `ui->graphicsView.setScene(scene);
これは、別のスレッドで親から子を作成できないことを示しています。シグナルとスロットを使用しているにもかかわらず、2 番目のスレッドのシーン データでメイン スレッドの 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 run()
...processing
...processing
...processing
painter->fillPath(*path, Qt::blue);
scene->addPath(*path);
emit setScene(scene);
mainwindow.cpp setScene スロット
void MainWindow::setScene(QGraphicsScene *sceneIncoming)
{
QGraphicsScene *scene = new QGraphicsScene(sceneIncoming);
ui->graphicsView->setScene(scene);
ui->graphicsView->show();
}
上記のスニペットは、操作順に掲載されています。繰り返しになりますが、集中的で GUI をブロックする QPainterPath と QGraphicsScene を含む処理を引き渡し、処理が完了したらデータをメイン スレッドに戻し、メイン スレッドが graphicsView ウィジェットをシーン データで更新できるようにします。処理スレッドから。を新しいオブジェクトにコピーするsceneIncoming
と、新しいオブジェクトがメインスレッドで所有され、処理スレッドからのシーンのデータが保持されるようになると考えましたが、それほど簡単には機能しないようです。
おそらく の代わりにemit setScene(scene)
、scene.moveToThread(mainThread)?? が必要です。その場合、メイン スレッドへの参照をグラフィックス ワーカーに渡す必要があると思います。
EDIT 2: 解決済み 実際には、これらのコード行の両方が必要でした:
scene.moveToThread(this->mainThread);
emit setScene(scene);
また、メイン スレッド参照で渡されるオーバーロードされたコンストラクターも追加しました。
すべてがスムーズに機能するようになりました。これをより良く行う方法、またはこれがまだ間違っているかどうかについて、私はまだ提案を受け付けています。お知らせ下さい!