Das deutsche Python-Forum Foren-Übersicht Das deutsche Python-Forum
Diskussionen rund um die Programmiersprache Python
 
 FAQFAQ   SuchenSuchen MitgliederlisteMitgliederliste BenutzergruppenBenutzergruppen   RegistrierenRegistrieren 
 Wiki FAQWiki FAQ WikiWiki ImpressumImpressum
 ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Pythonischere API für PyQt
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche Python-Forum Foren-Übersicht -> Qt/KDE
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
flying sheep
User


Anmeldungsdatum: 17.09.2009
Beiträge: 13

BeitragVerfasst am: Sa Feb 06, 2010 16:48    Titel: Pythonischere API für PyQt Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
sma
User


Anmeldungsdatum: 19.11.2007
Beiträge: 2132
Wohnort: Kiel

BeitragVerfasst am: So Feb 07, 2010 17:18    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
lunar
User


Anmeldungsdatum: 04.08.2006
Beiträge: 2992
Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen

BeitragVerfasst am: So Feb 07, 2010 19:46    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
flying sheep
User


Anmeldungsdatum: 17.09.2009
Beiträge: 13

BeitragVerfasst am: Mo Feb 08, 2010 01:30    Titel: Antworten mit Zitat

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 Sad)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
snafu
User


Anmeldungsdatum: 21.02.2008
Beiträge: 1369
Wohnort: Gelsenkirchen

BeitragVerfasst am: Mo Feb 08, 2010 05:37    Titel: Antworten mit Zitat

flying sheep hat folgendes geschrieben:
(oder zur not forken Sad)
Meine Glaskugel sagt mir, dass es wohl tatsächlich auf Arbeit für dich hinauslaufen könnte, wenn das Vorhaben umgesetzt werden soll. Smile
_________________
http://lord-killux.mybrute.com
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
lunar
User


Anmeldungsdatum: 04.08.2006
Beiträge: 2992
Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen

BeitragVerfasst am: Mo Feb 08, 2010 09:16    Titel: Antworten mit Zitat

@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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
mkesper
User


Anmeldungsdatum: 20.11.2006
Beiträge: 547
Wohnort: formerly known as mkallas

BeitragVerfasst am: Mo Feb 08, 2010 10:43    Titel: Antworten mit Zitat

Es gibt ja teilweise neue APIs:
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#selecting-incompatible-apis
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#new-style-signal-and-slot-support
_________________
Ich liebe Freie Software!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
lunar
User


Anmeldungsdatum: 04.08.2006
Beiträge: 2992
Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen

BeitragVerfasst am: Mo Feb 08, 2010 11:14    Titel: Antworten mit Zitat

@mkesper: Das hat jetzt aber wenig mit dem Vorschlag des OP zu tun.
_________________
Freiheit ist immer die Freiheit der Andersdenkenden.
(Rosa Luxemburg)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
flying sheep
User


Anmeldungsdatum: 17.09.2009
Beiträge: 13

BeitragVerfasst am: Mo Feb 08, 2010 14:41    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
lunar
User


Anmeldungsdatum: 04.08.2006
Beiträge: 2992
Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen

BeitragVerfasst am: Mo Feb 08, 2010 15:51    Titel: Antworten mit Zitat

@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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
sma
User


Anmeldungsdatum: 19.11.2007
Beiträge: 2132
Wohnort: Kiel

BeitragVerfasst am: Mo Feb 08, 2010 16:34    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
lunar
User


Anmeldungsdatum: 04.08.2006
Beiträge: 2992
Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen

BeitragVerfasst am: Mo Feb 08, 2010 17:00    Titel: Antworten mit Zitat

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 Smile
_________________
Freiheit ist immer die Freiheit der Andersdenkenden.
(Rosa Luxemburg)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
flying sheep
User


Anmeldungsdatum: 17.09.2009
Beiträge: 13

BeitragVerfasst am: Mo Feb 08, 2010 17:54    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
lunar
User


Anmeldungsdatum: 04.08.2006
Beiträge: 2992
Wohnort: Da, wo die Telefonkabel noch oberirdisch verlaufen

BeitragVerfasst am: Mo Feb 08, 2010 18:07    Titel: Antworten mit Zitat

@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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
flying sheep
User


Anmeldungsdatum: 17.09.2009
Beiträge: 13

BeitragVerfasst am: Di Feb 09, 2010 00:24    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche Python-Forum Foren-Übersicht -> Qt/KDE Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
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