Tkinter - 当写入两个 Entry Widget 时触发事件,无论顺序如何
Tkinter - Trigger an event when two Entry Widgets are written into,regardless of order
我一周前才开始 Tkinter,我正在尝试 link GUI 到用 [=33 编写的自动代码生成脚本=]。在这个论坛的大力帮助下,我几乎涵盖了所有案例,但这个特别的案例让我感到难过。
我需要 2 个条目小部件,并在输入它们后立即计算它们之间的关系(即没有按钮小部件来触发功能)。我意识到它必须通过事件来完成,所以经过一些尝试我想出了以下可行的方法,但感觉我并没有 'pythonic' 。
from Tkinter import *
root = Tk()
root.title("Test")
def OnValidate(S):
if S.isdigit():
return True
else:
return False
def insert_text_widg(widg,msg):
widg.delete(1.0,END)
widg.insert(INSERT,msg)
# Checks the required conditions
def check_var1(event):
try:
temp1=int(var1_ent.get())
temp2=int(var2_ent.get())
except ValueError:
return
if(temp2 > temp1):
insert_text_widg(log_text,"ERROR: Var2 cannot be greater than Var1")
for ent in [var1_ent,var2_ent]:
ent.configure(bg='indian red',fg='white')
elif ((temp1 - temp2) % 2) == 1:
insert_text_widg(log_text,"ERROR: Difference cannot be odd")
for ent in [var1_ent,var2_ent]:
ent.configure(bg='indian red',fg='white')
else:
log_text.delete(1.0,END)
for ent in [var1_ent,var2_ent]:
ent.configure(bg='white',fg='black')
# Duplicate of check_var1
def check_var2(event):
try:
temp2=int(var2_ent.get())
temp1=int(var1_ent.get())
except ValueError:
return
if(temp2 > temp1):
for ent in [var1_ent,var2_ent]:
ent.configure(bg='indian red',fg='white')
insert_text_widg(log_text,"ERROR: Var2 cannot be greater than Var1")
elif ((temp1 - temp2) % 2) == 1:
for ent in [var1_ent,var2_ent]:
ent.configure(bg='indian red',fg='white')
insert_text_widg(log_text,"ERROR: Difference cannot be odd")
else:
log_text.delete(1.0,END)
for ent in [var1_ent,var2_ent]:
ent.configure(bg='white',fg='black')
# App Configuration
vcmd = (root.register(OnValidate),'%S')
var1_lab = Label(root,text='Var1 :')
var1_lab.pack()
var1_ent = Entry(root,validate="key",validatecommand=vcmd)
var1_ent.bind("<KeyRelease>",check_var1)
var1_ent.pack()
var2_lab = Label(root,text='Var2 :')
var2_lab.pack()
var2_ent = Entry(root,validate="key",validatecommand=vcmd)
var2_ent.bind("<KeyRelease>",check_var2)
var2_ent.pack()
log_text = Text(root)
log_text.pack()
root.mainloop()
有两个函数 (check_var1() & check_var2()) 基本上做同样的事情,我希望合并成一个.
一旦任何条目小部件注册更改,就需要执行检查。
所以简而言之,我想要一种方法来调用 check_var1() 函数,只要输入任何一个 Entry 小部件,无论顺序如何他们是输入的。
任何正确方向的帮助或推动将不胜感激。
如果我正确理解了您的需求,那么在我看来您最好使用 .trace()
函数。
这允许您在写入或读取变量时引发回调。
在这种情况下,我们将创建两个变量 var1
和 var2
(为简单起见)并将它们分配给 StringVar()
.
的值
然后我们将每个 Entry
小部件的属性 textvariable
分别设置为 var1
和 var2
。
然后我们需要设置 .trace()
本身,所以我们调用 var1.trace("w", callback)
和 var2.trace("w", callback)
(其中 "w"
表示写入),它会在每次运行回调函数写入任一变量的时间。
这意味着无论先修改哪个Entry
,我们都会得到一个回调,更重要的是我们每次修改都会得到一个回调。
请参阅下面的工作示例:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.var1 = StringVar()
self.var2 = StringVar()
self.var1.trace("w", self.callback)
self.var2.trace("w", self.callback)
self.entry1 = Entry(self.root, text="Ok", textvariable=self.var1)
self.entry2 = Entry(self.root, text="Ok", textvariable=self.var2)
self.label = Label(self.root)
self.entry1.pack()
self.entry2.pack()
self.label.pack()
def callback(self, *args):
self.label.configure(text=self.entry1.get()+self.entry2.get())
root = Tk()
App(root)
root.mainloop()
我一周前才开始 Tkinter,我正在尝试 link GUI 到用 [=33 编写的自动代码生成脚本=]。在这个论坛的大力帮助下,我几乎涵盖了所有案例,但这个特别的案例让我感到难过。
我需要 2 个条目小部件,并在输入它们后立即计算它们之间的关系(即没有按钮小部件来触发功能)。我意识到它必须通过事件来完成,所以经过一些尝试我想出了以下可行的方法,但感觉我并没有 'pythonic' 。
from Tkinter import *
root = Tk()
root.title("Test")
def OnValidate(S):
if S.isdigit():
return True
else:
return False
def insert_text_widg(widg,msg):
widg.delete(1.0,END)
widg.insert(INSERT,msg)
# Checks the required conditions
def check_var1(event):
try:
temp1=int(var1_ent.get())
temp2=int(var2_ent.get())
except ValueError:
return
if(temp2 > temp1):
insert_text_widg(log_text,"ERROR: Var2 cannot be greater than Var1")
for ent in [var1_ent,var2_ent]:
ent.configure(bg='indian red',fg='white')
elif ((temp1 - temp2) % 2) == 1:
insert_text_widg(log_text,"ERROR: Difference cannot be odd")
for ent in [var1_ent,var2_ent]:
ent.configure(bg='indian red',fg='white')
else:
log_text.delete(1.0,END)
for ent in [var1_ent,var2_ent]:
ent.configure(bg='white',fg='black')
# Duplicate of check_var1
def check_var2(event):
try:
temp2=int(var2_ent.get())
temp1=int(var1_ent.get())
except ValueError:
return
if(temp2 > temp1):
for ent in [var1_ent,var2_ent]:
ent.configure(bg='indian red',fg='white')
insert_text_widg(log_text,"ERROR: Var2 cannot be greater than Var1")
elif ((temp1 - temp2) % 2) == 1:
for ent in [var1_ent,var2_ent]:
ent.configure(bg='indian red',fg='white')
insert_text_widg(log_text,"ERROR: Difference cannot be odd")
else:
log_text.delete(1.0,END)
for ent in [var1_ent,var2_ent]:
ent.configure(bg='white',fg='black')
# App Configuration
vcmd = (root.register(OnValidate),'%S')
var1_lab = Label(root,text='Var1 :')
var1_lab.pack()
var1_ent = Entry(root,validate="key",validatecommand=vcmd)
var1_ent.bind("<KeyRelease>",check_var1)
var1_ent.pack()
var2_lab = Label(root,text='Var2 :')
var2_lab.pack()
var2_ent = Entry(root,validate="key",validatecommand=vcmd)
var2_ent.bind("<KeyRelease>",check_var2)
var2_ent.pack()
log_text = Text(root)
log_text.pack()
root.mainloop()
有两个函数 (check_var1() & check_var2()) 基本上做同样的事情,我希望合并成一个. 一旦任何条目小部件注册更改,就需要执行检查。
所以简而言之,我想要一种方法来调用 check_var1() 函数,只要输入任何一个 Entry 小部件,无论顺序如何他们是输入的。
任何正确方向的帮助或推动将不胜感激。
如果我正确理解了您的需求,那么在我看来您最好使用 .trace()
函数。
这允许您在写入或读取变量时引发回调。
在这种情况下,我们将创建两个变量 var1
和 var2
(为简单起见)并将它们分配给 StringVar()
.
然后我们将每个 Entry
小部件的属性 textvariable
分别设置为 var1
和 var2
。
然后我们需要设置 .trace()
本身,所以我们调用 var1.trace("w", callback)
和 var2.trace("w", callback)
(其中 "w"
表示写入),它会在每次运行回调函数写入任一变量的时间。
这意味着无论先修改哪个Entry
,我们都会得到一个回调,更重要的是我们每次修改都会得到一个回调。
请参阅下面的工作示例:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.var1 = StringVar()
self.var2 = StringVar()
self.var1.trace("w", self.callback)
self.var2.trace("w", self.callback)
self.entry1 = Entry(self.root, text="Ok", textvariable=self.var1)
self.entry2 = Entry(self.root, text="Ok", textvariable=self.var2)
self.label = Label(self.root)
self.entry1.pack()
self.entry2.pack()
self.label.pack()
def callback(self, *args):
self.label.configure(text=self.entry1.get()+self.entry2.get())
root = Tk()
App(root)
root.mainloop()