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

Tkinter框架切换问题:切换后旧框架按钮未消失

问题解决:Tkinter框架切换时旧组件不消失

你的代码存在几个关键问题,导致框架切换时组件叠加显示:

核心错误点及修正

  1. 混用grid与pack布局
    循环中给每个框架同时设置了grid(row=0, column=0, sticky="nsew")和frame.pack(),pack会强制框架展开显示,造成所有框架组件叠加。只需保留grid布局,让框架堆叠在同一位置,通过tkraise()切换显示层级。

  2. show_frame方法逻辑错误
    tk.Frame.lower(self)是对主窗口操作,完全无效。只需获取目标框架并调用tkraise(),将其置于最上层即可。

  3. 组件父组件错误
    NewGame类中的Label使用root作为父组件,导致它直接挂载在主窗口而非当前框架,不受框架切换影响。需改为self作为父组件。

  4. 重复创建主窗口
    你既继承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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:43:19