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

如何在CustomTkinter中实现同功能多按钮的状态切换

解决按钮网格的状态切换问题

要实现点击按钮切换状态/样式,核心是让回调函数能识别当前点击的按钮。下面是针对你的CustomTkinter代码的修正版本:

import customtkinter

customtkinter.set_appearance_mode("System")
customtkinter.set_default_color_theme("dark-blue")

class App(customtkinter.CTk):
    def __init__(self):
        super().__init__()

        self.dezenas_frame = customtkinter.CTkFrame(self, width=30, corner_radius=0)
        self.dezenas_frame.grid(row=0, column=0, rowspan=4, sticky="nsew")
        self.dezenas_frame.grid_rowconfigure(4, weight=1)
        self.logo_label = customtkinter.CTkLabel(self.dezenas_frame, text="text text!",
                                                 font=customtkinter.CTkFont(size=10, weight="bold"))
        self.logo_label.grid(row=0, column=0, padx=15, pady=(10, 10))

        # 用字典存储所有按钮实例,键为按钮编号
        self.buttons = {}
        c_r = 1
        c_c = 1
        for cnt in range(1, 61):
            # 用lambda绑定当前按钮和编号到回调函数
            button = customtkinter.CTkButton(self.dezenas_frame, text=cnt, width=40,
                                            command=lambda btn=button, num=cnt: self.toggleState(btn, num))
            self.buttons[cnt] = button
            button.grid(row=c_r, column=c_c, padx=1, pady=1)

            if c_c == 10:
                c_c = 0
                c_r += 1
            c_c += 1

    def toggleState(self, button, num):
        # 示例:切换按钮状态和背景色
        if button.cget("state") == "normal":
            button.configure(state="disabled", fg_color="#ff6b6b")
        else:
            button.configure(state="normal", fg_color=customtkinter.ThemeManager.theme["CTkButton"]["fg_color"])

if __name__ == "__main__":
    app = App()
    app.mainloop()

关键改动说明:

  • 存储按钮实例:用self.buttons字典保存每个按钮,键是按钮的编号(1-60),后续可以通过编号直接访问对应按钮。
  • 绑定回调参数:创建按钮时用lambda把当前按钮实例和编号传给toggleState函数,这样回调函数能明确知道是哪个按钮被点击。
  • 状态切换逻辑:在toggleState里直接操作传入的按钮实例,通过cget()获取当前状态,再用configure()修改样式或状态。

如果是用标准Tkinter的按钮,逻辑完全一致,只需要调整按钮的配置参数:

import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.right_frame = tk.Frame(self)
        self.right_frame.pack(padx=10, pady=10)

        self.buttons = {}
        # 生成60个按钮,按6行10列排列
        for row in range(6):
            for col in range(10):
                num = row * 10 + col + 1
                btn_text = f"{num:02d}"
                button = tk.Button(self.right_frame, text=btn_text, relief="raised",
                                  command=lambda btn=button: self.togg(btn))
                self.buttons[num] = button
                button.grid(row=row, column=col, padx=5, pady=5)

    def togg(self, button):
        # 示例:切换按钮的凸起/凹陷状态和背景色
        if button.cget("relief") == "raised":
            button.configure(relief="sunken", bg="#ff6b6b")
        else:
            button.configure(relief="raised", bg=self.cget("bg"))

if __name__ == "__main__":
    app = App()
    app.mainloop()

原方案的问题:

  • 循环创建按钮时一直用self.button赋值,最终这个变量只会指向最后一个按钮,无法通过它修改其他按钮。
  • 手动命名button_01到button_60的方式过于繁琐,且回调函数无法自动识别当前点击的按钮,必须为每个按钮单独写回调,扩展性极差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:01:25