如何实现Tkinter窗口自动更新?洗车模拟器代码问题求助
洗车任务游戏界面更新问题解决方案
问题描述
制作基于栈结构的洗车任务游戏(学校项目),需求是随机分配洗车任务到栈中后,窗口自动显示最新任务并更新金钱计数器,但使用window.update()和window.after(1000, update)均无效,代码如下:
import tkinter as tk import time as time import random as random stack = [] money = 0 def push(item): global stack stack.append(item) def pop(): global stack stack_length = len(stack) if stack_length == 0: pass else: stack.pop() def peek(): global stack if len(stack) == 0: pass else: return stack[-1] def random_cars(): global stack global tasks tasks = ["wash", "vac", "polish", "dry", "interior detail", "exterior detail", "full detail", "wheel wash"] random_number = random.randint(0,7) task_to_add = tasks[random_number] if len(stack) <= 10: push(task_to_add) window.update() def job(): global tasks correct_answers = tasks correct_answers[0] = "exterior" correct_answers[1] = "interior" correct_answers[2] = "exterior" correct_answers[3] = "exterior" correct_answers[4] = "interior" correct_answers[5] = "exterior" correct_answers[6] = "both" correct_answers[7] = "exterior" return correct_answers def start(): random_cars() start_button.config(state="disabled") exterior_button.config(state="normal") interior_button.config(state="normal") both_button.config(state="normal") task_to_do_is = peek() global stack if len(stack) == 0: info_text.set("There are no jobs yet.") random_cars() else: info_text.set("The task you need to do is: " + task_to_do_is) def exterior(): global tasks global stack global money button_click = "exterior" task_doing = peek() correct_anwers = job() for i in range(len(tasks)): if tasks[i] == task_doing: if correct_anwers[i] == button_click: pop() money += 10 def interior(): pass def both(): pass window = tk.Tk() window.title("Car wash simulator") title = tk.Label(window, text="Car wash simulator", font=("Arial", 30)) title.grid(column=0, row=0, padx=75) info_text = tk.StringVar() info_text.set("The aim of the game is to select the correct task. \n You will be given a job in a random order, \n and you have to decide whether it is an interior or exterior job.") game_info = tk.Label(window, textvariable=info_text, font=("Arial", 15)) game_info.grid(column=0, row=1, padx=75) start_button = tk.Button(window, text="Start game", command=start) start_button.grid(column=0, row=2, padx=75) frame = tk.Frame(window) frame.grid(column=0, row=3) exterior_button = tk.Button(frame, text="exterior", command=exterior) exterior_button.grid(row=0, column=0) exterior_button.config(state="disabled") interior_button = tk.Button(frame, text="interior", command=interior) interior_button.grid(row=0, column=2) interior_button.config(state="disabled") both_button = tk.Button(frame, text="both", command=both) both_button.grid(row=0, column=1) both_button.config(state="disabled") money_label_text = tk.StringVar() money_label_text.set("Money:" + str(money)) money_label = tk.Label(window, textvariable=money_label_text, font=("Ariel", 15)) money_label.grid(column=0, row=4, padx=75) window.mainloop()
问题根源
- 未更新绑定界面变量:添加任务到栈后,未修改
info_text值,仅调用window.update()无法触发界面刷新 - 任务完成后未同步界面:点击按钮完成任务时,既没更新金钱显示,也没刷新当前任务提示
- 任务列表被意外覆盖:
job()函数直接修改全局tasks列表,导致原任务类型丢失 - 缺少自动任务循环:没有实现定时添加任务并更新界面的逻辑
修改后的完整代码
import tkinter as tk import random stack = [] money = 0 # 提前定义任务列表,避免被答案函数覆盖 tasks = ["wash", "vac", "polish", "dry", "interior detail", "exterior detail", "full detail", "wheel wash"] def push(item): global stack stack.append(item) def pop(): global stack if stack: stack.pop() def peek(): return stack[-1] if stack else None def get_correct_answers(): # 用字典映射任务与正确分类,不修改原任务列表 return { "wash": "exterior", "vac": "interior", "polish": "exterior", "dry": "exterior", "interior detail": "interior", "exterior detail": "exterior", "full detail": "both", "wheel wash": "exterior" } def random_cars(): global stack if len(stack) <= 10: task_to_add = random.choice(tasks) push(task_to_add) # 添加任务后立即更新界面显示 update_task_display() # 定时1秒后再次生成任务,实现自动分配 window.after(1000, random_cars) def update_task_display(): current_task = peek() if current_task: info_text.set(f"The task you need to do is: {current_task}") else: info_text.set("There are no jobs yet.") def update_money_display(): money_label_text.set(f"Money: {money}") def start(): start_button.config(state="disabled") exterior_button.config(state="normal") interior_button.config(state="normal") both_button.config(state="normal") # 启动自动任务生成循环 random_cars() def exterior(): global money current_task = peek() if not current_task: return correct_answers = get_correct_answers() if correct_answers.get(current_task) == "exterior": pop() money += 10 # 完成任务后同步更新金钱和任务显示 update_money_display() update_task_display() def interior(): global money current_task = peek() if not current_task: return correct_answers = get_correct_answers() if correct_answers.get(current_task) == "interior": pop() money += 10 update_money_display() update_task_display() def both(): global money current_task = peek() if not current_task: return correct_answers = get_correct_answers() if correct_answers.get(current_task) == "both": pop() money += 15 # 给全细节任务更高奖励 update_money_display() update_task_display() window = tk.Tk() window.title("Car wash simulator") title = tk.Label(window, text="Car wash simulator", font=("Arial", 30)) title.grid(column=0, row=0, padx=75) info_text = tk.StringVar() info_text.set("The aim of the game is to select the correct task. \n You will be given a job in a random order, \n and you have to decide whether it is an interior or exterior job.") game_info = tk.Label(window, textvariable=info_text, font=("Arial", 15)) game_info.grid(column=0, row=1, padx=75) start_button = tk.Button(window, text="Start game", command=start) start_button.grid(column=0, row=2, padx=75) frame = tk.Frame(window) frame.grid(column=0, row=3) exterior_button = tk.Button(frame, text="exterior", command=exterior) exterior_button.grid(row=0, column=0, padx=5) exterior_button.config(state="disabled") interior_button = tk.Button(frame, text="interior", command=interior) interior_button.grid(row=0, column=2, padx=5) interior_button.config(state="disabled") both_button = tk.Button(frame, text="both", command=both) both_button.grid(row=0, column=1, padx=5) both_button.config(state="disabled") money_label_text = tk.StringVar() money_label_text.set(f"Money: {money}") money_label = tk.Label(window, textvariable=money_label_text, font=("Arial", 15)) money_label.grid(column=0, row=4, padx=75) window.mainloop()
关键修改说明
- 拆分任务与答案映射:用字典存储任务分类,避免修改原任务列表
- 新增界面同步函数:
update_task_display()和update_money_display()专门负责更新绑定的界面变量 - 实现定时任务循环:通过
window.after()持续调用任务生成函数,实现自动分配任务 - 完善按钮逻辑:每个按钮完成任务后立即触发金钱和任务显示更新
- 简化栈操作:利用Python列表的布尔特性简化空栈判断逻辑
内容的提问来源于stack exchange,提问作者Gurcharan5
相关产品推荐
相关产品推荐

