connect_object

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
herakli
User
Beiträge: 9
Registriert: Dienstag 8. August 2006, 21:30

Mittwoch 16. August 2006, 07:34

Hallo!
Gestern habe ich begonnen, mich in pygtk einzuarbeiten. Leider hab ich da ein kleines Verständnisproblem mit einer Funktion, nämlich connect_object. Statt dem Parameter data (wie gewöhnlich) wird dieser Funktion ein anderes Widget z.B. ein Fenster übergeben, also

Code: Alles auswählen

button.connect_object("click", gtk.Widget.destroy, fenster
Leider ist mir nicht klar geworden, was hier genau passiert. Der Button wird hier bei dem Callback gtk.Widget.destroy verbunden und reagiert bei einem click-signal. Soweit, so gut.
Was hat es aber mit dem letzten Parameter auf sich?
Wird dieser letzte Parameter der Callbackfunktion übergeben und, wenn ja, welchem (formalen) Parameter wird der (aktuelle) Parameter fenster zugewiesen?
Oder bedeutet das: Rufe die Callbackfunktion, die mit fenster verbunden ist, falls ein click-signal eintritt?
Würde mich über eine ausführliche Erläuterung freuen.
mfg
Vortex
User
Beiträge: 16
Registriert: Sonntag 13. August 2006, 14:12
Kontaktdaten:

Mittwoch 16. August 2006, 11:47

Hi, bin zwar auch noch neuling aber ich glaube das lässt sich ganz einfach erklären.

Eigentlich steckt alles in diesem Satz:
The connect_object() method is the same as the connect() method except that the handler is invoked with the specified gobject in place of the object invoking the connect_object() method.
Wenn du jetzt das "normale" widget.connect(...) benutzt, dann wird dem callback (also der Funktion, die aufgerufen wird, sobald das entsprechende Signal auftritt) als erster Parameter das widget übergeben, auf das du .connect angewand hast.

Beispiel:

Code: Alles auswählen

self.fenster.connect("delete-event", self.on_delete_event)
Sobald nun "fenster" das Signal "delete-event" aussendet (das passiert z.B. wenn man auf das "X" in der Titelleiste des Fensters klickt) wird die Callbackfunktion "self.on_delete_event" aufgerufen. Als ersten Parameter erhält diese Funktion jetzt das widget, welches das signal ausgesendet hat, in diesem Falle "fenster".


Für connect_object nehme ich jetzt mal dein Beispiel:

Code: Alles auswählen

button.connect_object("clicked", gtk.Widget.destroy, fenster)
Hier passiert folgendes:
Sobald der Benutzer den Button "button" anklickt, sendet dieser das Signal "clicked" aus. Weil du dieses Signal bereits mit einer Funktion verbunden hast, wird hier als Callbackfunktion "gtk.Widget.destroy" aufgerufen.
Jedoch wird dieser Funktion als erster Parameter nicht "button" übergeben (wie es der Fall wäre, wenn du statt connect_object einfach connect genommen hättest), sondern das entsprechende "gobject", dass du als zweiten Parameter bei connect_object angegeben hast.
In diesem Fall lautet der erste Parameter, der der Callbackfunktion übergeben wird also "fenster".


Hier findest du nochmal eine kurze Erklärung mit Beispielen:
http://www.pygtk.org/pygtk2reference/cl ... t--connect
herakli
User
Beiträge: 9
Registriert: Dienstag 8. August 2006, 21:30

Donnerstag 17. August 2006, 09:12

Hallo,
erstmal vielen Dank für die ausführliche Antwort. Ich denk, jetzt hab ich ungefähr verstanden, wie es funktioniert. Dennoch ist bei meinen Ausflügen ins pygtk wieder ein neues Problem im Zusammenhang mit Signalen aufgetaucht:

Code: Alles auswählen

self.window.connect("destroy", lambda wid: gtk.main_quit())
self.window.connect("delete_event", lambda a1,a2: gtk.main_quit())
Mit lambda hatte ich bisher nicht viel zu tun. Ich weiß nur, dass man mit ihnen Funktionsdefinitionen erstellen kann, also z.B.

Code: Alles auswählen

f = lambda x,y : x+y
f(1,2) == 3
Man kann im obigen Aufruf einfach gtk.main_quit für den lambda-Ausdruck schreiben und es funktioniert. Wieso verwendet man aber nun lambda-Ausdrücke? Was passiert hier konkret? Und weshalb tauchen bei 'delete_event' zwei 'lambda-Argumente' auf, bei destroy aber nur einer? (Wahrscheinlich hängt das damit zusammen, dass bei event-handlern, parameter für widget und event, bei signal-handlern aber nur ein Parameter für widget benötigt werden.)
mfg
BlackJack

Donnerstag 17. August 2006, 09:44

Bei den Lambda-Funktionen in Deinem Beispiel werden die Parameter ignoriert. Wenn Du im ersten Fall nur `gtk.main_quit` benutzt dann wird es später mit dem Widget als Argument aufgerufen. Die Lambda-Funktion bekommt auch diese Widget, ruft `gtk.main_quit()` dann aber ohne Argumente auf.
Vortex
User
Beiträge: 16
Registriert: Sonntag 13. August 2006, 14:12
Kontaktdaten:

Donnerstag 17. August 2006, 13:11

Wie würde es dann richtig lauten?

So:

Code: Alles auswählen

self.window.connect("destroy", lambda wid: gtk.main_quit) 
oder so:

Code: Alles auswählen

self.window.connect("destroy", lambda wid: gtk.main_quit(wid)) 
?

Hab das mit diesem lambda eh nie verstanden. Wozu braucht man die denn eigentlich? Man kann doch einfach eine neue Funktion schreiben. :?:
BlackJack

Samstag 19. August 2006, 10:16

Vortex hat geschrieben:Wie würde es dann richtig lauten?
Wieso? War's denn bisher falsch?
So:

Code: Alles auswählen

self.window.connect("destroy", lambda wid: gtk.main_quit) 
Das gibt beim "destroy" die `gtk.main_quit` Funktion zurück und ruft sie nicht auf.
oder so:

Code: Alles auswählen

self.window.connect("destroy", lambda wid: gtk.main_quit(wid)) 
Hier ist das ``lambda`` überflüssig, man hätte gleich `gtk.main_quit` dafür schreiben können.
Hab das mit diesem lambda eh nie verstanden. Wozu braucht man die denn eigentlich? Man kann doch einfach eine neue Funktion schreiben. :?:
Man *muss* dann immer neue Funktionen schreiben und sich Namen dafür ausdenken.

Code: Alles auswählen

def quitter(widget):
    gtk.main_quit()

self.window.connect("destroy", quitter)
Antworten