You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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()

问题根源

  1. 未更新绑定界面变量:添加任务到栈后,未修改info_text值,仅调用window.update()无法触发界面刷新
  2. 任务完成后未同步界面:点击按钮完成任务时,既没更新金钱显示,也没刷新当前任务提示
  3. 任务列表被意外覆盖:job()函数直接修改全局tasks列表,导致原任务类型丢失
  4. 缺少自动任务循环:没有实现定时添加任务并更新界面的逻辑

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:25:20