Tkinter框架切换问题:切换后旧框架按钮未消失
问题解决:Tkinter框架切换时旧组件不消失
你的代码存在几个关键问题,导致框架切换时组件叠加显示:
核心错误点及修正
混用
grid与pack布局
循环中给每个框架同时设置了grid(row=0, column=0, sticky="nsew")和frame.pack(),pack会强制框架展开显示,造成所有框架组件叠加。只需保留grid布局,让框架堆叠在同一位置,通过tkraise()切换显示层级。show_frame方法逻辑错误tk.Frame.lower(self)是对主窗口操作,完全无效。只需获取目标框架并调用tkraise(),将其置于最上层即可。组件父组件错误
NewGame类中的Label使用root作为父组件,导致它直接挂载在主窗口而非当前框架,不受框架切换影响。需改为self作为父组件。重复创建主窗口
你既继承tk.Tk创建intothesea类,又单独实例化root = tk.Tk(),会生成两个窗口,需移除单独的root实例化代码。
修正后的完整代码
import tkinter as tk from tkinter import simpledialog LARGE_FONT = "Verdana" class intothesea(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.geometry("640x480") container = tk.Frame(self, height="640", width="480") container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for F in (Opening, NewGame, LithHarbor): frame = F(container, self) self.frames[F] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame(Opening) def show_frame(self, cont): frame = self.frames[cont] frame.tkraise() class Opening(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) label = tk.Label(self, text="In. To. The. Sea.", font=LARGE_FONT) label.pack(pady=10,padx=10) button = tk.Button(self, text="NEW GAME", command=lambda: controller.show_frame(NewGame)) button.pack() button2 = tk.Button(self, text="CONTINUE", command=lambda: controller.show_frame(LithHarbor)) button2.pack() class NewGame(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) label = tk.Label(self, text="In. To. The. Sea.", font=LARGE_FONT) label.pack(pady=10,padx=10) new_character = "" def accept_string(): nonlocal new_character user_input = simpledialog.askstring("Input", "Enter a string:") if user_input: new_character = user_input print(user_input) name.pack_forget() name = tk.Button(self, text="WHAT IS YOUR NAME?", command=accept_string) name.pack() class LithHarbor(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) label = tk.Label(self, text="In. To. The. Sea.", font=LARGE_FONT) label.pack(pady=10,padx=10) app = intothesea() app.mainloop()
额外优化建议
- 可给每个框架设置不同背景色,方便调试时区分显示状态。
- 原代码中用列表存储用户名不合理,改为字符串变量更直观。
内容的提问来源于stack exchange,提问作者m. lekk
相关产品推荐
相关产品推荐

