Tkinter/ ttk focus mit bindings setzen

Fragen zu Tkinter.
Antworten
ll9
User
Beiträge: 34
Registriert: Samstag 9. Februar 2013, 15:13

Hallo,

ich bin grad auf ein Problem in Tkinter bzw. in ttk gestoßen. Undzwar gelingt es mir nicht, mit bind() den focus neu zu setzen. Hört sich vielleicht kompliziert an, ich gebe mal ein Beispiel.

Code: Alles auswählen

from Tkinter import *
import ttk

root = Tk()

var1 = StringVar()
var2 = StringVar()

entry1 = ttk.Entry(root, textvariable = var1)
entry2 = ttk.Entry(root, textvariable = var2)
entry1.bind('<Return>', entry2.focus_set)
entry1.grid()
entry2.grid()
entry1.focus()

root.mainloop()
Ich will, dass wenn man bei entry1 mit Enter bestätig der focus auf entry2 übergeht. Ich krieg aber nur diesen Fehler:
TypeError: focus_set() takes exactly 1 argument (2 given)
Wenn ich den Code so umändere funktioniert alles.

Code: Alles auswählen

from Tkinter import *
import ttk

root = Tk()

var1 = StringVar()
var2 = StringVar()

entry1 = ttk.Entry(root, textvariable = var1)
entry2 = ttk.Entry(root, textvariable = var2)

def change_focus(event):
    entry2.focus_set()
    
entry1.bind('<Return>', change_focus)
entry1.grid()
entry2.grid()
entry1.focus()

root.mainloop()
Das kann aber nicht sein, dass ich dafür eine extra Funktion brauche oder? Könnt ihr mir vielleicht sagen, wie ich das Binding im ersten Beispiel zum laufen bringen kann?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo,

für solche Spezialfälle kannst du Lambda-Ausdrücke verwenden:

Code: Alles auswählen

entry1.bind('<Return>', lambda event: entry2.focus_set)
Schau dazu am besten mal in die Dokumentation, dann verstehst du was genau passiert.

Noch eine Anmerkung zu deinem Code: vermeide *-Importe. Damit müllst du dir nur den ganzen Namensraum zu, kannst beim Lesen des Codes nicht erkennen von wo die Namen kommen und die Gefahr von versehentlichen Namenskonflikten ist extrem hoch. Bei Tkinter ist es üblich, dass Moduls mittels ``import Tkinter as tk`` zu importieren. Auf die Namen des Moduls kannst du dann qualifiziert mittels ``tk.StringVar`` oder ``tk.Entry`` zugreifen.
Das Leben ist wie ein Tennisball.
ll9
User
Beiträge: 34
Registriert: Samstag 9. Februar 2013, 15:13

Danke EyDu,

dass mit lambda wusste ich schon, ich hab nur selbst vergessen, dass man da noch 'event' dazu schreiben muss. Dein Tipp hat mir sehr geholfen.
Jedoch ist dir glaube ich noch ein kleiner Fehler unterlaufen.

Code: Alles auswählen

entry1.bind('<Return>', lambda event: entry2.focus_set)
So tut sich nämlich nichts, kommt aber auch keine Fehlermeldung.

Code: Alles auswählen

entry1.bind('<Return>', lambda event: entry2.focus_set())
Mit den Klammern am Ende geht's dann. Danke für deine Hilfe.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Die Klammern habe ich doch nicht vergessen, sonder dir als Übung zu Fehlersuche überlassen ;-) Gut, vielleicht habe ich auch einfach nicht dran gedacht :D
Das Leben ist wie ein Tennisball.
Antworten