loadUi und auto-completion

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Rekrul
User
Beiträge: 78
Registriert: Dienstag 7. Dezember 2010, 16:23

Hallo,

um mir das lästige kompilieren meiner *.ui Dateien zu ersparen bin ich nun auch auf PyQt4.uic.loadUi umgestiegen. Nun habe ich, wie der Titel schon vermuten lässt, ein Problem mit der Autovervollständigung. Klappt natürlich nicht mehr ...

Kennt jemand einen Weg dieses Problem zu umgehen? Ich benutze Eclipse und das PyDev-Plugin.


Gruß,

Rekrul
Rekrul
User
Beiträge: 78
Registriert: Dienstag 7. Dezember 2010, 16:23

Habe das Problem gelöst mit:

Code: Alles auswählen

from PyQt4.uic import compileUiDir
compileUiDir('GUI/UI')
from GUI.UI.MainWindow_UI import Ui_MainWindow
Wenn ich nun das Programm ausführe und meinen workspace aktualisiere kann ich die auto-completion-Funktion nutzen. Ist das so in Ordnung, oder spricht etwas gegen diese Lösung?

Gruß,

Rekrul
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du meinst beim Zugriff auf die Elemente in der späteren UI-Klasse? Das wird dann wohl nicht gehen; außer es existiert ein Hook für die AutoCompletion von Eclipse / PyDev, der ein *.ui-File parsen kann ;-)

@Deine "Lösung":
Was ist denn Dein Ziel? Autocompletion um jeden Preis oder sinnvolles Nutzen von PyQt? Ich würde das sinnvolle Nutzen des uic-Moduls zum dynamischen Laden der Autocompletion ja vorziehen...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lunar

@Rekrul: Das funktioniert nur, wenn Schreibrechte im Verzeichnis mit den UI-Dateien bestehen. Das ist im Regelfall nur während der Entwicklung, aber nicht bei einer normalen Installation der Fall. Diesen Ansatz zu nutzen, ist daher nicht ratsam. Es ist ganz allgemein nicht sonderlich elegant, Aufgaben, die eigentlich der Entwicklungsumgebung obliegen (wie eben das Kompilieren von Dateien), im Quelltext selbst zu erledigen, denn für jeden anderen Nutzer Deines Programms ist das einfach überflüssig.

Wenn Dir das Kompilieren lästig ist, dann stelle Deine IDE so ein, dass sie vor der Ausführung des Programms die UI-Dateien kompiliert. Auf die eine oder andere Weise wird das wohl auch in Eclipse und Pydev möglich sein.

Du kannst das dann auch mit dem dynamischen Laden kombinieren, indem Du zuerst versuchst, die UI-Datei zu importieren, und sie im Falle eines Fehlers dynamisch lädst. So funktioniert die Vervollständigung der Entwicklungsumgebung, ohne dass Du bei der Verteilung Deines Programms kompilierte Dateien mitliefern musst, was die Verteilung im Regelfall erschwert. Das könnte dann in etwas so aussehen:

Code: Alles auswählen

try:
    from GUI.UI.MainWindow_UI import Ui_MainWindow
except ImportError:
    from PyQt4.uic import loadUi
    Ui_MainWindow = None

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent=None):
        if Ui_MainWindow:
            ui = Ui_MainWindow()
            ui.setupUi(self)
        else:
            uic.loadUi('mainwindow.ui', self)
@Hyperion: Deine Präferenzen in Ehren, aber akzeptiere, dass der OP andere hat. Du musst nicht jedes Mal, wenn jemand anders verfährt als Du oder Deine Vorlieben nicht teilt, die Sinnfrage stellen und Deine eigenen Vorlieben aufdrängen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

lunar hat geschrieben: @Hyperion: Deine Präferenzen in Ehren, aber akzeptiere, dass der OP andere hat. Du musst nicht jedes Mal, wenn jemand anders verfährt als Du oder Deine Vorlieben nicht teilt, die Sinnfrage stellen und Deine eigenen Vorlieben aufdrängen.
Ich schrieb ja auch "Ich würde ... vorziehen" - nicht "Du solltest ...!" Zugegebener Maßen waren einige wertende Attribute enthalten, dennoch war es nicht als Aufdrängen gemeint. Ich habe nur darauf hingewiesen, weil der OP wohl beides wollte, sich aber - bis zu Deinem sehr guten Vorschlag - wohl für eine Alternative hätte entscheiden müssen. An solchen Stellen muss man eben abwägen, außer, man kann beides kombinieren.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Rekrul
User
Beiträge: 78
Registriert: Dienstag 7. Dezember 2010, 16:23

@lunar: Deine Lösung sieht mal wieder sehr elegant aus. Vielen Dank!

Ich habe mich auch ein wenig schlau gemacht und herausgefunden wie man in Eclipse *.ui-Dateien kompilieren kann:

1. Run -> External Tools -> External Tools Configurations ...
2. New Program
3. Namen eingeben (zb pyuic)
4. Unter 'Location' den Pfad zum Python-Interpreter eingeben (z.B: 'C:\Python\python.exe')
5. Unter 'Arguments' "\path\to\python\Lib\site-packages\PyQt4\uic\pyuic4.py" "${resource_loc}" eingeben
6. Zum Common-Reiter wechseln, 'File' aktivieren und unter 'Standard Input/Output' '${resource_loc}.py' eingeben
7. Zum Build-Reiter wechseln und 'Build before launch' deaktivieren
8. Zum Refresh-Reiter wechseln und 'Refresh resources upon completion' aktivieren
9. ->'Apply'

Bei Auswahl einer ui-File kann diese nun mit ->Run->pyuic (oder vorher gewählten Namen) kompiliert werden. Das Problem ist dass foo.ui zu foo.ui.py wird.

Umd dies zu umgehen habe ich dann folgendes Script geschrieben:

Code: Alles auswählen

from PyQt4.uic import compileUi
import argparse

parser = argparse.ArgumentParser(description='Compile an ui-file.')
parser.add_argument(dest='file', help='The input ui-file.')

args = parser.parse_args()

py_file = args.file[:-3]+'.py'
with open(py_file, 'w') as output:
    compileUi(args.file, output)
Einfach in der Beschriebung oben unter Schritt 5 "\path\to\python\Lib\site-packages\PyQt4\uic\pyuic4.py" durch den Pfad zum obigen Script austauschen und Schritt 6 ignorieren.
Antworten