我创建了三行文本小部件,其中包含使用'for'循环的四列,如下所示。
我的目标是将每个文本小部件的列值附加到不同的列表中,如list1 =[]
,list2=[]
,list3=[]
和list4=[]
因此,使用Tab键绑定函数并使用lambda
我已将值附加到其特定列表。到目前为止哪个工作正常。
现在的问题是,如果我错误地输入了错误的值(例如第二行第二列中的值 - 764),它也会被添加到列表中,因为'tab'被绑定了。
因为我正在为某些计算目的创建这些列表,这肯定会破坏我的计算。我们不能指望用户毫无错误地进入。
我想要一种方法来清除文本,并在列表中更改它之前存储的值。就像它在文本小部件中被更改一样,它必须在列表中进行更改。
我的代码:
from tkinter import *
list1 = []
list2 = []
list3 = []
list4 = []
def testfunction(var):
print(var)
list1.append(var)
def testfunction2(var):
print(var)
list2.append(var)
def testfunction3(var):
print(var)
list3.append(var)
def testfunction4(var):
print(var)
list4.append(var)
root = Tk()
for _ in range(3):
t = StringVar()
t1 = IntVar()
t2 = IntVar()
t3 = IntVar()
ent = Entry(root, textvariable=t)
ent.bind("<Tab>",(lambda event, ent=ent:testfunction(ent.get())))
ent.grid(row=_, column=0)
ent2 = Entry(root, textvariable=t1)
ent2.bind("<Tab>",(lambda event, ent2=ent2:testfunction2(ent2.get())))
ent2.grid(row=_, column=1)
Rat = Entry(root, textvariable=t2)
Rat.bind("<Tab>",(lambda event, Rat=Rat:testfunction3(Rat.get())))
Rat.grid(row=_, column=2)
amt = Entry(root, textvariable=t3)
amt.bind("<Tab>",(lambda event, amt=amt:testfunction4(amt.get())))
amt.grid(row=_, column=3)
root.mainloop()
答案 0 :(得分:2)
我建议您使用tkinter.Entry
小部件而不是tkinter.Text
。
这些参数支持textvariable
可选参数,该参数可以接收变量,然后可以跟踪该变量。
该变量是tkinter.Variable
类的实例。
更确切地说,它将是tk.StringVar
类中的一个,它扩展了前者。
它将为我们提供条目内容的处理:它将始终自动更新,以保存当前输入的值。
所以我在这里:首先,我创建一个变量矩阵和一个条目矩阵。 为了简单和清晰起见,我选择向您展示详细而明确的版本,而不是嵌套列表推导。
import tkinter as tk
root = tk.Tk()
variables = []
for i in range(3):
row = []
for j in range(4):
variable = tk.StringVar()
row.append(variable)
variables.append(row)
entries = []
for i in range(3):
row = []
for j in range(4):
entry = tk.Entry(root, textvariable=variables[i][j])
entry.grid(row=i, column=j)
row.append(entry)
entries.append(row)
此时,我们可以调用root.mainloop()
,并观察您生成的条目网格。
现在,让我们定义一个get_values
函数:它将帮助我们获取条目的输入。
可以通过tkinter.Variable
方法访问tkinter.Variable.get
实例包装的值。
def get_values():
values = []
for j in range(4):
column = []
for i in range(3):
column.append(entries[i][j].get())
values.append(column)
return values
最后,让我们创建一个按钮,以便我们打印当前值:
button = tk.Button(root, text="Print values", command=lambda: print(get_values()))
button.grid(row=3, column=0, columnspan=4)
现在,让我们打电话给root.mainloop()
,看看会发生什么。
我们有一个条目矩阵,带有Print values
按钮:
现在,如果我们输入一些文字然后点击Print values
:
以下是控制台中的内容:
[['hello', '', ''], ['', 'stuff', ''], ['', '', 'blah'], ['foo', '', '']]
在每一刻,不仅在按下按钮时,get_values
功能都会返回条目矩阵的当前内容。
正如我所说,它会自动保持最新,所以你不必担心绑定。
显而易见的优点是,用户不必按特定顺序键入输入,也不会通过按Tab键强制切换条目。
修改强>
现在,您要在第四列中显示column 2
次column 3
的结果。
由于我们已经掌握了条目变量,因此编辑文本非常直接。
我们所要做的就是通过tk.Variable.trace
方法跟踪正在编辑的条目的事件。
我首先定义一个build_callback
函数,它将两个源单元格的变量和目标单元格的变量作为参数。
def build_trace(source1, source2, target):
def callback(*_):
value1 = source1.get()
value2 = source2.get()
try:
value1 = float(value1)
value2 = float(value2)
target.set(value1*value2)
except:
target.set("")
return callback
这会创建一个回调,它获取两个源单元格的值,尝试将它们转换为浮点数,然后将它们写入目标的变量中。
Tkinter的变量是这样的:如果为窗口小部件提供了变量,那么对后者的写入访问将导致前者的视觉变化。
因此,target.set(value1*value2)
不仅会设置target
变量的内部值,还会使关联的条目显示新值。
现在,我们需要告诉tkinter在修改其中一个单元格时调用正确的回调。 这很容易,但我们需要注意指数:
for i in range(3):
variables[i][1].trace(
'w',
build_trace(variables[i][1], variables[i][2], variables[i][3]))
variables[i][2].trace(
'w',
build_trace(variables[i][1], variables[i][2], variables[i][3]))
那是什么意思?
这告诉tkinter,只要写variables[i][1]
('w'
),就应该执行回调build_trace(variables[i][1], variables[i][2], variables[i][3])
。
调用build_trace
函数,其结果作为第二个参数传递。
此结果是内部callback
函数。
由于回调是用一些我们并不真正关心的参数调用的,我只是通过定义callback(*_)
来吸收它们,这基本上意味着“接受所有参数,并将它们放在_
中,即在垃圾箱中”
现在你很高兴,对第二列或第三列的任何更改都会导致第四列发生变化。
一些自我宣传,但我认为值得一读: