更新Tkinter窗口内容

1 投票
1 回答
4662 浏览
提问于 2025-04-19 18:03

我正在创建一个Python程序,想在Tkinter窗口中显示时间和天气。我需要让时间、天气和其他内容不断更新。以下是我以前的代码:

import time

from Tkinter import *

root = Tk()
while True:
    now = time.localtime(time.time()) # Fetch the time
    label = time.strftime("%I:%M", now) # Format it nicely
    # We'll add weather later once we find a source (urllib maybe?)
    w = Label(root, text=label) # Make our Tkinter label
    w.pack()
    root.mainloop()

我之前从来没有用过Tkinter,所以当循环不工作的时候我感到很沮丧。显然,Tkinter在运行时不允许你做任何循环或者其他非Tkinter的事情。我想也许可以尝试用线程来解决这个问题。

#!/usr/bin/env python


# Import anything we feel like importing
import threading
import time

# Thread for updating the date and weather
class TimeThread ( threading.Thread ):
    def run ( self ):
        while True:
            now = time.localtime(time.time()) # Get the time
            label = time.strftime("%I:%M", now) # Put it in a nice format
            global label # Make our label available to the TkinterThread class
            time.sleep(6)
            label = "Weather is unavailable." # We'll add in weather via urllib later.
            time.sleep(6)

# Thread for Tkinter UI
class TkinterThread ( threading.Thread ):
    def run ( self ):
        from Tkinter import * # Import Tkinter
        root = Tk() # Make our root widget
        w = Label(root, text=label) # Put our time and weather into a Tkinter label
        w.pack() # Pack our Tkinter window
        root.mainloop() # Make it go!

# Now that we've defined our threads, we can actually do something interesting.
TimeThread().start() # Start our time thread
while True:
    TkinterThread().start() # Start our Tkinter window
    TimeThread().start() # Update the time
    time.sleep(3) # Wait 3 seconds and update our Tkinter interface

但是这样也不行。出现了多个空窗口,而且它们经常出错。我在调试器中也收到了很多错误信息。

我需要在更新时停止并重新打开窗口吗?我能不能用类似tkinter.update(root)的方式告诉Tkinter去更新呢?

有没有什么解决办法,或者我是不是漏掉了什么?如果你发现我的代码有问题,请告诉我。

谢谢!
亚历克斯

1 个回答

1

你可以把你的 after 调用“嵌套”起来:

def update():
    now = time.localtime(time.time())
    label = time.strftime("%I:%M:%S", now)
    w.configure(text=label)
    root.after(1000, update)

现在你只需要在主循环之前调用一次 after,从现在开始,它会每秒更新一次。

撰写回答