Qt4.5 und X11, zeichnen in Threads...
-
Ich habe folgende Anforderung:
Ein Qt-Widget holt sich aus einer intensiven Anwendung ein Hintergrundbild und zeichnet darauf dann noch zusätzlich ein wenig herum.
Diese Anwendung, eine externe Bibliothek, verwendet nur x11-Methoden zum Zeichnen, benötigt also Pixmap-Handles wie X11 sie kennt und QPixmap::handle() auch liefert.
Mache ich das ganze ohne Threads funktioniert es einwandfrei, davon abgesehen das es unschön ist wenn die gesamte Anwendung für mehrere Sekunden einfriert. Und das jedesmal wenn ein neuer Frame kommt. Unschön. Nur alle X Frames ein neues Hintergrundbild zu nehmen (was möglich wäre) ist auch keine Lösung, weil es dann halt alle X Frames blockiert.
Daher: Threads. Nur ist eben das Problem wie vorgegangen werden muss, das ist mir nicht ganz klar.
Meine erste Idee war es im Worker-Thread ein QPixmap zu erstellen, dies wie gewohnt an die Library zu übergeben und dies dann im Endeffekt den Main-Thread auslesen zu lassen.
Problem: QPixmaps dürfen nur im Hauptthread erstellt werden. Doof, ist aber so.
Nächster Ansatz ist es natürlich das QPixmap außerhalb zu erstellen und dem Worker-Thread zu übergeben. Ergebnis: _XAllocID: Assertion `!(dpy->flags & (1L << 3))' failed.
Anscheinend mag Qt es nicht wenn aus einem anderen Thread da rumgewerkelt wird.Nächster Ansatz: Im Worker-Thread ein XPixmap zu erstellen, dies dann mit der Qt4.5-Methode QPixmap::fromX11Pixmap konvertieren und gut ist. Leider geht das nicht, die Funktion hängt sich (und alles andere) auf.
Was nun? Ich bin etwas ratlos.
-
Zeichnen darfst du ja, nur nicht in der aktuellen Ansicht.
Erstell im Thread ein QImage, zeichne drauf rum und wenn er fertig ist, teile dem Hauptthread mittels eines Signal mit, dass er es sich holen kannähnliches Beispiel: http://qt.nokia.com/doc/4.5/threads-mandelbrot.html
-
Das Problem dabei ist das ich in dem Worker-Thread nicht mit QImage arbeiten kann.
Das Bild das die Library erzeugt ist ein Pixmap (X11). Die einzige Konvertierungsmethode die bei Qt existiert ist hier entweder mit XCopyArea in ein QPixmap zu zeichnen oder das nicht funktionierende QPixmap::fromX11Pixmap() zu benutzen.Das Hintergrundbild liegt also nur am X-Server vor und jeder Versuch darauf aus dem anderen Thread zuzugreifen schlug bisher fehl. Ebenso der Versuch aus dem Worker-Thread in ein QPixmap zu zeichnen. Denn wenn dieses im Gui-Thread erstellt wurde darf ich nicht drauf zugreifen und ein QPixmap im Worker-Thread zu erstellen erlaubt Qt nicht.
-
Fellhuhn schrieb:
Nächster Ansatz: Im Worker-Thread ein XPixmap zu erstellen, dies dann mit der Qt4.5-Methode QPixmap::fromX11Pixmap konvertieren und gut ist. Leider geht das nicht, die Funktion hängt sich (und alles andere) auf.
Man kann das auch von Hand konvertieren. Wenn die Farbtiefe jeweils 24bit ist, geht das relativ einfach.
Nur aufpassen QT verwendet rgb und X11 verwendet bgr !