Tkinter: catturare testo Entry senza bottone
Voglio catturare il testo all’interno di una Entry, mentre lo scrivo.
Ovviamente non voglio fare come su tutte le guide, dove viene utilizzato
un bottone per la cattura.
Voglio fare il bind a
Probabilmente esiste un metodo più elegante di questo,
ma il codice seguente fa il suo lavoro.
import Tkinter as tk import ttk CHARS = 'abcdefghijklmnopqrstuvwxyz1234567890' CENTER = tk.N + tk.S + tk.W + tk.E class ViewTH: def __init__(self): self.root = tk.Tk() self.frame = tk.Frame(self.root) self.frame.pack(fill=tk.BOTH) self.en_cod = tk.Entry(self.frame) self.en_cod.grid(sticky=CENTER, row=0, column=0, padx=2, pady=2) btn_quit = tk.Button(self.frame, text='Quit', command=self.root.destroy) btn_quit.grid(sticky=CENTER, row=1, column=0, padx=2, pady=2) self.en_cod.bind('<KeyPress>', func=self.on_entry) self.en_cod.focus_set() def on_entry(self, event): text = self.en_cod.get() char = event.keysym index = self.en_cod.index(tk.INSERT) if not text: string = char else: if char in CHARS + CHARS.upper(): string = text + char elif char == 'BackSpace': if index == 0: string = text else: string = text[ :index - 1] + text[index: ] elif char == 'Delete': string = text[ :index] + text[index + 1: ] else: string = text print string def start(self): self.root.mainloop() if __name__ == '__main__': vth = ViewTH() vth.start()
In pratica nella callback on_entry, richiamata ad ogni pressione di un tasto all’interno della
Entry, effettuo questi controlli:
…e se il tasto premuto, è il primo della sequenza, lo utilizzo per ottenere il primo
carattere, che altrimenti verrebbe saltato dal metodo get().
... def on_entry(self, event): text = self.en_cod.get() char = event.keysym index = self.en_cod.index(tk.INSERT) if not text: string = char
poi controllo che il carattere premuto (event.symkey), faccia parte di quelli consentiti
(CHARS)
... else: if char in CHARS + CHARS.upper(): string = text + char ... else: string = text
In più nelle condizioni elif gestisco i casi di ‘BackSpace’ e ‘Delete’,
richiamando l’indice posizionale del cursore all’interno della Entry,
per ottenere il testo corretto in caso di cancellazione caratteri
(soprattutto nel mezzo della stringa).
index = self.en_cod.index(tk.INSERT)
Tutti gli altri tasti non alfanumerici non li considero.
Nel caso comunque premessi ‘Home’ e di seguito ‘BackSpace’, gestirei la stringa all’interno di
questo if/else:
elif char == 'BackSpace': if index == 0: string = text else: string = text[ :index - 1] + text[index: ]
…poi è chiaro che con un Button ed una callback che al proprio interno richiami il
metodo get() della Entry ed il testo al suo interno, sarebbe tutto molto più facile,
ma più brutto.
Commenti recenti