Tkinter: Problem mit *.bind("<Leave>", ...)

Fragen zu Tkinter.
Antworten
MightyJ

Hallo zusammen!

Ich habe folgendes Problem:

Für meine Programm habe ich eine Eingabemaske, in der ich die wichtigen Daten eingeben kann. Unter anderem verwende ich auch ein OptionMenu. Je nachdem, wie ich den Wert in diesem OptionMenu setze, sollen andere Werte automatisch gesetzt werden. Darum dachte ich mir, dass ich das OptionMenu mit bind("<Leave>", ...) verbinde. Das funktioniert ja auch soweit. Nur ruft er die definierte Funktion schon auf, bevor etwas ausgewählt wurde und damit das OptionMenu verlassen wird :-( Somit weiß ich in der aufgerufenen Funktion logischerweise auch noch nicht, was ausgewählt wurde und kann die anderen Werte nicht korrekt setzen :-(

Hat jemand vielleicht eine Idee, wie ich das lösen kann, so dass die Funktion wirklich erst dann aufgerufen wird, wenn in dem OptionMenu etwas ausgewählt wurde?

Danke schon mal im Voraus :-)

MfG
MightyJ
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo MightyJ

Kannst du vielleicht ein wenig Code von deinem Projekt
präsentieren?

Gruss wuf :wink:
Take it easy Mates!
MightyJ

Definition des OptionMenu's:

Code: Alles auswählen

omProdukte = OptionMenu(self.clientArea, self.vars[field],
                        gi_festprod["LFNR"][0]+": "+gi_festprod["PRODBEZ"][0],
                        gi_festprod["LFNR"][1]+": "+gi_festprod["PRODBEZ"][1],
                        gi_festprod["LFNR"][2]+": "+gi_festprod["PRODBEZ"][2],
                        gi_festprod["LFNR"][3]+": "+gi_festprod["PRODBEZ"][3])
omProdukte.grid(row = row, column = 1, sticky = W)
omProdukte.bind("<Leave>", self.on_leave_produkte)
Funktion "on_leave_produkte":

Code: Alles auswählen

def on_leave_produkte(self, event):
    produkt = self.vars["Produktnummer"].get()
    produktnr = Ermittlungen.welchesProdukt(self, produkt)
    if self.vars["zentraler Postversand"].get() == "":
        self.vars["zentraler Postversand"].set(gi_festprod["POSY"][produktnr])
In der Funktion "welchesProdukt" wird nur die Produktnummer ermittelt. Sie gibt momentan, da ich ja leider noch nicht den richtigen Wert ermitteln kann, eine 0 zurück.
Der Wert für den zentralen Postversand wird bei mir jetzt momentan, insofern er noch nicht gesetzt ist, immer schon dann gesetzt, wenn ich das OptionMenu angeklickt habe, um dort einen Wert auszuwählen.
Ich hoffe, dass Dir/Euch das an Code reicht, wollte jetzt auch nicht mein ganzes Projekt hier posten ;-)
Falls ihr noch mehr braucht, einfach Bescheid sagen :-)
Würde mich freuen, wenn mir jemand helfen kann :-)

MfG
MightyJ
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo MigthyJ

Hier ist meine Variante der Menuauswahl.
Meine vorgehensweise ist zuerst Produkt-
nummer auswählen und dann mit der 'OK'
Schaltfläche bestätigen. In der Funktion
ok() kannst du nach deinem Willen noch
andere Aktionen auslösen.

Eventuell habe ich dich missverstanden?

Code: Alles auswählen

from Tkinter import *

root = Tk()

def ok():
    print "Das gewählte Produkt = ", produkt.get()
    root.quit()

produkt = StringVar()

# Option für die Initialisierung
produkt.set("Produkt-1")

option = OptionMenu(root, produkt, "Produkt-1", "Produkt-2", "Produkt-3", "Produkt-4")
option.pack()

# Schaltfläche für die Übernahme der Auswahl und verlassen des Options-Menue
button = Button(text="OK", command=ok)
button.pack()

root.mainloop()
Gruss wuf :wink:
Take it easy Mates!
MightyJ

Hallo wuf!

Erstmal vielen Dank für dein Hilfe.

So wie du es geschildert hast, wäre es auf jeden Fall eine Möglichkeit, da hab ich auch schon dran gedacht. Leider geht das aber in meinem Fall nicht, zumindest nicht ohne einen zusätzlichen Dialog :-(

Ich habe in meiner Eingabemaske zwar auch einen OK-Button, aber dieser dient dazu, auf die nächste Seite, die Bestätigungsseite, zu wechseln. Durch das Klicken auf meinen OK-Button wird also überprüft, ob alle Felder gefüllt sind und die Werte plausibel.

Durch die Auswahl in dem OptionMenu möchte ich einige Felder meiner Eingabemaske mit anderen Werten vorbelegen, was praktisch unmittelbar nach dem Anklicken des Produkts passieren muss und aufgrund ober genannter Funktionalität des OK-Buttons nicht mit in diesen integriert werden kann.

Die einzige Möglichkeit, die ich mir dann noch vorstellen könnte, wäre entweder in das OptionMenu einen Button einzubauen, oder eben für die Auswahl des Produkts einen eigenen kleinen modalen Dialog zu schreiben, den man dann mit OK bestätigen muss. Dass man allerdings einen Button in ein OptionMenu einbauen kann, habe ich noch nie gesehen und wird wohl auch nicht gehen vermute ich, oder?

Naja, wahrscheinlich werde ich mir dann noch einen solchen Dialog schreiben, da die Auswahl des Produkts der wichtigste Punkt der Eingabemaske ist.

Noch mal danke...

MfG
MightyJ
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo MigthyJ

Hast du es schon einmal mit der option 'command'
des Options-Menu probiert.

Hier meine frisierte Variante.

Code: Alles auswählen

from Tkinter import *

root = Tk()

def ok():
	# Beendet Option-Menue
    root.quit()

def selection(item):
	# Gibt die selektierte Produktnummer aus
	print 'Selektierte Produktnummer = ',item

produkt = StringVar()

# Option für die Initialisierung
produkt.set("Produkt-1")

# Erzeugt Options-Menue mit vier Produktnummern
option = OptionMenu(root, produkt, "Produkt-1", "Produkt-2", "Produkt-3", "Produkt-4",command=selection)
option.pack()

# Schaltfläche für das Beenden des Options-Menu
button = Button(text="OK", command=ok)
button.pack()

root.mainloop()
Gruss wuf :wink:
Take it easy Mates!
MightyJ

Hallo wuf!

Deine Variante habe ich noch nicht probiert, nein. Vielleicht werde ich das noch mal tun :-)

Ich habe aber eben durch Zufall eine andere Methode entdeckt, die mein Problem auch löst:

Code: Alles auswählen

self.vars[field].trace("w", self.on_leave_produkte)
Durch dieses Konstrukt wird die Methode "on_leave_produkte" immer dann aufgerunfen, wenn ein schreibender Zugriff auf die Variable stattgefunden hat. Und das ist ja prinzipiell genau das, was ich wollte :-)

Danke noch mal für dein Hilfe, aber ich werde es jetzt erstmal so probieren.

MfG
MightyJ
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo MightyJ

In meiner letzten Variante wird die Function
selection() bei jeder Auswahl mit Übergabe des
ausgewählten Item aufgerufen.

Wenn ich fragen darf, wie und wo bist du auf
die Methode:
self.vars[field].trace("w", self.on_leave_produkte)
gestossen?

Ist sie irgendwo in der sehr umfangreichen
Python-Dokumentation auffindbar? Würde mich
sehr interessieren.

Gruss wuf :wink:
Take it easy Mates!
MightyJ

Hallo wuf!

Die Funktion "trace(mode, callback)" gehört zu den Standardfunktionen der Variablenklassen StringVar, IntVar, DoubleVar und BooleanVar. "mode" gibt dabei an, auf was du reagieren willst. "r" steht für lesenden Zugriff, "w" für schreibenden Zugriff und bei "u" wird die in "callback" definierte Methode aufgerufen, wenn die Variable gelöscht wurde.

Nachlesen kannst du das in den Dokumentationen zu den oben genannten Klassen, zum Beispiel auch hier:

http://effbot.org/zone/tkinter-variable.htm

Gefunden habe ich das mehr rein zufällig, als ich gerade auf der Suche nach etwas ganz anderem war (was aber schon mit Python zu tun hatte *gg*). Aber es funzt ja wunderbar :-)

Ich denke, dass es damit klar sein sollte :-)

MfG
MightyJ
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi MightyJ

Alles klar

Besten Dank für deine hilfreiche Mitteilung

Good programming

Gruss wuf :wink:
Take it easy Mates!
Antworten