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

Tkinter应用切换至Input Frame时背景变白问题求助

问题分析与解决

核心问题1:Frame切换时未销毁旧实例,导致叠加

当前代码每次点击分段按钮都会新建MenuFrame或InputFrame,但旧的Frame实例未被销毁,会一直叠加在窗口上。同时place()方法返回None,你无法通过self.menu或self.input引用到之前创建的Frame,无法管理它们的显示状态。

修复代码(SelectFrame部分)

class SelectFrame(customtkinter.CTkFrame):
    def __init__(self, master, back):
        super(SelectFrame, self).__init__(master)
        self.configure(width=120, height=60, border_width=2,)
        self.master = master
        self.menu_frame = None  # 保存Frame实例,而非place的返回值
        self.input_frame = None
        self.back = back
        self.create_widgets()

    def create_widgets(self):
        def segmented_button_callback(value):
            # 先销毁旧的Frame实例
            if self.menu_frame is not None:
                self.menu_frame.destroy()
            if self.input_frame is not None:
                self.input_frame.destroy()

            if value == "Menu":
                import menu_frame
                self.menu_frame = menu_frame.MenuFrame(self.master, self.back)
                self.menu_frame.place(x=25, y=125)

            if value == "Inputs":
                import input_frame
                self.input_frame = input_frame.InputFrame(self.master, self.back)
                self.input_frame.place(x=25, y=125)

        segemented_button = customtkinter.CTkSegmentedButton(master=self,
                                                             values=["Menu", "Inputs"],
                                                             command=segmented_button_callback,
                                                             width=100,
                                                             height=40,
                                                             selected_hover_color="blue",
                                                             font=("Helvetica", 14))
        segemented_button.place(x=10, y=10)

核心问题2:InputFrame组件绑定错误+背景未匹配主题

  1. self.lbl_error的master设为self.master(主窗口),导致标签直接显示在主窗口而非InputFrame内,位置超出Frame范围引发视觉错乱。
  2. 未显式设置InputFrame的背景颜色,导致其未继承CustomTkinter主题颜色,与Treeview背景色冲突。

修复代码(InputFrame部分)

class InputFrame(customtkinter.CTkFrame):
    def __init__(self, master, back):
        # 设置fg_color继承父容器主题颜色,避免背景突兀
        super(InputFrame, self).__init__(master, fg_color="transparent")
        self.master = master
        self.configure(width=850, height=350)
        self.table = ttk.Treeview(self, columns=("c1", "c2"), show='headings')
        # 错误标签绑定到InputFrame自身
        self.lbl_error = customtkinter.CTkLabel(master=self, text="", text_color="red")
        self.style()
        self.back = back
        self.createWidgets()

    def style(self):
        style = ttk.Style()
        # 获取InputFrame背景色,确保Treeview与Frame背景一致
        frame_bg = self.cget("fg_color")
        if isinstance(frame_bg, tuple):
            frame_bg = frame_bg[0]  # 适配深浅主题的颜色元组格式

        style.configure("Treeview",
                        background="#2a2d2e",
                        foreground="white",
                        fieldbackground=frame_bg,
                        bordercolor=frame_bg,
                        rowheight=35,
                        borderwidth=0,
                        font=(None, 16))
        style.map('Treeview', background=[('selected', '#22559b')])

        style.configure("Treeview.Heading",
                        background="#565b5e",
                        foreground="white",
                        font=(None, 16))
        style.map("Treeview.Heading",
                  background=[('active', '#3484F0')])

    def createWidgets(self):
        lbl_mod2 = customtkinter.CTkLabel(master=self, text="INPUTS INFO", font=("Helvetica", 16))
        lbl_mod2.place(x=380, y=10)

        self.table['columns'] = ('input', 'pulses')
        self.table.column("input", width=300, anchor="center")
        self.table.column("pulses", width=500, anchor="center")
        self.table.heading("input", text="INPUT")
        self.table.heading("pulses", text="Nº PULSES")
        self.updateData()
        self.table.place(x=225, y=60)

        # 调整错误标签位置,确保在InputFrame范围内
        self.lbl_error.place(x=180, y=310)

    def updateData(self):
        self.table.delete(*self.table.get_children())
        pulses = []
        try:
            pulses = self.back.get_pulses()
            self.lbl_error.configure(text="")
        except Exception as e:
            self.lbl_error.configure(text="ERROR: Cannot get info from device")
        
        for i in range(8):
            self.table.insert(parent='', index='end',
                              values=('INPUT ' + str(i + 1), pulses[i]))

        self.after(1000, self.updateData)

额外优化建议

  • 将import menu_frame和import input_frame移到文件顶部,避免回调函数内重复导入模块。
  • 考虑使用customtkinter.CTkTreeview替代ttk.Treeview,它会自动适配CustomTkinter主题,无需手动设置样式。

内容的提问来源于stack exchange,提问作者Pinkurauchin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:45:46