从Qt中的多个线程 [英] Drawing from multiple threads in Qt

查看:1395
本文介绍了从Qt中的多个线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Qt中编写一个程序,它运行10个工作线程,计算空间中对象的轨迹。他们还必须绘制对象的路径。我有一个Body类派生QGraphicsEllipseItem,它有一个QPainterPath。 模拟类获取世界上的障碍物的列表,并且身体模拟并运行,直到身体与某物碰撞。模拟在单独的线程中运行(使用moveToThread完成,而不是通过子类化QThread)。当身体碰撞时,模拟发出一个信号,说它完成了。当所有线程都完成后,我想绘制路径(我通过调用Body中的一个方法,在它的 draw 方法中启用路径绘制)。



不幸的是我收到ASSERT错误:

  ASSERT:!unindexedItems.contains(item) graphicsview\ qgraphicsscenebsptreeindex.cpp,第364行

它们似乎是随机的。我尝试了不同的连接类型,没有结果。

我在循环中启动线程。

我使用Qt 5.0


一般来说,使用Qt,你不能在GUI线程外执行任何GUI操作(即执行QApplication :: exec()的线程)



因此,如果你有多个线程处理QGraphicsItems(尤其是QGraphicsItems,目前是一个QGraphicsScene的一部分),这可能是原因你的断言失败。也就是说,当Qt GUI线程执行其窗口刷新时,它正在从各种QGraphicsItem对象读取数据作为其计算的一部分,并且它期望QGraphicsItem在刷新操作的持续时间保持不变。如果在执行刷新例程时改变(通过另一线程)QGraphicsItem,则由主线程进行的计算可能变得错误/损坏,并且偶尔导致断言失败(和/或其他不希望的行为)。



如果你真的需要使用多个线程,你可能需要做的是让线程做他们自己的私有数据结构,Qt GUI线程没有进入。然后当线程计算出它们的结果时,它们应该将结果发送回Qt GUI线程(通过队列连接或QApplication :: postEvent())。 GUI线程然后可以查看结果并使用它们来更新QGraphicsItem等;这将是安全的,因为此更新不会发生在窗口更新的中间。



如果这听起来像太多的工作,那么你可以考虑只是做一切在GUI线程;它会更容易和更简单的一切工作可靠的这种方式。


I'm writing a program in Qt, which runs 10 worker threads which calculate the trajectory of an object in space. They also have to draw the path of the object. I have a "Body" class deriving QGraphicsEllipseItem and it has a QPainterPath in it. The "Simulation" class takes a list of obstacles in the world, and the body to simulate and runs until the body collides with something. Simulation runs in a separate thread ( done with moveToThread, not by subclassing QThread). When the body collides, the Simulation emits a signal saying that it finished. When all threads have finished I'd like to draw the paths (I do it by invoking a method in "Body" which enables path drawing in its draw method).

Unfortunately I get ASSERT errors :

ASSERT: "!unindexedItems.contains(item)" in file graphicsview\qgraphicsscenebsptreeindex.cpp, line 364

They happen seemingly randomly. I've tried different connection types, to no result.
I'm starting the threads in a loop.
I'm using Qt 5.0

解决方案

Generally speaking, with Qt you can't do any GUI operations outside of the GUI thread (i.e. the thread that is executing QApplication::exec(), which is typically the main() thread).

So if you have multiple threads manipulating QGraphicsItems (especially QGraphicsItems that are currently part of a QGraphicsScene), that is likely the cause of your assertion failures. That is, when the Qt GUI thread is doing its window refresh, it is reading data from the various QGraphicsItem objects as part of its calculations, and it expects the QGraphicsItems to remain constant for the duration of the refresh operation. If a QGraphicsItem is changed (by another thread) while the refresh routine is executing, then the calculations made by the main thread can become wrong/corrupted, and that occasionally causes an assertion failure (and/or other unwanted behaviors).

If you really need to use multiple threads, what you'll probably need to do is have the threads do all their calculations on their own private data structures that the Qt GUI thread has no access to. Then when the threads have computed their results, they should send the results back to the Qt GUI thread (via queued connection or QApplication::postEvent()). The GUI thread can then look at the results and use them to update the QGraphicsItems, etc; this will be "safe" because this update can't happen in the middle of a window update.

If that sounds like too much work, then you might consider just doing everything in the GUI thread; it will be much easier and simpler to make everything work reliably that way.

这篇关于从Qt中的多个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆