在Tkinter中永久更改标签值

时间:2019-06-25 15:18:53

标签: python tkinter

我想在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()-它会返回您当前的温度,因此我希望标签根据此函数调用每秒刷新一次。

2 个答案:

答案 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毫秒。


You can read more about after() here.

答案 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()