Qt物理场景多线程

Joe*_*oel 9 c++ user-interface qt multithreading physics

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

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

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

Lol*_*4t0 2

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

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

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

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

    • 正如您提到的,使用信号/槽机制。
    • 使用调用QueuedConnection
    • 发送自定义事件。

    BlockingQueuedConnection如果您想等待绘画完成,请不要忘记您有。

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

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

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

就目前而言,由于QGraphicsItem不是线程安全的,甚至读取也不是。我在 Qt 中开发多线程应用程序的经验告诉我,如果有可能发生不好的事情,它就会发生。