2013-06-08 4 views
14

Io sono un Python che inizia l'auto-apprendimento, in esecuzione su MacOS.Come si associa il tasto Invio a una funzione in tkinter?

Sto facendo un programma con una GUI di testo parser in Tkinter, in cui si digita un comando in un widget Entry, e ha colpito un widget Button, che innesca il mio parse() funct, ect, la stampa i risultati di un widget Text, stile testo-avventura.

> Circumvent the button

I can't let you do that, Dave.

Sto cercando di trovare un modo per sbarazzarsi della necessità di trasportare il mouse sopra alla Button ogni volta che l'utente invia un comando, ma questo si è rivelato più difficile di quanto pensassi.

Immagino che il codice corretto assomigli a self.bind('<Return>', self.parse())? Ma non so nemmeno dove metterlo. root, __init__, parse() e create_widgets() non lo vogliono.

Per essere chiari, l'unico motivo per cui chiunque dovrebbe entrare nel programma è quello di attivare parse(), quindi non è necessario sposarlo specificamente al widget Entry. Ovunque funzioni, va bene.

In risposta alla 7stud, il formato di base:

from tkinter import * 
import tkinter.font, random, re 

class Application(Frame): 

    def __init__(self, master): 
     Frame.__init__(self, master, ...) 
     self.grid() 
     self.create_widgets() 
     self.start() 


    def parse(self): 
     ... 


    def create_widgets(self): 

     ... 

     self.submit = Button(self, text= "Submit Command.", command= self.parse, ...) 
     self.submit.grid(...) 


root = Tk() 
root.bind('<Return>', self.parse) 

app = Application(root) 

root.mainloop() 

risposta

24

provare a eseguire il seguente programma. Devi solo essere sicuro che la tua finestra ha il focus quando premi Invio - per assicurarti che lo faccia, prima fai clic sul pulsante un paio di volte fino a quando non vedi qualche output, quindi senza fare clic su nessun altro premi Invio.

import tkinter as tk 

root = tk.Tk() 
root.geometry("300x200") 

def func(event): 
    print("You hit return.") 
root.bind('<Return>', func) 

def onclick(): 
    print("You clicked the button") 

button = tk.Button(root, text="click me", command=onclick) 
button.pack() 

root.mainloop() 

Poi basta avere le cose modificare un po 'quando si effettua sia la chiamata button click e hitting Return la stessa funzione - perché la funzione di comando deve essere una funzione che prende alcun argomento, mentre la funzione bind deve essere un funzione che prende un argomento (l'oggetto evento):

import tkinter as tk 

root = tk.Tk() 
root.geometry("300x200") 

def func(event): 
    print("You hit return.") 

def onclick(event=None): 
    print("You clicked the button") 

root.bind('<Return>', onclick) 

button = tk.Button(root, text="click me", command=onclick) 
button.pack() 

root.mainloop() 

Oppure, si può semplicemente rinunciare utilizzando argomento di comando del pulsante e di utilizzare invece bind() per fissare la funzione onclick al pulsante, il che significa che la funzione deve prendere un argomento - proprio come con Ritorno:

import tkinter as tk 

root = tk.Tk() 
root.geometry("300x200") 

def func(event): 
    print("You hit return.") 

def onclick(event): 
    print("You clicked the button") 

root.bind('<Return>', onclick) 

button = tk.Button(root, text="click me") 
button.bind('<Button-1>', onclick) 
button.pack() 

root.mainloop() 

Qui è in un ambiente di classe:

import tkinter as tk 

class Application(tk.Frame): 
    def __init__(self): 
     self.root = tk.Tk() 
     self.root.geometry("300x200") 

     tk.Frame.__init__(self, self.root) 
     self.create_widgets() 

    def create_widgets(self): 
     self.root.bind('<Return>', self.parse) 
     self.grid() 

     self.submit = tk.Button(self, text="Submit") 
     self.submit.bind('<Button-1>', self.parse) 
     self.submit.grid() 

    def parse(self, event): 
     print("You clicked?") 

    def start(self): 
     self.root.mainloop() 


Application().start() 
+0

Sto ricevendo un NameError: self non è definito, utilizzando 'def parse (self, event): ...' e 'root.bind ('', self.parse)', nel frattempo il mio pulsante 'comando = self.parse funziona ancora bene ... – Ghosty

+0

@Ghosty, ho aggiunto altri due esempi. – 7stud

+0

Stai ovviamente utilizzando le classi nel tuo programma, quindi se pubblichi solo la struttura di base delle tue classi (possono essere vuote), posso modificare l'esempio affinché tu possa lavorare in un'impostazione di classe. – 7stud

5

Un'altra alternativa è quella di utilizzare un lambda:

ent.bind("<Return>", (lambda event: name_of_function())) 

codice completo:

from tkinter import * 
from tkinter.messagebox import showinfo 

def reply(name): 
    showinfo(title="Reply", message = "Hello %s!" % name) 


top = Tk() 
top.title("Echo") 
top.iconbitmap("Iconshock-Folder-Gallery.ico") 

Label(top, text="Enter your name:").pack(side=TOP) 
ent = Entry(top) 
ent.bind("<Return>", (lambda event: reply(ent.get()))) 
ent.pack(side=TOP) 
btn = Button(top,text="Submit", command=(lambda: reply(ent.get()))) 
btn.pack(side=LEFT) 

top.mainloop() 

Come si può vedere , la creazione di una funzione lambda con una variabile inutilizzata "evento" risolve il problema.

+0

Il tuo codice utilizza un'immagine esterna 'Iconshock-Folder-Gallery.ico', che probabilmente causerebbe un errore per chiunque la eseguisse. –