【问题标题】:Qt physics scene multithreadingQt 物理场景多线程
【发布时间】:2012-04-19 18:15:50
【问题描述】:

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

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

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

【问题讨论】:

  • 我读过一些关于在连接信号/插槽时使用 QueuedConnection 的内容。我没有尝试过,甚至没有研究过细节,但我认为值得进一步研究。有没有其他人有这方面的经验?
  • 我使用了Box2D的Delphi端口,非常满意。为什么不试一试呢?如果您有兴趣,请前往page
  • Box2D 看起来很有趣,但我没有看到它是多线程的。
  • QtConcurrent 看起来很有趣。我已经有了我的 QGraphicsItems 的列表,如果我可以使用 QtConcurrent 在每个项目上运行一个函数,那么物理学会很容易。我的理解是,如果 2 个线程试图同时访问同一个内存,这可能会导致问题。例如,QGraphicsItem 在被 QtConcurrent 修改时被绘制。那么,有没有办法在 QtConcurrent 运行时“暂停”绘制场景?

标签: c++ multithreading qt user-interface physics


【解决方案1】:
  1. 如果我在我的 QGraphicsItem 绘制方法中使用 QMutex 并在我的 物理方法(这将改变我的 QGraphicsItem 的属性), 这会保证每个线程只有一个线程在读/写吗 QGraphicsItem 在任意时刻?

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

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

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

    • 如您所述,使用信号/槽机制。
    • 使用meta-callsQueuedConnection
    • 发送自定义事件。

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

    此外,您可以将所有这些东西与QtConcurent 一起使用。

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

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

至于QGraphicsItem 不是线程安全的,即使阅读也不是。我在 Qt 中开发多线程应用程序的经验告诉我,如果可能发生不好的事情,它将会发生

【讨论】:

  • 感谢您的回答。一个问题:如果我创建了一个继承 QGraphicsItem 的类,并添加了一些自定义属性(颜色、速度等),我可以从另一个线程修改这些属性吗?只要我确保在任何时候只有一个线程在读取/写入每个属性,我就可以了吗?
  • @Joel,如果他们不使用其他继承的成员,你可以。但在这种情况下,我最好使用聚合而不是继承(your 包括 QGraphicsItem 作为成员),因为在这种情况下,这些属性服务于一些单独的目标,而不是实际上 extendQGraphicsItem。我个人认为,它会增加清晰度。
  • 我不确定在我的情况下聚合将如何工作。我们很清楚,我希望我的班级重新实现paint方法。如果不继承 QGraphicsItem,我不确定如何做到这一点。
  • @Joel,您可以从QGraphicsItem 继承创建一些结构,用于线程。
猜你喜欢
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多