2011-07-01 20 views

Odpowiedz

50

Dodaj ciąg Tkinter StringVar do widgetu Entry. Powiąż swoje wywołanie zwrotne z StringVar, używając metody śledzenia.

from Tkinter import * 

def callback(sv): 
    print sv.get() 

root = Tk() 
sv = StringVar() 
sv.trace("w", lambda name, index, mode, sv=sv: callback(sv)) 
e = Entry(root, textvariable=sv) 
e.pack() 
root.mainloop() 
+0

Doskonale, dzięki! – bfops

+0

Twoje rozwiązanie nie działa z komponentem "self". – Nicholas

+0

@Nicholas: Próbka kodu działa tak jak jest. Czego brakuje? –

8

Dzięki Steven! Tkinter Folklore Russella Owena wyjaśnia, jak uzyskać wartość StringVar bezpośrednio z argumentu name (PY_VAR #) za pomocą globalgetvar(), ale nie w jaki sposób zamapować nazwę na widget. Twoja metoda lambda zmiany argumentów callback jest jak magia (przynajmniej dla początkujących Pythona).

W przypadku więcej niż jednego wpisu często konieczne jest poznanie nie tylko wartości, ale także tego, która pozycja została zmieniona. Rozszerzając nieco przykład Stevena, poniższy (Python3) przekazuje indeks, który może być używany do śledzenia wielu wpisów.

from tkinter import Tk, Frame, Label, Entry, StringVar 

class fruitlist: 
    def entryupdate(self, sv, i): 
     print(sv, i, self.fruit[i], sv.get()) 

    def __init__(self, root): 
     cf = Frame(root) 
     cf.pack() 
     self.sva = [] 
     self.fruit = ("Apple", "Banana", "Cherry", "Date") 
     for f in self.fruit: 
      i = len(self.sva) 
      self.sva.append(StringVar()) 
      self.sva[i].trace("w", lambda name, index, mode, var=self.sva[i], i=i: 
           self.entryupdate(var, i)) 
      Label(cf, text=f).grid(column=2, row=i) 
      Entry(cf, width=6, textvariable=self.sva[i]).grid(column=4, row=i) 

root = Tk() 
root.title("EntryUpdate") 
app = fruitlist(root) 
root.mainloop() 
6

W momencie pisania (2017, Python 3.6, wersja 8.6.6 tkinter) docs sugerują, że .trace jest przestarzała. Sugerowany formularz wydaje się teraz być:

sv.trace_add("write", callback) 

Działa to bardzo dobrze, jeśli chcesz otrzymywać powiadomienia o każdej zmianie zmiennej. Jednak moja aplikacja chce tylko powiadomienia, gdy użytkownik zakończy edycję tekstu. Znalazłem świnka poparcie na „walidacji” mechanizm działa dobrze tutaj:

from tkinter import * 

root = Tk() 
sv = StringVar() 

def callback(): 
    print(sv.get()) 
    return True 

e = Entry(root, textvariable=sv, validate="focusout", validatecommand=callback) 
e.grid() 
e = Entry(root) 
e.grid() 
root.mainloop() 

To wywoła callback gdy widget wpis traci fokus (dodałem widget 2nd wejścia więc 1st można rzeczywiście stracić skupić!)

0

znam inny wariant. przed i wprowadzić kod, to może lepiej wyjaśnić ścieżkę kodowania: trzcina tutaj http://stupidpythonideas.blogspot.com/2013/12/tkinter-validation.html?view=classic

i tam jest mój kod:

from Tkinter import * 
 

 
class ttt: 
 
    def __init__(self): 
 
     self.str1 = StringVar() 
 
     self.e1 = Entry(root, textvariable=self.str1) 
 
     self.str1.trace('w', self.callback_1) 
 
     self.e1.pack() 
 
     
 
     self.str2 = StringVar() 
 
     self.e2 = Entry(root, textvariable=self.str2, state='readonly') 
 
     self.e2.pack() 
 
     
 
     self.str3 = StringVar() 
 
     self.e3 = Entry(root, textvariable=self.str3, state='readonly') 
 
     self.e3.pack() 
 
     
 
     bt = Button(root, text = 'ещё', command = self.callback_2) 
 
     bt.pack() 
 
    
 
    def callback_1(self, name='', index='', mode=''): 
 
     tmp = self.str1.get() 
 
     if tmp: 
 
     self.str2.set(int(tmp) * 6) 
 
     print self.str2.get() 
 
    
 
    def callback_2(self, name='', index='', mode=''): 
 
     tmp = self.str1.get() 
 
     if tmp: 
 
     self.str3.set(int(tmp) * 6) 
 
     print self.str3.get() 
 

 
root = Tk() 
 
t = ttt() 
 
root.mainloop()

jest 2 wariant: przez nacisnąć przycisk i wprowadź do wpisu. teraz możesz wybrać dowolny wariant

Powiązane problemy