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

CustomTkinter中CTKButton状态修改不生效问题求助

解决CustomTkinter折叠按钮禁用后仍可点击的问题

问题原因

你通过bind("<Button-1>")给按钮绑定了点击事件,但CustomTkinter的CTkButton设置state=DISABLED时,仅会禁用按钮的默认command回调,不会阻止通过bind()绑定的自定义事件逻辑。这就是按钮状态显示为禁用,但点击依然触发折叠/展开的核心原因。

解决方案

有两种可行的修复方式,根据你的需求选择:

方案1:改用按钮的command参数(推荐)

将绑定事件的方式替换为按钮自带的command参数,这样设置state=DISABLED时会自动禁用回调逻辑:

修改CollapsibleFrame类的__init__方法中按钮初始化的代码:

# 初始化折叠按钮,用command替代bind
self.collapsebuton = ctk.CTkButton(self,
                                   image=self.down_chevron, text="",
                                   command=self.collapse)
self.collapsebuton.grid(row=0, column=1,
                        padx=20, pady=20,
                        sticky="e")
# 删除原有的bind语句:self.collapsebuton.bind("<Button-1>", lambda event: self.collapse())

# 初始化展开按钮,用command替代bind
self.uncollapsebuton = ctk.CTkButton(self,
                                   image=self.up_chevron, text="",
                                   command=self.uncollapse)
self.uncollapsebuton.grid(row=0, column=1,
                        padx=20, pady=20,
                        sticky="e")
# 删除原有的bind语句:self.uncollapsebuton.bind("<Button-1>", lambda event: self.uncollapse())

方案2:在绑定事件中检查按钮状态

如果必须保留bind的方式,需要在事件回调中先判断按钮状态,仅当状态为normal时执行逻辑:

修改__init__中的bind语句:

self.collapsebuton.bind("<Button-1>", lambda event: self.collapse() if self.collapsebuton.cget("state") == "normal" else None)

self.uncollapsebuton.bind("<Button-1>", lambda event: self.uncollapse() if self.uncollapsebuton.cget("state") == "normal" else None)

完整修复后的代码示例(方案1)

import tkinter
import customtkinter as ctk
from PIL import Image

ctk.set_appearance_mode("Dark")
ctk.set_default_color_theme("dark-blue")
appWidth, appHeight = 600, 700

class CollapsibleFrame(ctk.CTkFrame):
    """
    Class to create a collapsible frame. Starts as collapsed. Row and Column are row and column of parent frame it should be gridded to
    """
    def __init__(self, master, row:int=0,column:int=0,collapsed_text:str='',**kwargs):
        super().__init__(master, **kwargs)
        self.collapsed_text=collapsed_text
        # add widgets onto the frame, for example:
        self.label = ctk.CTkLabel(self)
        self.label.grid(row=0, column=0)
        self.title_label = ctk.CTkLabel(self,
                                      text=self.collapsed_text)
        self.title_label.grid(row=0, column=0)
        self.row=row
        self.column=column
        self.collapsed_widgets=[]
        # load icons
        self.down_chevron=ctk.CTkImage(Image.open("chevron_up.png"), size=(7, 7))
        self.up_chevron = ctk.CTkImage(Image.open("chevron_down.png"), size=(7, 7))
        # Add hide/unhide buttons
        self.collapsebuton = ctk.CTkButton(self,
                                           image=self.down_chevron,text="",
                                           command=self.collapse)
        self.collapsebuton.grid(row=0, column=1,
                                padx=20, pady=20,
                                sticky="e")

        self.uncollapsebuton = ctk.CTkButton(self,
                                           image=self.up_chevron,text="",
                                           command=self.uncollapse)
        self.uncollapsebuton.grid(row=0, column=1,
                                padx=20, pady=20,
                                sticky="e")


    def hide(self):
        """ Completely hides frame """
        print('hiding')
        self.grid_forget()
    def unhide(self):
        """ Completely unhides frame """
        print('unhiding')
        self.grid(row=self.row,column=self.column,sticky='ew')
        self.columnconfigure(0,weight=1)
        #self.rowconfigure(0, weight=1)
    def collapse(self):
        """ Collapses frame, leaving icon to uncollapse """
        print('collapsing')
        # hide all known items
        sub_items=self.grid_slaves()
        for item in sub_items:
            self.collapsed_widgets.append(item) # save these items for if we want to un-hide them later
            item.grid_remove()
        # add back uncollapse button, title
        self.uncollapsebuton.grid()
        self.collapsebuton.grid_remove()
        self.title_label.grid()
    def uncollapse(self):
        """ Uncollapses frame, leaving icon to collapse """
        print('uncollapsing')
        # unhide previously hidden widgets
        for item in self.collapsed_widgets:
            item.grid()
        self.collapsed_widgets.clear()
        self.unhide()
        self.collapsebuton.grid()
        self.uncollapsebuton.grid_remove()
    def disable_uncollapse(self):
        self.uncollapsebuton.configure(state=ctk.DISABLED)
        self.collapsebuton.configure(state='disabled')

class App(ctk.CTk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.title("My awesome window")
        self.geometry(f"{appWidth}x{appHeight}")
        self.columnconfigure(0, weight=1)
        create_vault_frame = CollapsibleFrame(self,row=0,column=0,collapsed_text="Panel1")
        create_vault_frame.uncollapse()
        new_label=ctk.CTkLabel(create_vault_frame,text='aaah')
        new_label.grid(row=1,column=0)
        create_vault_frame.disable_uncollapse()
if __name__ == "__main__":
    app = App()
    app.mainloop()

内容的提问来源于stack exchange,提问作者Mr. T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:05:03