2012-04-06 15 views
9

Tengo un QGraphicsScene con aproximadamente 1000 QGraphicsItems, que en realidad son elementos de física. Cada fotograma avanza, comprueba colisiones y resuelve esas colisiones, entre otras cosas. Realmente me gustaría tener la física multiproceso.Qt física escena multiproceso

Tengo entendido que las clases de QGraphics no son seguras para subprocesos. Es decir, solo pueden ser llamados desde el hilo principal. ¿Esto me obliga a enviar las propiedades finales (x, y, rotación) de cada cuadro al hilo principal utilizando un mecanismo de señal/ranura, y luego utilizar un método de hilo principal para actualizar realmente los QGraphicsItems? ¿O hay una manera más fácil de hacer esto?

Lo que sigue es solo una hipótesis: ¿Podría usar QtConcurrent para ejecutar un método en mi lista de QGraphicsItems? Si uso un QMutex en mi método de pintura QGraphicsItem y un QMutex en mi método de física (que cambiará las propiedades de mi QGraphicsItem), ¿garantizaría esto que solo un hilo esté leyendo/escribiendo cada QGraphicsItem en cualquier momento en el tiempo?

+0

He leído algo sobre el uso de QueuedConnection al conectar las señales/ranuras. No lo he intentado, ni siquiera he investigado los detalles, pero creo que vale la pena seguir investigando. ¿Alguien más tiene experiencia con esto? – aldo

+0

Utilicé el puerto Delphi de Box2D y estoy muy satisfecho con él. ¿Por qué no intentarlo? Diríjase a esta [página] (http://labs.qt.nokia.com/2010/02/26/qt-box2d-is-easy/) si está interesado. – menjaraz

+0

Box2D parece interesante, pero no veo en ningún lado que sea multiproceso. – Joel

Respuesta

2
  1. Si uso un QMutex en mi método de pintura QGraphicsItem y una QMutex en mi método de la física (que va a cambiar las propiedades de mi QGraphicsItem), haría esta garantía que sólo un hilo está leyendo/escribiendo cada uno QGraphicsItem en cualquier momento en el tiempo?

    No, no lo haría. QGraphicsItem utilizado en gran medida al dibujar, no solo paint método llamado. Mire, por ejemplo, here. Incluso si pudiera funcionar, sería una solución fea, porque aparentemente, QGraphicsItem se puede usar no solo para pintar.

  2. hace esto fuerza me para enviar las propiedades finales del artículo (x, y, rotación) cada marco para el hilo principal utilizando un mecanismo de señal/ranura, y luego utilizar un método hilo principal para actualizar realmente el QGraphicsItems? ¿O es hay una manera más fácil de hacer esto?

    Sí, debe mover el proceso de cambio de elemento a la secuencia principal. En realidad tiene algunas alternativas:

    • Use el mecanismo de señales/ranuras, como ha mencionado.
    • Use meta-calls con QueuedConnection
    • Envíe eventos personalizados.

    No olvides que tienes BlockingQueuedConnection, si quieres esperar a que termine la pintura.

    Además, puede usar todo esto con QtConcurent.

En realidad, no es tan difícil de administrar. Es mucho más seguro y sencillo que garantizar la seguridad de los hilos manualmente.

El problema más grande es que es probable que incluso puede fallar al intentar leer elementos (utilizando sólo const memebers, por ejemplo) en el subproceso de trabajo.

En cuanto, como QGraphicsItem no es hilo de seguridad, incluso la lectura es no. Y mi experiencia con el desarrollo de aplicaciones multihilo en Qt me dice que, si algo malo puede suceder, ocurrirá.

+0

Gracias por la respuesta. Una pregunta: si creé una clase que hereda QGraphicsItem y agregué algunas propiedades personalizadas (color, velocidad, etc.), ¿podría modificarlas desde otro hilo? ¿Estaré bien siempre y cuando me asegure de que solo un hilo esté leyendo/escribiendo en cada propiedad al mismo tiempo? – Joel

+0

@Joel, si no usan otros miembros heredados, puede. Pero sería mejor usar agregando más bien herencia en este caso (_your_ incluye 'QGraphicsItem' como memeber), porque en este caso esas propiedades sirven para algunos objetivos separados, en realidad no _extend_' QGraphicsItem'. Personalmente creo que aumentará la claridad. – Lol4t0

+0

No estoy seguro de cómo funcionaría una agregación en mi caso. Para que quede claro, quiero que mi clase vuelva a aplicar el método de pintura. No estoy seguro de cómo haría esto sin heredar QGraphicsItem. – Joel