9

我有一个带有大约 1000 个 QGraphicsItems 的 QGraphicsScene,它们实际上是物理项目。他们前进的每一帧,检查碰撞,并解决这些碰撞,等等。我真的很想让物理多线程。

我的理解是 QGraphics 类不是线程安全的。意思是,它们只能从主线程调用。这是否迫使我使用信号/槽机制将每帧的最终项目属性(x、y、旋转)发送到主线程,然后使用主线程方法实际更新 QGraphicsItems?或者有没有更简单的方法来做到这一点?

以下只是一个假设:我可以使用 QtConcurrent 在我的 QGraphicsItems 列表上运行一个方法吗?如果我在我的 QGraphicsItem 绘制方法中使用 QMutex 并在我的物理方法中使用 QMutex(这将改变我的 QGraphicsItem 的属性),这是否可以保证在任何时候只有一个线程正在读取/写入每个 QGraphicsItem?

4

1 回答 1

2
  1. 如果我在我的 QGraphicsItem 绘制方法中使用 QMutex 并在我的物理方法中使用 QMutex(这将改变我的 QGraphicsItem 的属性),这是否可以保证在任何时候只有一个线程正在读取/写入每个 QGraphicsItem?

    不,它不会。QGraphicsItem绘图时大量使用,不仅paint调用方法。例如,看这里。即使它可以工作,这将是一个丑陋的解决方案,因为显然,QGraphicsItem它不仅可以用于绘画。

  2. 这是否迫使我使用信号/槽机制将每帧的最终项目属性(x、y、旋转)发送到主线程,然后使用主线程方法实际更新 QGraphicsItems?或者有没有更简单的方法来做到这一点?

    是的,您必须将项目更改过程移至主线程。你实际上有一些选择:

    • 如您所述,使用信号/插槽机制。
    • 使用调用QueuedConnection
    • 发送自定义事件。

    别忘了,你有BlockingQueuedConnection,如果你想等待绘画完成。

    此外,您可以将所有这些东西与QtConcurent.

其实,管理起来并没有那么难。它比手动确保线程安全更安全、更容易。

更大的问题是,即使尝试在工作线程中读取项目(const例如,仅使用成员),您也可能会失败。

就目前而言,因为QGraphicsItem不是线程安全的,即使阅读也不是. 我在 Qt 中开发多线程应用程序的经验告诉我,如果可能发生不好的事情,它就会发生。

于 2012-04-09T20:23:12.487 回答