まさに質問が言うように。 Text
ウィジェットには<<Modified>>
イベント、ただしEntry
ウィジェットは表示されません。
Tkinter StringVarをエントリウィジェットに追加します。 traceメソッドを使用して、コールバックをStringVarにバインドします。
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()
執筆時点(2017、Python 3.6、tkinterバージョン8.6.6)では、ドキュメントでは.trace
は非推奨です。推奨される形式は次のとおりです。
sv.trace_add("write", callback)
変数が変更されるたびに通知が必要な場合、これは非常にうまく機能します。ただし、私のアプリケーションは、ユーザーがテキストの編集を終了したときに通知を受け取りたいだけです。私はここでうまく機能するための「検証」メカニズムのピギーバッキングを見つけました。
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()
これにより、エントリウィジェットがフォーカスを失うたびにcallback
が呼び出されます(最初のウィジェットが実際にフォーカスを失うことができるように、2番目のエントリウィジェットを追加しました!)
スティーブンありがとう! Russell OwenのTkinter Folkloreは、globalgetvar()を使用して名前引数(PY_VAR#)からStringVar値を直接取得する方法を説明していますが、名前をウィジェットにマップする方法は説明していません。コールバック引数を変更するラムダメソッドは魔法のようなものです(少なくとも、私たちにとってはPython初心者)。
複数のエントリがある場合、値だけでなく、どのエントリが変更されたかを知る必要があることがよくあります。 Stevenの例を少し拡張して、次の(Python3)は、複数のエントリを追跡するために使用できるインデックスを渡します。
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.string_vars = []
self.fruit = ("Apple", "Banana", "Cherry", "Date")
for f in self.fruit:
i = len(self.string_vars)
self.string_vars.append(StringVar())
self.string_vars[i].trace("w", lambda name, index, mode, var=self.string_vars[i], i=i:
self.entryupdate(var, i))
Label(cf, text=f).grid(column=2, row=i)
Entry(cf, width=6, textvariable=self.string_vars[i]).grid(column=4, row=i)
root = Tk()
root.title("EntryUpdate")
app = Fruitlist(root)
root.mainloop()
私は他のバリアントを知っています。
コードを入力する前に、コーディングのパスをよりよく説明できます:read here
私のコードがあります:
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()
2つのバリエーションがあります。ボタンを押して入力することです。今、あなたは任意のバリアントを選択することができます
ユーザーがウィジェットをクリックするたびに発生するKeyReleaseイベントを使用することもできます。
変更よりもフィルターをかけることができます。
from tkinter import *
from tkinter import ttk
class GUI():
def __init__(self):
self.root = Tk()
self.sv = StringVar()
self.prevlaue=''
#entry
self.entry = ttk.Entry(self.root, width=30, textvariable =self.sv)
self.entry.grid(pady=20,padx=20)
self.entry.bind("<KeyRelease>", self.OnEntryClick) #keyup
self.root.mainloop()
def OnEntryClick(self, event):
value=self.sv.get().strip()
changed = True if self.prevlaue != value else False
print(value, 'Text has changed ? {}'.format(changed))
self.prevlaue = value
#create the gui
GUI()
役に立てば幸いです。
Python 3.6を使用し、.traceを機能させることができませんでした。次のコードでは、StringVarのデフォルト値を受け入れたり編集したりできます。
from tkinter import Tk, LEFT, BOTH, StringVar
from tkinter.ttk import Entry, Frame
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Entry")
self.pack(fill=BOTH, expand=1)
self.contents = StringVar()
# give the StringVar a default value
self.contents.set('test')
self.entry = Entry(self)
self.entry.pack(side=LEFT, padx=15)
self.entry["textvariable"] = self.contents
self.entry.bind('<Key-Return>', self.on_changed)
def on_changed(self, event):
print('contents: {}'.format(self.contents.get()))
return True
def main():
root = Tk()
ex = Example(root)
root.geometry("250x100+300+300")
root.mainloop()
if __== '__main__':
main()