Python + QT was braucht man alles

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

burli hat geschrieben:Hm, ich habe in Erinnerung das mal irgendwo geschrieben wurde Python würde häufig dazu verwendet um "mal eben auf die Schnelle" eine Applikation zu entwickeln um sie dann später in C++ zu übertragen. Den Sinn hab ich zwar nicht verstanden, aber so wurde es beschrieben. Vielleicht hängen viele noch an dem Glauben Python sei eine Prä-C++ Sprache.
Das hat mit Prototyping recht wenig am Hut. Prototyping ist dazu da, dass man mit Python schnell einen mehr oder minder funktionsfähigen Prototyp basteln kann, den man nutzen kann um die Realisierbarkeit zu testen oder um den Chef zu überzeugen. Dann kann man es in C++ neu schreiben, weil man sich gerne selbst quält (*g*) oder weil der Chef das so verlangt.
burli hat geschrieben:@Leonidas, machen wir es doch mal kurz: wie sieht denn die korrekte Anwendung von PyQt aus so wie es jetzt angeboten wird und wie sollte es Deiner Meinung nach aussehen und warum? Vielleicht wird ja so Dein Standpunkt deutlicher
Aktuell:

Code: Alles auswählen

import QtGui
PyQt4.QtGui.QApplication
Aktuelles Problem:

Code: Alles auswählen

from PyQt4.QtGui import *
QApplication
IMHO besser:

Code: Alles auswählen

import qt
qt.Application
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Ok, aber wo ist das Problem von "from xyz import *"?

Rein technisch kann es doch nur Probleme geben wenn man zwei Namensräume importiert die Methoden mit identischen Namen haben.

Alles andere ist doch eigentlich nur eine Konvention der Python Programmierer zur Vereinheitlichung von Code, oder hab ich was missverstanden?

Ich will mich nicht beschweren, nur verstehen und lernen

Es gibt im übrigen noch eine Variante die mir persönlich am besten Zusagt und in den Examples von python_qt_doc verwendet wird

Code: Alles auswählen

import sys
from PyQt4 import QtCore, QtGui

app = QtGui.QApplication(sys.argv)
quit = QtGui.QPushButton("Quit")
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

burli hat geschrieben:Ok, aber wo ist das Problem von "from xyz import *"?
Die von dir bereits erwähnten Namespace-Clashes und außerdem ist der Code schwerer zu verstehen weil man mehrere hunderte Namen in den Modulnamespace bekommt und die nutzen kann. Bei einem erneuten lesen ist es nicht unbedingt klar, wo ein bestimmter Name herkommt. Mit Namespaces hingegen kein Problem.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@burli: Das "nur" solltest Du aus dem Satz streichen. Früher oder später *kommt* es zu solchen Kollisionen. Beliebte Beispiele, die mehr oder weniger regelmässig nachgefragt werden, sind `Tk.Image` vs. `PIL.Image`, `numpy.random` vs. `random` aus der Standardbibliothek, und `os.open()` vs. `open()`.

Was ebenfalls sehr blöd ist, ist Code der problemlos läuft, bis man eine Bibliothek aktualisiert und *dann* eine Kollision entsteht. Im Grunde hat man mit jedem Sternchen-Import eine tickende Zeitbombe.

Wenn das jeder machen würde käme auch noch dazu, dass sich die Namen dann über viele Module weiter verteilen und bei jedem *-Import mehr werden. Damit holt man sich aus einem Modul ja auch die Namen, die das importierte Modul seinerseits per * importiert hat. Damit wäre letztendlich das gesamte Modul-Konzept hinfällig und man könnte gleich "includes" á la PHP einführen.
lunar

Leonidas hat geschrieben:
lunar hat geschrieben:Das ist kein Quatsch. Im kommerziellen Bereich nutzen viele Programmierer PyQt4 für Prototypen, weil man damit schnell lauffähige GUIs erzeugen und damit das Marketing überzeugen kann ;)
Naja, und wegen dem fehlenden, in Python überflüssigen Q ist das nicht mehr möglich?
Wenn man zwischen verschiedenen Sprachen wechselt, dann sollten die Klassennamen schon gleich sein, und wenn es nur darum geht, dass der Chef sieht, dass der Python-Code auch Qt4 verwendet ;)
lunar hat geschrieben:Ich habe von all diesen APIs nur Logging benutzt. Das ist zwar unkomfortabel, aber doch keine Katastrophe.
So schlimm wie pywin32 ist PyQt ja nicht, das will ich auch damit nicht sagen, nur geht es mir darum, dass APIs übernehmen nur Programmierern anderer Sprachen hilft, Python-Programmierer aber öfter stört.
Sprich für dich, und überlasse anderen, sich ihre Meinung selbst zu bilden. Mich stört das Q nicht, ebenso wenig wie es andere zu stören scheint, denn von einem PyQt4-Programmierer habe ich diese Klagen noch nicht gehört.

Es sagt in gewisser Weise etwas über dich und PyQt4 aus, wenn du dich als Gtk- oder Wx-Programmierer über das Namenspräfix von Qt4 beschwerst...
lunar hat geschrieben:Es bringt keine Verständnisgewinn, es erschwert das Verständnis aber auch nicht, noch macht es den Code schwerer lesbar. Außerdem ist das keine Ungarische Notation.
Leichter aber auch nicht, also ist es so ziemlich unnütz.
Du stimmst mir also zu, dass das Präfix das Verständnis nicht erschwert, und die Lesbarkeit von Code beeinträchtigt. Es bestehen also in der täglichen Arbeit keine messbaren Einschränkungen. Obwohl also keinerlei Nachteil besteht, keinerlei Behinderung auftritt, sollen die Maintainer sich trotzdem die Arbeit machen, alle Präfixe zu entfernen, bei einem Framework, welches bei weitem mehr Klassen hat als Gtk oder Wx?

Bitte, Qt4 ist freie Software, fühle dich also frei, Patches einzureichen. Von den Maintainern kannst du das nicht ernsthaft verlangen, da noch nicht mal irgendein erkennbarer Nutzen aus dieser Maßnahme zu gewinnen ist.

Sorry, aber da gibt es andere Stellen, an denen die Arbeitskraft von Python-Entwicklern wesentlich sinnvoller angelegt ist!
Ich kann der Bibliothek vorwerfen, dass sie zu einem schludrigen Stil verleitet.
Weil das umständliche Präfix angeblich Sternchen-Imports Vorschub leistet?

Qt4 ist - obwohl aus C++ stammend - mit die konsistenteste und strukturierteste Bibliothek, die es für Python gibt. Im Gegensatz zu vielen Adhoc-Modulen, die man so für Python sieht und die als works-for-me-Lösung angefangen haben und später gewachsen sind, hat sich bei Qt4 jemand mal wirklich Gedanken ums Design gemacht, und ist dann auch noch auf eine vernünftige Lösung gekommen.
Da gibt es ganz andere Bibliotheken, die zwar Sternchen-Imports nicht befördern, weil sie nur aus einem einzigen Modul bestehen, dafür aber eine API haben, die der GLib zur Ehre gereicht.
Leonidas hat geschrieben:Dann kann man es in C++ neu schreiben, weil man sich gerne selbst quält (*g*) oder weil der Chef das so verlangt.
In der Realität sind da wohl eher Dinge wie Legacy-C++-Code, gewachsene Bibliotheken, fehlende Inhouse-Entwickler für Python und andere solche Kleinigkeiten.

Mit dem Chef wird man fertig, aber wenn man der einzige Python-Entwickler für ein MLOC-Projekt ist, dann nimmt man doch lieber C++. Da kommt man dann am Ende mit weniger Arbeit raus ;)
Aktuell:

Code: Alles auswählen

import QtGui
PyQt4.QtGui.QApplication
Wie immer du auch darauf gekommen bist, die Doku empfiehlt das nicht! Den offiziellen und vernünftigen Weg kannst du burli's Posting entnehmen. Vielleicht kann man dann ja in Zukunft mal gute PyQt4-Beispiele in deinen Postings lesen ;)
IMHO besser:

Code: Alles auswählen

import qt
qt.Application
Das ist aber nicht zu realisieren. Du versuchst, hier deine Erfahrungen aus Wx und PyGtk auf PyQt4 zu transferieren, was aber nicht funktioniert, da PyQt4 nun mal wesentlich mehr ist als nur ein GUI-Framework. PyQt4 enthält noch wesentlich mehr Klassen u.a. für SVG-Verarbeitung, Netzwerkzugriff und XML-Parsing.

Nun verwendet aber nicht jedes Programm, welches QtGui verwendet, auch QtXml, gerade weil es mit z.B. lxml auch andere XML-Pakete gibt. Deine Lösung würde das gesamte Qt4-Toolkit beim Start laden, selbst wenn man nur an den GUI-Klassen interessiert ist.

Die gegenwärtige Struktur mit dem PyQt4 Paket, welches die einzelnen Qt4-Module bereitstellt, würde von Leuten entworfen, die sich mit Qt4 wesentlich besser auskennen als wir beide zusammen und die für ihre Entscheidung gute Gründe hatten, über die nachzudenken sich lohnt.
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

lunar hat geschrieben: Nun verwendet aber nicht jedes Programm, welches QtGui verwendet, auch QtXml, gerade weil es mit z.B. lxml auch andere XML-Pakete gibt. Deine Lösung würde das gesamte Qt4-Toolkit beim Start laden, selbst wenn man nur an den GUI-Klassen interessiert ist.
Richtig, es gibt mindestens 8. QtGui, QtCore, QtNetwork, QtOpenGL usw die alle in PyQt4 zusammengefasst sind

Man könnte mit PyQt4.Qt sämtliche Klassen des Qt Framework laden, dann hätte Leonidas sein Scenario mit Qt.QApplication (nur halt noch mit dem Q davor). Dann würde aber auch das komplette Framework in den Speicher geladen, und wer will das schon.

Ich werde mich an die Examples halten und meinem Beispiel von weiter oben folgen

Code: Alles auswählen

import sys
from PyQt4 import QtCore, QtGui

app = QtGui.QApplication(sys.argv)
quit = QtGui.QPushButton("Quit")
BlackJack

Mit ein bisschen "hacken" bekommt man auch eine Lazy-Import hin, der nicht gleich alles importiert, sondern erst, wenn man die Sachen verwendet.
lunar

BlackJack hat geschrieben:Mit ein bisschen "hacken" bekommt man auch eine Lazy-Import hin, der nicht gleich alles importiert, sondern erst, wenn man die Sachen verwendet.
Das löst zwar das Geschwindigkeitsproblem, widerspricht aber irgendwie dem Sinn von Modulen, deren Zweck es doch ist, Code in logische Gruppen zu unterteilen.
BlackJack

Oder einen Namensraum zur Verfügung zu stellen. Ein Namensraum für alle Qt-Klassen ist doch eine nette Sache. Dass da dann zu viel drin ist, würde ich nicht gelten lassen, weil bei GUI-Code andere "Regeln" gelten als bei normalem Quelltext.
lunar

BlackJack hat geschrieben:Oder einen Namensraum zur Verfügung zu stellen. Ein Namensraum für alle Qt-Klassen ist doch eine nette Sache. Dass da dann zu viel drin ist, würde ich nicht gelten lassen, weil bei GUI-Code andere "Regeln" gelten als bei normalem Quelltext.
Qt4 ist aber mehr als GUI, wesentlich mehr. Man Qt4 auch prima dazu hernehmen, einen Dämon zu schreiben, der das XML-Webservice fungiert. QtGui spielt da keine Rolle, wohl aber QtCore, QtNetwork und QtXml.

Das ist zwar ein Namensraum, die einzelnen Module haben aber total unterschiedliche Aufgaben.

Deswegen finde ich den aktuellen Ansatz perfekt. Ein Namensraum (PyQt4), welcher einzelne Module zur Verfügung (QtCore, QtGui, etc.) stellt.
g4borg
User
Beiträge: 16
Registriert: Donnerstag 4. Oktober 2007, 20:38

qt/__init__.py

Code: Alles auswählen

import PyQt4
from PyQt4.QtGui import QApplication as Application
bitte. :roll: eventuell noch ein schönes __all__[] bauen.

es gibt auch sinnvolle diskussionen... wenn man sowas präferiert baut man sich ein modul qt, importiert dort wie man es lieber hat und baut sich - je nachdem was man so braucht - langsam sein abstraktionstoolkit.

vorteil2: bei Qt5 bleibt der code womöglich kompatibel, angepasst wird nur die wrapper bib.

und dann spielt man es in ein svn und macht es publik. und dann vermehrt sich der code von selbst!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

g4borg hat geschrieben:bitte. :roll: eventuell noch ein schönes __all__[] bauen.
Habe ich schon vor zwei Jahren für Qt3 gemacht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten