如何使用Tkinter创建一个自动更新的图形用户界面(GUI)?

8
from Tkinter import *
import time
#Tkinter stuff

class App(object):
    def __init__(self):
        self.root = Tk()

        self.labeltitle = Label(root, text="",  fg="black", font="Helvetica 40 underline bold")
        self.labeltitle.pack()

        self.labelstep = Label(root, text="",  fg="black", font="Helvetica 30 bold")
        self.labelstep.pack()

        self.labeldesc = Label(root, text="",  fg="black", font="Helvetica 30 bold")
        self.labeldesc.pack()

        self.labeltime = Label(root, text="",  fg="black", font="Helvetica 70")
        self.labeltime.pack()

        self.labelweight = Label(root, text="",  fg="black", font="Helvetica 25")
        self.labelweight.pack()

        self.labelspeed = Label(root, text="",  fg="black", font="Helvetica 20")
        self.labelspeed.pack()

        self.labeltemp = Label(root, text="", fg="black", font="Helvetica 20")
        self.labeltemp.pack()

        self.button = Button(root, text='Close recipe', width=25, command=root.destroy)
        self.button.pack()

    def Update(self, label, change):
        label.config(text=str(change))

def main():
    app = App()
    app.mainloop()

if __name__ == "__main__":
    main()

我正在尝试创建一个食谱显示器,在Tkinter GUI中显示步骤、说明、重量和其他变量。然而,我不知道如何更新GUI以在配方的每个新步骤中进行更改,因为内容必须根据用户输入(从服务器获取)进行动态更新。如何实现GUI的其他元素基于步骤变化进行更新?
6个回答

25
你可以使用after()函数在1000毫秒(1秒)后运行某个功能并更新标签上的文本。这个函数可以在1000毫秒后再次自我运行(循环执行)。下面是一个以当前时间为例的示例。
from Tkinter import *
import datetime

root = Tk()

lab = Label(root)
lab.pack()

def clock():
    time = datetime.datetime.now().strftime("Time: %H:%M:%S")
    lab.config(text=time)
    #lab['text'] = time
    root.after(1000, clock) # run itself again after 1000 ms
    
# run first time
clock()

root.mainloop()

顺便说一下:你可以像sundar nataraj Сундар建议的那样使用StringVar


编辑:(2022.01.01)

已更新为Python 3,并采纳了PEP 8 -- Python代码风格指南中的其他建议。

import tkinter as tk   # PEP8: `import *` is not preferred
import datetime

# --- functions ---
# PEP8: all functions before main code
# PEP8: `lower_case_name` for funcitons
# PEP8: verb as function's name
                     
def update_clock():
    # get current time as text
    current_time = datetime.datetime.now().strftime("Time: %H:%M:%S")
    
    # udpate text in Label
    lab.config(text=current_time)
    #lab['text'] = current_time
    
    # run itself again after 1000 ms
    root.after(1000, update_clock) 

# --- main ---

root = tk.Tk()

lab = tk.Label(root)
lab.pack()
    
# run first time at once
update_clock()

# run furst time after 1000ms (1s)
#root.after(1000, update_clock)

root.mainloop()

我认为这非常优雅。这是一个很好的选择,有相当大的创意可能性。 - Marc

2

如果您想动态修改标签

self.dynamiclabel=StringVar()
self.labeltitle = Label(root, text=self.dynamiclabel,  fg="black", font="Helvetica 40 underline bold")
self.dyanamiclabel.set("this label updates upon change")
self.labeltitle.pack()

每当您获得新值时,只需使用.set()
self.dyanamiclabel.set("Hurrray! i got changed")

这适用于所有标签。要了解更多,请阅读此文档

2
如果您正在使用标签,那么您可以使用以下内容:
label = tk.Label(self.frame, bg="green", text="something")
label.place(rely=0, relx=0.05, relwidth=0.9, relheight=0.15)

refresh = tk.Button(frame, bg="white", text="Refreshbutton",command=change_text) 
refresh.pack(rely=0, relx=0.05, relwidth=0.9, relheight=0.15)

def change_text()
   label["text"] = "something else"

对我来说很好用,但它依赖于需要按下按钮的需求。


0

使用 root.config() 并添加运行方式


0
我在我的窗口中添加了一个进度条,并使用update函数每1秒根据randint更改其值:
from random import randint
def update():
    mpb["value"] = randint(0, 100) # take process bar for example
    window.after(1000, update)
update()
window.mainloop()

0

我用Python 3.7写了一个例子。

from tkinter import *

def firstFrame(window):
    global first_frame
    first_frame = Frame(window)
    first_frame.place(in_=window, anchor="c", relx=.5, rely=.5)
    Label(first_frame, text="ATTENTION !").grid(row=1,column=1,columnspan=3)


def secondFrame(window):
    global second_frame
    second_frame= Frame(window, highlightbackground=color_green, highlightcolor=color_green, highlightthickness=3)
    second_frame.place(in_=window, anchor="c", relx=.5, rely=.5)
    Label(second_frame, text="This is second frame.").grid(row=1, column=1, columnspan=3, padx=25, pady=(15, 0))


window = Tk()
window.title('Some Title')
window.attributes("-fullscreen", False)
window.resizable(width=True, height=True)
window.geometry('300x200')


firstFrame(window)
secondFrame(window)
first_frame.tkraise()
window.after(5000, lambda: first_frame.destroy()) # you can try different things here
window.mainloop()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接