首页 > 解决方案 > 如何动态更新 tkinter 中的标签?

问题描述

我创建了这段代码,它每秒更新一个标签以指示正在加载某些内容(运行代码以了解我的意思)。我正在使用带有 tkinter 的线程模块,但我觉得必须有一种更有效的方法来做到这一点。

这是我的代码:

from tkinter import *
from time import sleep
import threading

root = Tk()
new_var = StringVar()
new_var.set('Loading')

def change_text():
    array = [".", "..", "...", ""]
    while True:
        for num in range(4):
            sleep(1)
            new_var.set(f"Loading{array[num]}")
            root.update_idletasks()

l = Label(root, textvariable = new_var)
l.pack()

Loading_animation = threading.Thread(target=change_text)
Loading_animation.start()
root.mainloop()

另外,如果没有更好的方法来做到这一点,我如何防止在关闭根窗口时不断收到错误?

谢谢!

标签: pythonmultithreadingtkinter

解决方案


这是一个不涉及线程的更简单的方法。

保持一个计数器,每秒调用该函数。在函数中只需将文本设置为由计数器作为索引列表中的每个项目。

更新:在评论中回答您的问题。

这不会卡在阻止我们到达的某个循环中,mainloop()因为此代码仅添加一个命令,以 1 秒的固定间隔在事件列表上运行。实际发生的是该after()方法将添加一个新的甚至运行不早于 1 秒(1000 毫秒)。因为 Tkinter 是事件驱动的,所以 Tkinter 甚至会在每个mainloop()循环之后处理列表中的每一个。

import tkinter as tk

root = tk.Tk()
counter = 0

def change_text():
    global counter
    my_list = [".", "..", "...", ""]
    if counter != 3:
        l.config(text="Loading{}".format(my_list[counter]))
        counter += 1
        root.after(1000, change_text)
    else:
        l.config(text="Loading{}".format(my_list[counter]))
        counter = 0
        root.after(1000, change_text)

l = tk.Label(root, text = "")
l.pack()

change_text()
root.mainloop()

推荐阅读