Update Scene from Thread?

末鹿安然 提交于 2019-12-23 05:14:04

问题


I need to update a QGraphicsView with a QGraphicsScene from a thread.

Below is some pseudo'ish code example of what I am doing which is causing me issues (runtime errors).

What am I doing wrong, and how should I be doing it?

Main App:

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();
}

The Thread:

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

Thanks in advance!!!

[edit] The error is:

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

回答1:


What am I doing wrong, and how should I be doing it?

I think the canonical answer is here -- in a nutshell, the article states that you shouldn't be subclassing QThread, but rather you should use a "bare" (i.e. not-subclassed) QThread object and connect its started() signal to a slot that will then be run in the context of that thread, after the thread starts. That way the object-thread-ownership issues are handled automatically for you.

Note also that threads other than the main Qt thread are generally not allowed to create or interact directly with GUI objects like QGraphicsScene, since doing that would introduce race conditions due to the operations going on simultaneously behind the scenes in Qt's GUI event loop. If you want to use a separate thread, you'll need to keep it away from your GUI objects, and instead just have it emit asynchronous signals and/or send Events to the main/GUI thread to get the main/GUI thread to do the GUI-object updates on its behalf.




回答2:


The problem is with your connection line. You are connecting a slot to a signal which does not make sense. You should connect the signal from the thread to the slot :

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



回答3:


in

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

}

do you pass this to the constructor of QGraphicsScene()?

That could be one cause of error, since now you are passing a child of MyThread to Main

Try creating a QGraphicsScene object on the stack or with the parent as NULL ( new QGraphicsScene(0) )



来源:https://stackoverflow.com/questions/24743218/update-scene-from-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!