Обновить сцену из темы?
Мне нужно обновить 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)
)