我需要从帖子中使用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
答案 0 :(得分:1)
问题在于您的连接线。您正在将插槽连接到没有意义的信号。您应该将信号从线程连接到插槽:
connect(thread, SIGNAL(doSceneUpdate(QGraphicsScene*)),this, SLOT(updateScene(QGraphicsScene*)));
答案 1 :(得分:1)
in
void MyThread::run()
{
QGraphicsScene *scene = new QGraphicsScene(...);
...
}
您是否将this
传递给QGraphicsScene()
的构造函数?
这可能是导致错误的原因之一,因为现在您将MyThread
的孩子传递给Main
尝试在堆栈上创建QGraphicsScene对象,或者将父对象创建为NULL(new QGraphicsScene(0)
)
答案 2 :(得分:1)
我做错了什么,我该怎么做?
我认为规范的答案是here - 简而言之,文章指出你不应该将QThread子类化,而是应该使用"裸" (即未子类化)QThread对象并将其started()信号连接到一个槽,然后在线程启动后将在该线程的上下文中运行。这样就可以自动处理对象线程所有权问题。
另请注意,除了主Qt线程之外的线程通常不允许直接创建或与QGraphicsScene等GUI对象交互,因为这样做会引入竞争条件,因为Qt'中的操作同时进行。的GUI事件循环。如果你想使用一个单独的线程,你需要远离你的GUI对象,而只是让它发出异步信号和/或将事件发送到主/ GUI线程以获得主/ GUI线程代表它进行GUI对象更新。