2017-03-13 2 views
1

Ich entwickle eine 3D-App mit Qt und OpenGL. Die App besteht aus einem QMainWindow mit einem QOpenGLWidget als zentralem Widget und einer QML UI als Dock Widget. Ich erkannte, dass die Benutzereingaben und die Benutzeroberfläche von der Renderleistung abhängen: Wenn meine App mit niedrigen fps läuft, werden die Benutzereingaben nicht alle abgefangen, und es wird schwierig, die Benutzeroberfläche zu verwenden.QOpenGLWidget und Multithreading

Also habe ich über das Rendering in einem separaten Thread nachgedacht. Ich habe verschiedene Techniken ausprobiert, zum Beispiel QTimer oder QThread, aber ich bekomme immer Probleme, den OpenGL-Kontext zu teilen, die Größe zu ändern oder einen QPainter zu verwenden.

Ich wundere mich, wenn das Rendern in einem anderen Thread ein guter Ansatz ist.

Irgendwelche Vorschläge, Ratschläge?

Danke.

Antwort

2

Typische GUI-Frameworks können nicht direkt aus mehreren Threads verwendet werden, und QT ist keine Ausnahme. Der Versuch, GUI-Stuff aus verschiedenen Threads zu erstellen, führt in der Regel zu Problemen.

Diese Frameworks haben normalerweise eine interne Ereigniswarteschlange, in der Ereignisse platziert und dann nacheinander verarbeitet werden. Wenn das Framework korrekt verwendet wird, wird sichergestellt, dass auf die GUI-bezogenen Elemente nur von einem einzigen Thread zugegriffen wird. Sie ermöglichen es jedoch, zusätzliche Ereignisse in die Warteschlange aufzunehmen.

Und hier sind wir auf dem Weg zu gehen: Halten Sie die gesamte GUI in einem einzigen Thread und Benutzereingabe Verarbeitung in den anderen Thread. Sobald die Benutzerdaten verarbeitet sind, füttern Sie Ihre GUI entsprechend.

Möglichkeiten, die von Qt angeboten werden, sind e. G. invoke Funktion oder die event system.

0

Verwenden Sie einfach nicht QOpenGLWidget. Verwenden Sie ein einzelnes QML-Fenster für alles.

Rendern Sie Ihre OpenGL-Dinge in Pre-Render oder Post-Render-Funktion der QML mit den QQuickWindow::beforeRendering() oder QQuickWindow::afterRendering() Signale.

Das wird den Rendering-Thread der QML verwenden, so dass Sie es nicht erstellen müssen. Und die Anwendungsfälle und Synchronisation sind in den qt docs erklärt:

http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-example.html