Я знаю, что есть много вещей, которые могут пойти не так с многопоточностью, и, похоже, это происходит со мной здесь.
Я немного сбит с толку, потому что я использую сигналы и слоты, которые предположительно являются потокобезопасными, но все же получаю ошибки, подобные тем, которые я вижу у других людей в Интернете, которые не используют сигналы и слоты.
Вот моя ситуация:
- Из моего основного потока пользовательского интерфейса я создаю новый поток и перемещаю в него объект
- Запускается второй поток, и объект обрабатывает некоторые данные.
- Когда обработка завершена, объект отправляет сигнал
setScene
, который я создал, обратно в поток пользовательского интерфейса, попадая в слот. - Слот делает:
QGraphicsScene *scene = new QGraphicsScene(sceneIncoming);
- Затем он делает: `ui->graphicsView.setScene(scene);
Это по-прежнему говорит мне, что я не могу создать дочерний элемент из родителя в другом потоке. Я не понимаю, как обновить 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()
...processing
...processing
...processing
painter->fillPath(*path, Qt::blue);
scene->addPath(*path);
emit setScene(scene);
Слот setScene mainwindow.cpp
void MainWindow::setScene(QGraphicsScene *sceneIncoming)
{
QGraphicsScene *scene = new QGraphicsScene(sceneIncoming);
ui->graphicsView->setScene(scene);
ui->graphicsView->show();
}
Приведенные выше фрагменты размещены в порядке работы. Итак, еще раз, я хочу передать некоторую обработку, включающую QPainterPath и QGraphicsScene, которая интенсивна и блокирует графический интерфейс, а затем передать данные обратно в основной поток после завершения обработки и позволить основному потоку обновить виджет graphicsView данными сцены. из потока обработки. Я полагал, что копирование sceneIncoming
в новый объект позволит новому объекту принадлежать основному потоку, но при этом иметь данные сцены из потока обработки, но, похоже, это не так просто работает.
Возможно, вместо emit setScene(scene)
мне нужна сцена.moveToThread(mainThread)?? В таком случае, я думаю, мне нужно передать ссылку на основной поток в обработчик графики.
РЕДАКТИРОВАНИЕ 2: РЕШЕНО На самом деле мне нужны были обе эти строки кода:
scene.moveToThread(this->mainThread);
emit setScene(scene);
Я также добавил перегруженный конструктор, передающий ссылку на основной поток.
Теперь все работает гладко. Я все еще открыт для предложений о том, как лучше сделать это или если это все еще неправильный путь. Дайте мне знать!
QObject::connect()
захочетchar*
из макросаSIGNAL()
иSLOT()
- person Zaiborg   schedule 08.07.2013