PyQt4.uic und resources

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
franzf
User
Beiträge: 78
Registriert: Samstag 29. August 2009, 10:21

Hi,

Nachdem ich mich bekehren ließ und auf pyuic4 verzichte, wollte ich mir jetzt ein QMainWindow mit uic.loadUiType erstellen, zwecks Ableiten. ein self.widget = uic.loadUi() fällt flach, da ich ja mein MainWindow mit setupUi erstellen muss, fällt ein setCentralWidget(self.widget) wg. MainWindow-Spezifika flach :/
Das funktioniert auch ganz prima - so lange ich keine Resourcen einbinde!
Dafür muss ich mit pyrc4 erst das resource-file kompilieren - darauf wollte ich aber verzichten!
Naja, pyrc4 hat auch den Nachteil, dass ein mit python2 erstelltes rc-file nicht mit python3 kompatibel ist.

Eine Alternative wäre, dass ich mit uic.compileUi ein Python-Modul generieren lasse. Wäre ganz praktisch, da ich nimmer auf ein mit korrektem python erstelltes resource.py angewiesen bin!
Riesen Nachteil: Wird das global in /usr/lib/pythonxyz/site-packages installiert, hat da ein normaler User keine Schreibrechte! F***

Ein weiteres Problem das sich ergeben hat:
Ich lege die Gui-Komponenten in ein eigenes Modul (z.B. ui). Wenn ich darin ein MainWindow definieren will, kann ich das ui nicht mit "window.ui" laden, es muss "ui/window.ui" sein. Ein resource-file ebenfalls in "ui" platziert wird tollerweise auch nicht gefunden :(

Also doch wieder manuell mit pyuic4 kompilieren?
Oder hat jemand von euch eine Lösung?


Danke
Franz
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

franzf hat geschrieben:...
Dafür muss ich mit pyrc4 erst das resource-file kompilieren - darauf wollte ich aber verzichten!
Naja, pyrc4 hat auch den Nachteil, dass ein mit python2 erstelltes rc-file nicht mit python3 kompatibel ist.
Ja die Ressourcen sind nicht ohne Dein Zutun dynamisch einbindbar. Einer der Hauptgründe dürfte darin liegen, daß das Vorhandensein gewünschter Ressourcen, z.B. irgendeine Bilddatei, auf der Zielplattform nicht gewährleistet ist (externe Abhängigkeit). Das gilt für ui-Dateien nicht, da diese sich nur auf Interna beziehen. Das Kompatibilitätsproblem gilt im Übrigen auch für hartkodierte Uis mittels pyuic.
Der von riverbank vorgeschlagene Deployweg ist so: Da die Kompatibilität der "Kompilate" mit der installierten PyQt-Version nicht sichergestellt ist, sollten diese Umwandlungen zur Installationszeit vorgenommen werden, also mit dem pyrcc4 und pyuic4 der Zielinstallation.
Allerdings hilft Dir das wenig, wenn Du zur Entwicklungszeit den Aufruf von pyrcc4 sparen willst. Wenn Dir das wichtig ist, könntest Du Dir mit einer kleinen Wrapperfunktion die ressource.py on the fly erstellen lassen.
franzf hat geschrieben: Eine Alternative wäre, dass ich mit uic.compileUi ein Python-Modul generieren lasse. Wäre ganz praktisch, da ich nimmer auf ein mit korrektem python erstelltes resource.py angewiesen bin!
Riesen Nachteil: Wird das global in /usr/lib/pythonxyz/site-packages installiert, hat da ein normaler User keine Schreibrechte! F***
Ressourcedateien mit compileUi() erstellen? Geht das? compileUi() nimmt ein Dateiobjekt entgegen, d.h. das muß nicht in Systempfaden landen.
franzf hat geschrieben: Ein weiteres Problem das sich ergeben hat:
Ich lege die Gui-Komponenten in ein eigenes Modul (z.B. ui). Wenn ich darin ein MainWindow definieren will, kann ich das ui nicht mit "window.ui" laden, es muss "ui/window.ui" sein. Ein resource-file ebenfalls in "ui" platziert wird tollerweise auch nicht gefunden :(
Ja das liegt an (uiparser.py):

Code: Alles auswählen

# Zeile 613
self.resources.append(os.path.basename(loc[:-4] + '_rc'))
Während in der ui-Datei der richtige Pfad noch drin steht, vergißt PyQt ihn hier via os.path.basename(). Am Ende der ui-Kompilate steht dann einfach ein

Code: Alles auswählen

import <Name_der_res_datei_ohne_.qrc>_rc
uic geht also davon aus, das sich die py-Ressourcendatei direkt über sys.path erreichen läßt. (Mit einem os.chdir() würde das dann wieder funktionieren, ist aber eher ein Hack als eine saubere Lösung.)
franzf hat geschrieben:Also doch wieder manuell mit pyuic4 kompilieren?
Für ui-Dateien sehe ich das nicht so, für pylupdate4 und pyrcc4 schon.

Grüße, jerch
franzf
User
Beiträge: 78
Registriert: Samstag 29. August 2009, 10:21

Danke für deine ausführliche Antwort!
Da ich nicht weiß, mit welcher python-Version das Programm am Zielrechner ausgeführt wird, komm ich um zwei rcc4-Kompilate nicht rum.
Da mir nicht ganz klar ob das ein Bug oder ein Feature ist, dass uic den korrekten Pfad zum rc vergisst, will ich mich darauf nicht verlassen.

Also pyrcc4-Kompilate ins package legen, neben die "main.py", form.ui mit uic.loadUiType() einlesen.
Auf einen Install-Prozess, bei dem Ui_MainWindow.py erzeigt wird, wollte ich verzichten. Mal schaun, vllt find ich diese Lösung aber mal besser ;)

Alles klar, danke nochmal!
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Das hatte ich ganz vergessen zu sagen, aber Du hast es ja raus gelesen, solange die res-Kompilate neben Deinem main-Skript liegen, in dem auch uic.loadUi() ausgeführt wird, sollte Python sie finden können.

Das Problem mit der Doppelkompiliererei geht leider noch weiter. So trennen manche Distributionen zwischen PyQt-Libs und PyQt-Dev-Tools auf Paketebene (ich glaub opensuse und ubuntu machen das so). Das führt dazu, dass Du zwar auf Pythonebene PyQt importieren, aber die Kompilate während der Installation nicht erstellen kannst. pyuic ist hier eine Ausnahme, da es komplett modularisiert in Python vorliegt und es Dir freisteht, uis zum Installationszeitpunkt zu kompilieren oder on the fly erstellen zu lassen.
Einzige Abhilfe ist hier, auf res-Dateien zu verzichten oder halt die zusätzliche Paketabhängigkeit mit anzugeben. Warum Riverbank nicht auch die anderen Tools in Python verfügbar macht, ist mir ein Rätsel.
Unter Windows sieht die Sache noch trauriger aus, hier können die Tools sonst wo installiert und wegen mangelhafter $PATH-Abstraktion unerreichbar sein. Daher erstelle ich für Windows in der Regel binaries mittels PyInstaller, sofern keine weiteren Python-Apps benötigt werden, und erspare mir so den Installationshorror.

Alles in allem scheint mir die Python-Umsetzung der Qt-Build-Goodies mit PyQt nicht so recht gelungen. (Die Lib holt ja inzwischen schon auf ;))

Grüße jerch
Antworten