2012-04-06 9 views
9

Mam QGraphicsScene z około 1000 QGraphicsItems, które są faktycznie przedmiotami fizyki. Każda ramka, którą posuwają się naprzód, sprawdza kolizje i usuwa te kolizje, między innymi. Naprawdę chciałbym mieć wielowątkową fizykę.Scenka z fizyki Qt wielowątkowość

Rozumiem, że klasy QGraphics nie są bezpieczne dla wątków. Oznacza to, że można je wywołać tylko z głównego wątku. Czy to zmusza mnie do wysłania końcowych właściwości elementu (x, y, obrót) każdej ramki do głównego wątku za pomocą mechanizmu sygnału/szczeliny, a następnie użyć metody głównego wątku, aby faktycznie zaktualizować QGraphicsItems? Czy istnieje prostszy sposób na zrobienie tego?

Poniżej znajduje się tylko hipoteza: czy mogę użyć QtConcurrent do uruchomienia metody na mojej liście QGraphicsItems? Jeśli użyję QMutex w mojej metodzie QGraphicsItem i QMutex w mojej metodzie fizyki (która zmieni właściwości mojego QGraphicsItem), czy zagwarantuje to, że tylko jeden wątek będzie czytał/zapisał każdy QGraphicsItem w dowolnym momencie?

+0

Czytałem coś o użyciu QueuedConnection podczas łączenia sygnałów/slotów. Nie próbowałem ani nawet nie zaglądałem w szczegóły, ale uważam, że warto je zbadać. Czy ktoś inny ma doświadczenie w tym? – aldo

+0

Użyłem portu Delphi Box2D i jestem z niego bardzo zadowolony. Dlaczego nie spróbować? Udaj się do tej [strony] (http://labs.qt.nokia.com/2010/02/26/qt-box2d-is-easy/), jeśli jesteś zainteresowany. – menjaraz

+0

Box2D wygląda interesująco, ale nigdzie nie widzę, że jest wielowątkowy. – Joel

Odpowiedz

2
  1. Jeśli używam QMutex w moim QGraphicsItem metody malowania i QMutex w moim metody fizyki (który zmienia właściwości mojego QGraphicsItem) by ta gwarancja, że ​​tylko jeden wątek jest czytanie/pisanie każdego QGraphicsItem w dowolnym momencie w czasie?

    Nie, nie będzie. QGraphicsItem używane ciężko podczas rysowania, nie tylko metoda o nazwie zwanej paint. Na przykład: here. Nawet gdyby to zadziałało, byłoby to brzydkie rozwiązanie, ponieważ podobno, QGraphicsItem może być używane nie tylko do malowania.

  2. działa tej siły mi wysłać ostateczne właściwości punkt (x, y, obrót) każdej ramce głównego wątku przy użyciu mechanizmu sygnał/gniazda, a następnie użyciu głównie metody gwintu faktycznie aktualizuje QGraphicsItems? Czy jest tam łatwiejszy sposób na zrobienie tego?

    Tak, musisz przenieść proces zmiany pozycji do głównego wątku. Trzeba rzeczywiście jakieś alternatywy:

    • korzystać z sygnałów/mechanizm slotów, jak wspomniano.
    • Zastosowanie meta-calls z QueuedConnection
    • Wyślij niestandardowych zdarzeń.

    Nie zapomnij, że masz BlockingQueuedConnection, jeśli chcesz poczekać na ukończenie malowania.

    Możesz również używać wszystkich tych rzeczy z QtConcurent.

Właściwie, to nie jest tak trudna do opanowania. Jest znacznie bezpieczniejsze i łatwiejsze niż ręczne zapewnienie bezpieczeństwa gwintów.

Większym problemem jest to, że prawdopodobnie może zakończyć się niepowodzeniem, nawet gdy próbuje czytać elementy (przy użyciu tylko const memebers, na przykład) w wątku roboczego.

Jak daleko, jak QGraphicsItem nie jest wątku bezpieczne, nawet czytając to nie. Moje doświadczenie w tworzeniu aplikacji wielowątkowych w Qt mówi mi, że jeśli zdarzy się coś złego, stanie się to.

+0

Dzięki za odpowiedź. Jedno pytanie: jeśli utworzyłem klasę, która dziedziczy QGraphicsItem i dodałem jakieś niestandardowe właściwości (kolor, prędkość itd.), Czy mogę zmodyfikować te z innego wątku? Czy będę w porządku, o ile upewnię się, że tylko jeden wątek czyta/piszę do każdej nieruchomości w tym samym czasie? – Joel

+0

@Joel, jeśli nie używają innych odziedziczonych członków, możesz. Ale w tym przypadku lepiej użyłbym agregowania raczej dziedziczenia (_two_ zawiera 'QGraphicsItem' jako memeber), ponieważ w tym przypadku te właściwości służą niektórym osobnym celom, a nie _extend_' QGraphicsItem'. Osobiście uważam, że zwiększy to jasność. – Lol4t0

+0

Nie jestem pewien, jak działa agregacja w moim przypadku. Tak, aby było jasne, chcę, aby moja klasa ponownie wdrożyła metodę malowania. Nie jestem pewien, jak bym to zrobił bez dziedziczenia QGraphicsItem. – Joel