当我们在tkinter的Text小部件中清除它时,如何从列表中删除一个值?

时间:2017-09-14 04:24:41

标签: python python-3.x tkinter

我创建了三行文本小部件,其中包含使用'for'循环的四列,如下所示。 enter image description here

我的目标是将每个文本小部件的列值附加到不同的列表中,如list1 =[]list2=[]list3=[]list4=[]

因此,使用Tab键绑定函数并使用lambda我已将值附加到其特定列表。到目前为止哪个工作正常。 enter image description here

enter image description here



现在的问题是,如果我错误地输入了错误的值(例如第二行第二列中的值 - 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()

1 个答案:

答案 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按钮:

entries matrix

现在,如果我们输入一些文字然后点击Print values

Inputing values

以下是控制台中的内容:

[['hello', '', ''], ['', 'stuff', ''], ['', '', 'blah'], ['foo', '', '']]

在每一刻,不仅在按下按钮时,get_values功能都会返回条目矩阵的当前内容。 正如我所说,它会自动保持最新,所以你不必担心绑定。 显而易见的优点是,用户不必按特定顺序键入输入,也不会通过按Tab键强制切换条目。

修改

现在,您要在第四列中显示column 2column 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(*_)来吸收它们,这基本上意味着“接受所有参数,并将它们放在_中,即在垃圾箱中”

现在你很高兴,对第二列或第三列的任何更改都会导致第四列发生变化。

一些自我宣传,但我认为值得一读: