我想在GUI上显示一个永久更改(温度)的动态数字。如何使标签动态化?
我尝试设置其他值,但知道在调用mainLoop之后,程序处于无限状态。我已经阅读了有关.after()函数的信息,但是我不知道如何确切地使用它,因为我不想定义新函数。我得到一个返回值,只希望对其进行更新。
import tkinter as tk
from src import SerialPort as sp
HEIGHT = 300
WIDTH = 500
root = tk.Tk()
canvas = tk.Canvas(root, height = HEIGHT, width = WIDTH)
canvas.pack()
aktTemp = tk.Label(root, text=str(sp.read_current_Temperature())+"°C", fg="red")
aktTemp.pack()
root.mainloop()
sp.read_current_Temperature()-它会返回您当前的温度,因此我希望标签根据此函数调用每秒刷新一次。
答案 0 :(得分:3)
因此,在tkinter中不断更新某些内容的主要问题是,至少对于大多数程序而言,您被锁定在mainloop中。
对于所有意图和目的,这基本上意味着在您的程序中,您实际上从未调用过最后一行,因为Python正在等待mainloop结束。
我们已正确解决了此问题的解决方法,就是利用after()
函数。如果您还不知道如何使用它(并打算继续使用tkinter),则绝对应该将其添加到您的工具箱中。
首先,我对您的程序进行了快速更改,只是为了获得一个返回的温度值。我这样做是为了演示如何更新文本小部件,并涉及添加仅返回随机值的新函数。
import tkinter as tk
import random
def read_current_Temperature():
return random.randint(1, 100)
HEIGHT = 300
WIDTH = 500
root = tk.Tk()
canvas = tk.Canvas(root, height = HEIGHT, width = WIDTH)
canvas.pack()
aktTemp = tk.Label(root, text=str(read_current_Temperature())+"°C", fg="red")
aktTemp.pack()
root.mainloop()
read_current_Temperature()
现在,正如您在运行上述命令时所看到的,我们得到的结果基本上与您的原始程序相同。温度是 read (读取:随机生成),然后更新小部件,然后。 。 。没什么。
因此,首先,我们需要找到在何处使用after()
。我们可以通过多种方式来执行此操作,但是最简单的方式(在这种情况下,主观地说。在可能的情况下,我建议您使用class
来代替,但这需要更多的实质性重写)是添加新功能,如下所示:
import tkinter as tk
import random
def read_current_Temperature():
return random.randint(1, 100)
def update():
aktTemp.config(text=str(read_current_Temperature())+"°C")
aktTemp.after(1000, update)
HEIGHT = 300
WIDTH = 500
root = tk.Tk()
canvas = tk.Canvas(root, height = HEIGHT, width = WIDTH)
canvas.pack()
aktTemp = tk.Label(root, text=str(read_current_Temperature())+"°C", fg="red")
aktTemp.pack()
update()
root.mainloop()
让我们逐行看看。
update()
我们击中的第一行(运行时,而不是读取时)是对我定义的新函数的调用,即其中的。 。
def update():
aktTemp.config(text=str(read_current_Temperature())+"°C")
aktTemp.after(1000, update)
此函数的第一行。 。
aktTemp.config(text=str(read_current_Temperature())+"°C")
。 。 。只是简单地告诉程序去获取新温度并将其指定为标签小部件text
的{{1}}属性。这是实际上在GUI中进行更改的行。
另一方面,这行。 。
aktTemp
。 。 。是我上面提到的 aktTemp.after(1000, update)
的用法。这一切都是说“每隔1000毫秒,调用函数after
”,正如我们从上面知道的那样,然后将标签更新到新的温度,并在再次调用自身之前再延迟1000毫秒。
答案 1 :(得分:2)
不幸的是,要正确执行此操作,您必须定义至少一个新函数。我赞扬@EthanField的详细说明(+1),但这是我使用Tk的 tracing 功能的替代实现:
import tkinter as tk
from src import SerialPort as sp
WIDTH, HEIGHT = 500, 300
def refresh_temperature(string):
temperature.set(string.format(sp.read_current_Temperature()))
root.after(1000, refresh_temperature, string)
root = tk.Tk()
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()
temperature = tk.StringVar()
aktTemp = tk.Label(root, textvariable=temperature, fg="red")
aktTemp.pack()
refresh_temperature("{} °C")
root.mainloop()