Tkinter中mainloop与after方法未按预期工作(坎耶名言训练)
解决Tkinter定时刷新坎耶名言的问题
你的问题核心是对window.after()和mainloop()的逻辑理解有误:
mainloop()是Tkinter的事件循环,只会在启动时执行一次Tk()到mainloop()之间的初始化代码,之后只负责处理用户事件、定时器事件等。window.after(X, func, args)是一次性定时器,只会在X毫秒后调用一次指定函数,不会自动重复。
要实现每隔X秒自动刷新,需要在回调函数内部再次调用window.after(),形成循环。同时你当前提前获取了NEW_TEXT,导致每次刷新都是同一句名言,需要每次刷新时重新请求API。
修改后的代码:
import tkinter, requests from tkinter import * def get_quotes(): try: kanye = requests.get(url="https://api.kanye.rest") kanye.raise_for_status() quote = kanye.json() return quote["quote"] except requests.exceptions.RequestException: # 请求失败时返回默认文本 return "获取名言失败,请稍后重试" def change_quote(): # 每次刷新都重新获取新名言 new_quote = get_quotes() quote_canvas.itemconfig(TEXT, text=new_quote) # 再次调用after,实现循环刷新 window.after(3500, change_quote) # --- UI design of application --- window = Tk() window.title("Kanye quotes API") window.config(background="white", padx=20, pady=20) # -- Canvas for quote --- quote_canvas = Canvas(height=414, width=300, background="white", highlightthickness=0) quote_img = tkinter.PhotoImage(file="Kanye REST API/images/background.png") quote_canvas.create_image(150, 200, image=quote_img) TEXT = quote_canvas.create_text(150, 180, text=get_quotes(), font=("courier", 20, "normal"), fill="black", justify=CENTER, width=280) quote_canvas.grid(row=0, column=0) # -- Canvas for emoji --- emoji_canvas = Canvas(height=150, width=131, background="white", highlightthickness=0) emoji_img = tkinter.PhotoImage(file="Kanye REST API/images/kanye.png") emoji_canvas.create_image(70, 75, image=emoji_img) emoji_canvas.grid(row=1, column=0) # 启动第一次刷新定时器 window.after(3500, change_quote) window.mainloop()
关键改动说明:
- 重构
change_quote函数:去掉参数,改为内部调用get_quotes()获取最新名言,更新文本后再次调用window.after(),形成循环。 - 给
get_quotes()添加try-except捕获请求异常,避免API请求失败导致程序崩溃。 - 移除提前定义的
NEW_TEXT,确保每次刷新都是新的名言。
内容的提问来源于stack exchange,提问作者NickTahmer
相关产品推荐
相关产品推荐

