TKinter:从循环更新Label小部件的文本值

时间:2020-01-03 17:04:31

标签: python tkinter

我刚上了我的第一个python教程,并且正在做一些教程。这是我的第一个练习,我将按照教程提供的方法不同地解决问题。教程具有静态显示功能,这意味着它将同一行复制并粘贴10倍以显示表格。

但是,我希望它在给定范围内具有更高的动态性,并使用for循环多次显示它。

我尝试了几种编码方式,例如,以与操作显示器相同的功能对显示器进行编码,等等...

在代码中,我还包括“错误检查”以找出每个阶段的值。

但是,一旦代码转到“ LABEL WIDGET”,它呈现的值就是循环的最后一个值,而不是每次迭代时。

有人可以帮助我提供代码,但最重要的是向我解释为什么?似乎与更新“ thisLabel”变量有关的计时问题,也许可以通过延迟它来解决?我不知道如何,但是有更好的方法吗?

from tkinter import *


def clearEntry():
    entryField.delete(0, END)


def showLabel(x):
    labelText.set(x)


# PROBLEM:  Label only renders the last item
def showTableText(x, y, z):
    base = str(x)
    factor = str(y)
    prod = str(z)
    print(base, factor, prod)
    tableText.set(base + "x" + factor + "=" + prod)
    print(tableText.get())
    thisLabel = Label(root, textvariable=tableText)
    thisLabel.pack()


def showTable():
    num = entryField.get()
    showLabel("Multiplication Table of " + num)
    x = int(num)
    for i in range(1, tableRange+1):
        prod = x*i
        print(x, "x", i, "=", prod)
        showTableText(x, i, prod)


root = Tk()

tableRange = 5

labelText = StringVar()
labelText.set("Multiplication Table")

tableText = StringVar()
tableText.set("---")

Label(root, textvariable=labelText).pack()

entryField = Entry(root, bg="yellow", fg="blue", text="Enter number")
entryField.pack()

Button(root, text="CLEAR", command=clearEntry).pack()
Button(root, text="SHOW TABLE", command=showTable).pack()

root.mainloop()

sample output

1 个答案:

答案 0 :(得分:0)

首先需要了解什么是StringVar(),它是TKinter的可变类之一(BooleanVar,DoubleVar,IntVar,StringVar)。变量可与大多数输入小部件一起使用,以跟踪对输入值的更改。每当StringVar,IntVar等值更改时,它们都会使连接到它们的小部件的值发生变化。 (source

因此,在您的情况下,您正在名为tableText的全局变量中创建StringVar,并将其传递给正在创建的所有Lable小部件。在循环内部,您使用方法tableText不断更改函数showTableText中的tableText.set(base + "x" + factor + "=" + prod)值,因此下次在循环中通过“设置”方法更改“ tableText”时,将更改所有先前连接到tableText变量的标签。

要解决此问题,请将全局变量tableText = StringVar()移动到函数showTableText

所以会是这样:

def showTableText(x, y, z):
    base = str(x)
    factor = str(y)
    prod = str(z)
    print(base, factor, prod)
    tableText = StringVar() # Moved tableText to be a local variable inside this function
    tableText.set(base + "x" + factor + "=" + prod)
    print(tableText.get())
    thisLabel = Label(root, textvariable=tableText)
    thisLabel.pack()

那么,您是否想知道为什么现在可以使用? 因为现在在每个循环中,当循环调用showTableText函数时,它将创建StringVar()的新实例。但是,在您的代码中,它是一个全局变量,这意味着它仅创建一次,并且您对所有Lable都使用相同的StringVar实例