Обновить сцену из темы?

Мне нужно обновить QGraphicsView с QGraphicsScene из нити.

Ниже приведен пример псевдоишного кода того, что я делаю, что вызывает у меня проблемы (ошибки времени выполнения).

Что я делаю не так, и как я должен это делать?

Основное приложение:

void Main::startThread()
{
  view = new QGraphicsView(...);
  thread = new MyThread(...);
  connect(thread, SIGNAL(doSceneUpdate(QGraphicsScene*)), this, SLOT(updateScene(QGraphicsScene*)));
  thread->start();
}

void Main::updateScene(QGraphicsScene *scene)
{
  view->SetScene(scene);
  view->show();
  repaint();
}

Нить:

void MyThread::run()
{
  QGraphicsScene *scene = new QGraphicsScene(...);
  while(1)
  {
    //draw stuff on the scene
    emit doSceneUpdate(scene);
    //some delay
  }

Заранее спасибо!!!

[править] Ошибка:

ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread
3e53c0. Receiver '' (of type 'QGraphicsScene') was created in thread 1476cd18", file c:\Qt\qt-everywhere-opensource-src-4.8.2\src\corelib\kernel\qcoreapplication.cpp, line 501

3 ответа

Решение

Что я делаю не так, и как я должен это делать?

Я думаю, что канонический ответ здесь - в двух словах, в статье говорится, что вам не следует создавать подклассы QThread, а лучше использовать "голый" (то есть не подклассифицированный) объект QThread и подключить его сигнал start () к слот, который затем будет запущен в контексте этого потока, после запуска потока. Таким образом, проблемы с владением объектными потоками решаются автоматически.

Также обратите внимание, что потокам, отличным от основного потока Qt, как правило, не разрешается создавать или взаимодействовать напрямую с объектами GUI, такими как QGraphicsScene, поскольку это может привести к условиям гонки из-за операций, происходящих одновременно за кулисами в цикле событий QI GUI. Если вы хотите использовать отдельный поток, вам нужно держать его подальше от ваших объектов GUI, и вместо этого просто заставить его испускать асинхронные сигналы и / или отправлять события в основной поток /GUI, чтобы заставить основной поток /GUI делать GUI-объект обновляется от его имени.

Проблема в вашей соединительной линии. Вы подключаете слот к сигналу, который не имеет смысла. Вы должны подключить сигнал от потока к слоту:

connect(thread, SIGNAL(doSceneUpdate(QGraphicsScene*)),this, SLOT(updateScene(QGraphicsScene*)));

В

void MyThread::run()
{
  QGraphicsScene *scene = new QGraphicsScene(...);
  ...

}

ты проходишь this конструктору QGraphicsScene()?

Это может быть одной из причин ошибки, так как теперь вы передаете ребенка MyThread в Main

Попробуйте создать объект QGraphicsScene в стеке или с родительским значением NULL (new QGraphicsScene(0))

Другие вопросы по тегам