Bind von Return-Taste und Button command

Fragen zu Tkinter.
Antworten
Pete
User
Beiträge: 7
Registriert: Freitag 18. März 2011, 00:20

Hi zusammen,
ich schreibe gerade an der Software für ein wissenschaftliches Experiment. Dabei erheben wir auch die Reaktionszeit. Nun habe ich eine alte Version des Programms übernommen, jedoch müssen die Versuchspersonen dort nach Eingabe auf "OK"-Klicken, was natürlich die Reaktionszeitmessungen verunreinigt.
Der relevante Teil des Programms, clientseitig, sieht etwa so aus:

Code: Alles auswählen

while 1:
        if
        ....
        elif data == "@end \n":
            root.focus_set()
            button.config(state = NORMAL)
            entry.destroy()
            entry = Entry(root, width=12, font = ("Helvetica", "20"))
            entry.insert(0, "$")
            entry.pack()
            root.mainloop()
            str = entry.get()
            entry.delete(0, END)
            root.update()
            sock.send(str[:+10] + " \n")
Dabei sind button, entry & root ziemlich simpel festgelegt als:

Code: Alles auswählen

root = Tk()
entry = Entry(root)
def buttonCommand():
    root.quit()
button = Button(root, text = "OK", command = buttonCommand, font = "Helvetica, 20")
button.pack()
Mir ist klar, dass ich mit button.config(state = NORMAL) eine "Aufmerksamkeitsphase" (sorry für das fehlende Fachvokabular, ich bin noch relativ neu :) ) festlege, die die mainloop beendet, sobald auf den Button geklickt wird. Also müsste ich eigentlich nur ein bind("<Return>", root.quit) hinter root.mainloop schreiben und damit sollte nur genau während dieser Phase (wir wollen ja nicht, dass die Versuchspersonen via Return das Programm jederzeit crashen können) das Drücken der Return-Taste zum entry.get() führen.
Am Konjunktiv ist hier natürlich zu bemerken, dass die Praxis leider nur so präzise ist wie die ihr zu Grunde gelegte Theorie. Ich wäre also sehr dankbar über eure Hilfe.

Sonnige Grüße aus Kalifornien
Pete
BlackJack

@Pete: Meintest Du vielleicht das muss *vor* die `mainloop()`? Sonst verstehe ich das Problem nicht so ganz? Und danach könntest Du dann den Button wieder deaktivieren und die Taste mit `unbind()` wieder deaktivieren. Dazu müsstest Du Dir den Rückgabewert von `bind()` merken.
Pete
User
Beiträge: 7
Registriert: Freitag 18. März 2011, 00:20

Hey,
danke für deine schnelle Antwort.
Das Problem ist ganz einfach, dass ich nicht weiß wie ich das binden soll. Denn ein bind("<Return>", button.command) oder Ähnliches funktioniert nicht. Sprich, genauer ist das Problem, ich weiß nicht wie ich das button command aufrufen soll. Wahrscheinlich ist es extrem simpel und ich stehe einfach nur auf dem Schlauch, aber ich komme beim besten Willen nicht drauf.. :/

LG
BlackJack

@Pete: Die Funktion die man bei `bind()` angibt, muss ein Argument erwarten. Du könntest also bei `buttonCommand()` noch ein Argument einführen und dem einen Default-Wert geben und dann die Funktion auch an die Eingabetaste im `Entry` binden. Oder wenn es wirklich nur das `quit()` auf `root` sein soll, könnte man auch eine anonyme Funktion verwenden, also ``id_ = entry.bind('<Return>', lambda _: root.quit())`` vor die `mainloop()` setzen und danach dann ``entry.unbind('<Return>', id_).
Pete
User
Beiträge: 7
Registriert: Freitag 18. März 2011, 00:20

Hi BlackJack,

danke für deine Antwort - das hilft mir schon mal weiter.
Allerdings würde ich gerne nicht die selbst definierte Funktion buttonCommand binden, sondern den im Button-widget implizierten Befehl "command". Sprich, ich würde gerne die gesamte Funktionalität des Klickens auf den Button auf die Return-Taste übernehmen, damit die Versuchspersonen gar nicht erst mit der Maus rumhantieren und die Reaktionszeitmessung verunreinigen. Und da ist das Problem dass ich nicht weiß, wie.

Besten Dank für deine Hilfe!
BlackJack

@Pete: Aber an `command` wird doch die `buttonCommand()`-Funktion gebunden!? Das ist die, die ausgeführt wird, wenn die Schaltfläche betätigt wird. Zumindest sieht das in dem Quelltext so aus, den Du gezeigt hast. Dann musst Du die halt auch in der ``lambda``-Funktion aufrufen.

Falls das `Entry` und der `Button` zusammen gehören und auch visuell zusammen dargestellt werden, würde ich das wohl in einer Klasse kapseln.
Pete
User
Beiträge: 7
Registriert: Freitag 18. März 2011, 00:20

Ha! So wie unser Funktionentheorie-Prof damals immer gesagt hat:
"Kaum macht man's richtig, schon funktioniert's."

Danke für deine Hilfe!
Antworten