我有一个包含大约 1000 个 QGraphicsItems 的 QGraphicsScene,它们实际上是物理项。他们前进的每一帧,检查碰撞,并解决这些碰撞,等等。我真的很想让物理多线程化。
据我了解,QGraphics 类不是线程安全的。意思是,它们只能从主线程调用。这是否迫使我使用信号/槽机制将每帧的最终项目属性(x、y、旋转)发送到主线程,然后使用主线程方法实际更新 QGraphicsItems?或者有更简单的方法吗?
以下只是一个假设:我可以使用 QtConcurrent 来运行我的 QGraphicsItems 列表上的方法吗?如果我在我的 QGraphicsItem 绘制方法中使用 QMutex 并在我的物理方法中使用 QMutex(这将更改我的 QGraphicsItem 的属性),这是否可以保证在任何时刻只有一个线程正在读取/写入每个 QGraphicsItem?
最佳答案
-
If I use a QMutex in my QGraphicsItem paint method and a QMutex in my physics method (that will change properties of my QGraphicsItem), would this guarantee that only one thread is reading/writing each QGraphicsItem at any one moment in time?
不,不会。
QGraphicsItem
在绘图时大量使用,不仅调用了paint
方法。看,例如,here .即使可行,这也是一个丑陋的解决方案,因为显然QGraphicsItem
不仅可以用于绘画。 -
Does this force me to send the final item properties (x, y, rotation) each frame to the main thread using a signal/slot mechanism, and then use a main thread method to actually update the QGraphicsItems? Or is there an easier way to do this?
是的,您必须将项目更改过程移至主线程。你实际上有一些选择:
- 如您所述,使用信号/槽机制。
- 使用meta-calls使用
QueuedConnection
- 发送自定义事件。
别忘了,你有
BlockingQueuedConnection
, 如果你想等待绘画完成。此外,您可以将所有这些东西与
QtConcurent
一起使用。
其实管理起来并没有那么难。它比手动确保线程安全更安全、更容易。
更大的问题是,即使在工作线程中尝试读取 项(例如,仅使用const
成员),您也可能会失败。
就目前而言,QGraphicsItem
不是线程安全的,即使读取也不是。我在 Qt 中开发多线程应用程序的经验告诉我,如果可能发生不好的事情,它就会发生。
关于c++ - Qt物理场景多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10038224/