9

実際には物理アイテムである約1000個のQGraphicsItemsを持つQGraphicsSceneがあります。フレームごとに進み、衝突をチェックし、それらの衝突を解決します。物理演算をマルチスレッドにしたいと本当に思っています。

QGraphics クラスがスレッドセーフではないことは、私の理解です。つまり、メインスレッドからのみ呼び出すことができます。これにより、各フレームの最終アイテム プロパティ (x、y、回転) をシグナル/スロット メカニズムを使用してメイン スレッドに送信し、メイン スレッド メソッドを使用して実際に QGraphicsItems を更新する必要がありますか? または、これを行う簡単な方法はありますか?

以下は単なる仮説です。QtConcurrent を使用して、QGraphicsItems のリストでメソッドを実行できますか? QGraphicsItem ペイント メソッドで QMutex を使用し、物理メソッド (QGraphicsItem のプロパティを変更する) で QMutex を使用すると、どの時点でも 1 つのスレッドだけが各 QGraphicsItem を読み書きすることが保証されますか?

4

1 に答える 1

2
  1. QGraphicsItem ペイント メソッドで QMutex を使用し、物理メソッド (QGraphicsItem のプロパティを変更する) で QMutex を使用すると、どの時点でも 1 つのスレッドだけが各 QGraphicsItem を読み書きすることが保証されますか?

    いいえ、そうではありません。呼び出されるメソッドQGraphicsItemだけでなく、描画中に頻繁に使用されます。paintたとえば、こちらをご覧ください。たとえそれが機能したとしても、どうやらQGraphicsItem塗装だけでなく使用できるので、それは醜い解決策になるでしょう。

  2. これにより、各フレームの最終アイテム プロパティ (x、y、回転) をシグナル/スロット メカニズムを使用してメイン スレッドに送信し、メイン スレッド メソッドを使用して実際に QGraphicsItems を更新する必要がありますか? または、これを行う簡単な方法はありますか?

    はい、アイテム変更プロセスをメインスレッドに移動する必要があります。実際にはいくつかの選択肢があります:

    • あなたが述べたように、シグナル/スロットメカニズムを使用してください。
    • でメタコールを使用するQueuedConnection
    • カスタム イベントを送信します。

    BlockingQueuedConnection絵が完成するのを待ちたい場合は、 があることを忘れないでください。

    また、これらすべてを で使用できますQtConcurent

実際、管理するのはそれほど難しくありません。手動でスレッドの安全性を確保するよりも、はるかに安全で簡単です。

より大きな問題は、ワーカー スレッドで (たとえばメンバーのみを使用して) アイテムを読み取ろうとしても失敗する可能性があることです。const

QGraphicsItemスレッドセーフではない限り、読み取りも. また、Qt でのマルチスレッド アプリ開発の経験から、何か悪いことが起こり得るとすれば、それは必ず起こるということです。

于 2012-04-09T20:23:12.487 に答える