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()
解决方案
您首先需要了解什么是 StringVar(),它是 TKinter 的变量类之一(BooleanVar、DoubleVar、IntVar、StringVar)。变量可以与大多数条目小部件一起使用,以跟踪对输入值的更改。只要 StringVar、IntVar .. 等的值发生变化,它们就会使连接到它们的小部件更改其值。(来源)
因此,在您的情况下,您在调用的全局变量中创建了一个 StringVar,tableText
并将其传递给您正在创建的所有 Lable 小部件。在循环内部,您可以使用该方法不断更改tableText
函数内部的值,因此下次在循环中通过“set”方法更改“tableText”时,它将更改所有先前创建的连接到变量的标签。showTableText
tableText.set(base + "x" + factor + "=" + prod)
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()
. 但是,在您的代码中,它是一个全局变量,这意味着它只创建一次,并且您正在为所有标签重用 StringVar 的相同实例
推荐阅读
- grammar - 如何定义一种不符合乔姆斯基层次结构的语言?
- javascript - 示例代码,错误:应为“;” 但发现“类”和更多语法错误
- firebase - InvalidUrlError:无法识别的方案“gs”
- python-asyncio - 使用 asyncio.Queue() 时如何取消获取?
- javascript - 从比较中列出清单
- javascript - DiscordJS:检查输入是否在字符串中
- php - MySQLi 已启用但未在 Windows Server 2008 中加载
- node.js - 如何在 node.js 中的一台服务器上运行多个多人游戏(服务器)
- python - list1 在我的代码中的任何地方都不会被分配等于 list2,但是 list1 的值仍然被复制到 list2
- android - 当只有一个建议时,AutoCompleteTextView 建议隐藏在键盘下