 |
Das deutsche Python-Forum Diskussionen rund um die Programmiersprache Python
|
| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
| Autor |
Nachricht |
flying sheep User
Anmeldungsdatum: 17.09.2009 Beiträge: 13
|
Verfasst am: Sa Feb 06, 2010 16:48 Titel: Pythonischere API für PyQt |
|
|
hi, ich wollte fragen, ob es irgend ein interesse gibt, eine art PyQt4Py (Pythonic Qt4 for Python) zu erstellen.
ich spreche davon, mehr mit __getitem__ usw. zuarbeiten, properties statt gettern und settern zu verwenden usw.: | Code: (Python) | 1 2 3 4 5 6 7 8 9
| l = QGridLayout(self)
self.layout = l
w = QLabel(self)
w.text = "hello"
w.size = 600, 400
l[0,0] = w
print(l[0,0]) #gibt aus: QLabel("hello") | gäbe es eine möglichkeit ein modul zu erstellen, das auf PyQt4 aufsetzt und quasi dessen getter und setter maskiert und mit builtins ersetzt? damit dir(QWidget) auch nicht u.a. setParent oder sowas zurückliefert |
|
| Nach oben |
|
 |
sma User
Anmeldungsdatum: 19.11.2007 Beiträge: 2132 Wohnort: Kiel
|
Verfasst am: So Feb 07, 2010 17:18 Titel: |
|
|
Braucht man da nicht einfach nur ein
| Code: (Python) | 1
| QLabel.text = property(QLabel.text, QLabel.setText) |
Das scheint mir jetzt eher Monkey-Patch-Fleißarbeit zu sein und ich (sich nicht mit Qt und anderen GUI-Rahmenwerken unter Python auskennend) finde komisch, dass das nicht Teil von pyside (oder wie die Qt-Bindings gerade heißen) ist.
Möglicherweise kann man einfach nach "foo" und "setFoo" in allen Klassen suchen und das dann automatisiert ergänzen. Das sollte doch in 10 Zeilen oder so machbar sein. Hier -> http://www.pyside.org/home-binding/api-extractor/ schreiben die allerdings etwas von einem API-Extractor und vielleicht muss man den einfach schlau genug machen.
Stefan |
|
| Nach oben |
|
 |
lunar User

Anmeldungsdatum: 04.08.2006 Beiträge: 2992 Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen
|
Verfasst am: So Feb 07, 2010 19:46 Titel: |
|
|
Theoretisch ist es möglich, ein solches Modul zu entwickeln, da man über QMetaObject an alle Eigenschaften im Sinne von Qt herankommt, und daraus anschließend Eigenschaften im Sinne von Python machen könnte.
Praktisch ist das keine ganz so gute Idee, denn das führt zwangsläufig zu Namenskonflikten. In Qt haben Eigenschaften und Methoden unterschiedliche Namensräume. Eine von QObject abgeleitete Klasse kann also eine Qt-Eigenschaft namens "foo" und eine Methode namens "foo" haben.
In Python dagegen müssen sich Eigenschaften und Methoden einen Namensraum teilen, es kann nur ein einziges "foo" in einer Klasse geben, und das muss sich entscheiden, ob es Eigenschaft sein will oder Methode.
Das wäre nun alles kein Problem, wenn per definitionem eine Beziehung zwischen Getter und Eigenschaftsname bestehen würde. Die aber gibt es nicht, Getter können benannt werden, wie man lustig ist. Mehr noch, Getter können überladen werden.
In Qt kann es also eine Eigenschaft "foo", eine Methode "foo()" und eine Methode "foo(mit_argument)" geben. Würde man nun die Qt-Eigenschaft "foo" in eine Python-Eigenschaft "foo" umsetzen, fiele die zweite "foo"-Methode über Bord.
Aus diesem Grund verzichten sowohl PyQt als auch pyside auf diese Möglichkeit. Da zumindest PyQt4 aber eine "pyqtConfigure"-Methode bietet, mit der man viele Eigenschaften auf einmal setzen kann, und zudem die Konstruktoren der Objekte ebenfalls so überladen sind, dass man direkt Eigenschaften setzen kann, fällt das eigentlich nicht so ins Gewicht. Da gibt es wichtigeres (z.B. überflüssige Typen wie QString und QVariant transient zu machen). _________________ Freiheit ist immer die Freiheit der Andersdenkenden.
(Rosa Luxemburg) |
|
| Nach oben |
|
 |
flying sheep User
Anmeldungsdatum: 17.09.2009 Beiträge: 13
|
Verfasst am: Mo Feb 08, 2010 01:30 Titel: |
|
|
gemäß des kapselungsgeraffels von c++ und so sind doch die properties c++-versteckt, oder? d.h. hat man über python/sip eh keinen zugriff drauf. wenn man z.b. qwidget.width eingibt, ist das eindeutig die funtion width und nicht evtl. eine property.
das heißt, man müsste sip händisch so konfigurieren, dass sip nicht die methode width in den namespace packt, sondern daraus (und aus setWidth) eine property baut. das bedeutet zwar, dass man kein modul auf pyqt draufbauen kann, aber es bedeutet, dass man die devs von pyside / pyqt zu ner alternativen api überreden könnte (oder zur not forken ) |
|
| Nach oben |
|
 |
snafu User

Anmeldungsdatum: 21.02.2008 Beiträge: 1369 Wohnort: Gelsenkirchen
|
Verfasst am: Mo Feb 08, 2010 05:37 Titel: |
|
|
| flying sheep hat folgendes geschrieben: | (oder zur not forken ) | Meine Glaskugel sagt mir, dass es wohl tatsächlich auf Arbeit für dich hinauslaufen könnte, wenn das Vorhaben umgesetzt werden soll.  _________________ http://lord-killux.mybrute.com |
|
| Nach oben |
|
 |
lunar User

Anmeldungsdatum: 04.08.2006 Beiträge: 2992 Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen
|
Verfasst am: Mo Feb 08, 2010 09:16 Titel: |
|
|
@flying sheep: Qt-Eigenschaften sind nicht „versteckt“, sondern über "QObject.property()" und "QObject.setProperty()" erreichbar. Mit „Kapselungsgeraffel“ hat das auch so ziemlich gar nichts zu tun …
Was den Rest angeht, so habe ich das Gefühl, dass Du meinen Beitrag überhaupt nicht gelesen hast. "QWidget.width" ist zwar eine Methode, aber eben nicht eindeutig. Es kann mehrere überladene Versionen dieser Methode geben. Diese überladenen Methoden kann man nicht mehr erreichen, wenn man pauschal jeden Getter in eine entsprechende Eigenschaft verwandelt.
Falls Du ein konstruiertes Beispiel sehen möchtest, so verweise ich auf meinen Beitrag in einem anderen Forum (dort ist die Syntaxhervorhebung schöner). _________________ Freiheit ist immer die Freiheit der Andersdenkenden.
(Rosa Luxemburg) |
|
| Nach oben |
|
 |
mkesper User

Anmeldungsdatum: 20.11.2006 Beiträge: 547 Wohnort: formerly known as mkallas
|
|
| Nach oben |
|
 |
lunar User

Anmeldungsdatum: 04.08.2006 Beiträge: 2992 Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen
|
Verfasst am: Mo Feb 08, 2010 11:14 Titel: |
|
|
@mkesper: Das hat jetzt aber wenig mit dem Vorschlag des OP zu tun. _________________ Freiheit ist immer die Freiheit der Andersdenkenden.
(Rosa Luxemburg) |
|
| Nach oben |
|
 |
flying sheep User
Anmeldungsdatum: 17.09.2009 Beiträge: 13
|
Verfasst am: Mo Feb 08, 2010 14:41 Titel: |
|
|
außerdem kannte ich das schon. trotzdem danke, denn ich hab beim letzten lesen das hier übersehen und das ist mal echt eine erleichterung!
@lunar: du führst die diskussion öfter, oder? ^^
wegen der namensraumproblematik sei angemerkt, dass eine umsetzung in meinem sinne (mit python-properties) den spaß sowieso inkompatibel zum c++-qt4 macht, man also entsprechende methoden umbenennen könnte. soweit ich weiß ist mir eine solche aber auch noch nie untergekommen. könntest du ein beispiel nennen?
PS: im verinkten beitrag ist auch von qtruby die rede: wie löst das denn die namensraum-problematik? soweit ich weiß sind funktionen in ruby auch objekte. |
|
| Nach oben |
|
 |
lunar User

Anmeldungsdatum: 04.08.2006 Beiträge: 2992 Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen
|
Verfasst am: Mo Feb 08, 2010 15:51 Titel: |
|
|
@flying sheep: So einfach ist das auch nicht. Dieses „Umbenennen“ müsste schließlich automatisiert vonstatten gehen, ohne seinerseits neue Konflikte zu erzeugen. Davon abgesehen, müsste sowas wieder extra dokumentiert werden, da die C++-Dokumentation dann ja nicht mehr greift.
Ein Beispiel für Namenskonflikte zwischen Methoden und Eigenschaften kann ich Dir nicht nennen. Ich habe nicht danach gesucht. Die theoretische Möglichkeit reicht aber schon, damit man das berücksichtigen muss.
Möglich wäre das prinzipiell alles schon, nur eben doch mit verhältnismäßig viel Aufwand. Ob es das jetzt wert ist … ich persönlich finde das jetzt nicht so schlimm, aber ich bin möglicherweise auch zu stark von C++ beeinflusst.
Was Ruby angeht, so habe ich keine Ahnung. Ich kenne weder Ruby noch QtRuby. _________________ Freiheit ist immer die Freiheit der Andersdenkenden.
(Rosa Luxemburg) |
|
| Nach oben |
|
 |
sma User
Anmeldungsdatum: 19.11.2007 Beiträge: 2132 Wohnort: Kiel
|
Verfasst am: Mo Feb 08, 2010 16:34 Titel: |
|
|
| lunar hat folgendes geschrieben: | | Was Ruby angeht, so habe ich keine Ahnung. Ich kenne weder Ruby noch QtRuby. |
Die Doku zu QtRuby sagt, dass fooBar(), foo_bar(), setFooBar(), set_foo_bar() und foo_bar=() funktionieren. Statt CamelCase geht auch under_score. Statt C-style setter-Methode geht auch der Ruby-typische Setter. Da man in Ruby ja Argument-Klammern weglassen kann, hat man damit die typische Property-Notation fooBar und fooBar=.
Offenbar wird das Ruby-Binding genau wie PHP, C# und Perl aus einer Metabeschreibung generiert. Warum es für Python anders ist, habe ich nicht recherchiert. Wirklich zufriedenstellend finde ich das jedoch alles nicht, denn insbesondere wenn immer auf die C++-Dokumentation verwiesen wird, ist das kein UI-Rahmenwerk für die jeweilige Sprache sondern eines, wo man C++ mit etwas anderer Syntax benutzt.
Stefan |
|
| Nach oben |
|
 |
lunar User

Anmeldungsdatum: 04.08.2006 Beiträge: 2992 Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen
|
Verfasst am: Mo Feb 08, 2010 17:00 Titel: |
|
|
| sma hat folgendes geschrieben: | | Die Doku zu QtRuby sagt, dass fooBar(), foo_bar(), setFooBar(), set_foo_bar() und foo_bar=() funktionieren. Statt CamelCase geht auch under_score. Statt C-style setter-Methode geht auch der Ruby-typische Setter. Da man in Ruby ja Argument-Klammern weglassen kann, hat man damit die typische Property-Notation fooBar und fooBar=. |
Tja, "fooBar=()" gibt es nun eben nicht in Python. Da sind Eigenschaften und Methoden unterschiedliche Dinge, und können nicht denselben Namen tragen, was die an sich gute Idee des OP in der Implementierung recht kompliziert macht.
| Zitat: | | Wirklich zufriedenstellend finde ich das jedoch alles nicht, denn insbesondere wenn immer auf die C++-Dokumentation verwiesen wird, ist das kein UI-Rahmenwerk für die jeweilige Sprache sondern eines, wo man C++ mit etwas anderer Syntax benutzt. |
Genau das tut man ja auch, ein natives Python-Rahmenwerk gibt es ja nicht. Es wäre auch schwer, ein in Größe und Qualität ebenbürtiges Rahmenwerk zu implementieren … es wäre auch ziemlich viel Aufwand, nur weil die Namensgebung und die Semantik von Qt-Eigenschaften nicht pythonisch sind  _________________ Freiheit ist immer die Freiheit der Andersdenkenden.
(Rosa Luxemburg) |
|
| Nach oben |
|
 |
flying sheep User
Anmeldungsdatum: 17.09.2009 Beiträge: 13
|
Verfasst am: Mo Feb 08, 2010 17:54 Titel: |
|
|
uncool. man müsste halt recherchieren, ob es in qt4 getter mit optionalen argumenten gibt, was ich stark bezweifle und dann für jede funktion "qklasse.prop" , für die es eine setProp-funktion gibt eine python-property anfertigen.
was haltet ihr vom rest meines originalposts? |
|
| Nach oben |
|
 |
lunar User

Anmeldungsdatum: 04.08.2006 Beiträge: 2992 Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen
|
Verfasst am: Mo Feb 08, 2010 18:07 Titel: |
|
|
@flying sheep: Du meinst hinsichtlich der Verwendung eines Tupels als Ersatz für QSize und des Zugriffs auf "QGridLayout"?
Nun, ich würde sagen, auch wieder nicht weit genug gedacht. QSize verhält sich anders als ein Tupel (vgl. "QSize(100, 200) * 10" und "(100, 200) * 10"). QGridLayout.addWidget hat neben Zeile und Spalte noch ein Argument für die Ausrichtung, dass bei Deinem Ansatz über "__getitem__()" verloren geht. Man müsste eher "label.size = (100, 200, Qt.AlignCenter)" oder ähnlich verwenden.
Ein vollständiger Ersatz ist das also nicht … _________________ Freiheit ist immer die Freiheit der Andersdenkenden.
(Rosa Luxemburg) |
|
| Nach oben |
|
 |
flying sheep User
Anmeldungsdatum: 17.09.2009 Beiträge: 13
|
Verfasst am: Di Feb 09, 2010 00:24 Titel: |
|
|
aber ein einfacher. wenn man nur zwei argumente verwendet, funktioniert es auch (und ich benutze meist nur die beiden) ansonsten halt mehr tupelelemente, wie du vorgeschlagen hast
qsize sollte auch __getitem__ unterstützen, um auf x und y zuzugreifen. multiassignment, unpacking und so. |
|
| Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group using CodeBB 1.1
|