2012-04-06 77 views
9

我有一个QGraphicsScene约1000 QGraphicsItems,其实是物理项目。他们前进的每一帧,检查碰撞,并解决其中的冲突。我真的很想拥有物理多线程。Qt物理场景多线程

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

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

+0

我读过一些关于在连接信号/插槽时使用QueuedConnection的内容。我没有尝试过,甚至没有看过细节,但我认为这值得进一步调查。有没有其他人有这方面的经验? – aldo 2012-04-06 05:33:45

+0

我使用了Box2D的Delphi端口,对此我非常满意。为什么不试一试呢?如果您有兴趣,请前往此[网页](http://labs.qt.nokia.com/2010/02/26/qt-box2d-is-easy/)。 – menjaraz 2012-04-06 13:30:43

+0

Box2D看起来很有趣,但我没有看到它是多线程的。 – Joel 2012-04-06 14:44:05

回答

2
  1. 如果我用我的QGraphicsItem paint方法QMutex和我 物理方法QMutex(这将改变我的QGraphicsItem的性质), 将这项保证只有一个线程读取/写入每个QGraphicsItem在任何时刻?

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

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

    是的,您必须将项目更改过程移动到主线程。您实际上有一些替代方案:

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

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

    此外,您可以使用所有这些东西QtConcurent

其实,也不是那么难以管理。比手动确保线程安全性更安全,更简单。

更大的问题是,你很可能会失败,即使试图阅读项工作线程(仅使用const承包商,客人,例如)。

迄今为止,由于QGraphicsItem不是线程安全的,所以即使读数为而不是。而我在Qt中多线程应用开发的经验告诉我,如果有什么不好的事情发生,会发生

+0

感谢您的回答。一个问题:如果我创建了一个继承QGraphicsItem的类,并添加了一些自定义属性(颜色,速度等),我可以从另一个线程修改它们吗?只要我确保每次只有一个线程正在读/写每个属性,我会没事的吗? – Joel 2012-04-09 21:01:05

+0

@Joel,如果他们不使用其他继承的成员,你可以。但在这种情况下,我最好使用聚合而不是继承(因为在这种情况下,这些属性为一些单独的目标提供服务,而不是实际上_extend_“QGraphicsItem”)。我个人认为,这会增加清晰度。 – Lol4t0 2012-04-09 21:12:24

+0

我不确定聚合在我的情况下如何工作。我们很清楚,我想让我的课程重新实现绘画方法。我不知道如果不继承QGraphicsItem,我会如何做到这一点。 – Joel 2012-04-09 23:27:27