Checkbutton(複選框)是Tkinter中用於創建多選選項的組件,允許用户選擇多個選項。

基本用法

1. 導入和基本創建

import tkinter as tk
from tkinter import messagebox

# 創建主窗口
root = tk.Tk()
root.title("Checkbutton組件詳解")
root.geometry("500x400")

2. 創建基本Checkbutton

# 創建BooleanVar來跟蹤複選框狀態
var1 = tk.BooleanVar()
var2 = tk.BooleanVar()

# 創建Checkbutton
check1 = tk.Checkbutton(root, text="選項1", variable=var1)
check1.pack(pady=10)

check2 = tk.Checkbutton(root, text="選項2", variable=var2)
check2.pack(pady=10)

# 顯示選擇結果的按鈕
def show_selection():
    selections = []
    if var1.get():
        selections.append("選項1")
    if var2.get():
        selections.append("選項2")
    
    if selections:
        messagebox.showinfo("選擇結果", f"你選擇了: {', '.join(selections)}")
    else:
        messagebox.showinfo("選擇結果", "你沒有選擇任何選項")

tk.Button(root, text="顯示選擇", command=show_selection).pack(pady=20)

root.mainloop()

Checkbutton的完整參數和功能

示例1:Checkbutton全面展示

import tkinter as tk
from tkinter import ttk

class CheckbuttonComprehensive:
    def __init__(self, root):
        self.root = root
        self.setup_ui()
        
    def setup_ui(self):
        """設置用户界面"""
        self.root.title("Checkbutton組件全面展示")
        self.root.geometry("600x500")
        
        # 創建主Frame
        main_frame = tk.Frame(self.root, bg="#f0f0f0", padx=20, pady=20)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 1. 基本Checkbutton示例
        self.create_basic_checkbuttons(main_frame)
        
        # 2. 不同狀態的Checkbutton
        self.create_state_checkbuttons(main_frame)
        
        # 3. 帶命令的Checkbutton
        self.create_command_checkbuttons(main_frame)
        
        # 4. 樣式化Checkbutton
        self.create_styled_checkbuttons(main_frame)
        
        # 5. 實際應用示例
        self.create_practical_example(main_frame)
        
    def create_basic_checkbuttons(self, parent):
        """創建基本Checkbutton示例"""
        section_frame = tk.LabelFrame(parent, text="1. 基本Checkbutton示例", 
                                     padx=10, pady=10, bg="white")
        section_frame.pack(fill=tk.X, pady=10)
        
        # 使用BooleanVar
        self.var1 = tk.BooleanVar()
        check1 = tk.Checkbutton(section_frame, text="選項1 (BooleanVar)", 
                               variable=self.var1, bg="white")
        check1.pack(anchor="w", pady=2)
        
        # 使用IntVar (0=未選中, 1=選中)
        self.var2 = tk.IntVar()
        check2 = tk.Checkbutton(section_frame, text="選項2 (IntVar)", 
                               variable=self.var2, bg="white")
        check2.pack(anchor="w", pady=2)
        
        # 使用StringVar
        self.var3 = tk.StringVar()
        self.var3.set("off")  # 默認值
        check3 = tk.Checkbutton(section_frame, text="選項3 (StringVar)", 
                               variable=self.var3, 
                               onvalue="on", offvalue="off", bg="white")
        check3.pack(anchor="w", pady=2)
        
        # 顯示狀態按鈕
        show_btn = tk.Button(section_frame, text="顯示所有狀態", 
                            command=self.show_basic_states)
        show_btn.pack(anchor="w", pady=5)
        
    def create_state_checkbuttons(self, parent):
        """創建不同狀態的Checkbutton"""
        section_frame = tk.LabelFrame(parent, text="2. 不同狀態的Checkbutton", 
                                     padx=10, pady=10, bg="white")
        section_frame.pack(fill=tk.X, pady=10)
        
        # 正常狀態
        self.normal_var = tk.BooleanVar(value=True)
        normal_check = tk.Checkbutton(section_frame, text="正常狀態", 
                                     variable=self.normal_var, state="normal", bg="white")
        normal_check.pack(anchor="w", pady=2)
        
        # 禁用狀態
        self.disabled_var = tk.BooleanVar(value=True)
        disabled_check = tk.Checkbutton(section_frame, text="禁用狀態", 
                                       variable=self.disabled_var, state="disabled", bg="white")
        disabled_check.pack(anchor="w", pady=2)
        
        # 只讀狀態(看起來正常但不能修改)
        self.readonly_var = tk.BooleanVar(value=False)
        readonly_check = tk.Checkbutton(section_frame, text="只讀狀態", 
                                       variable=self.readonly_var, state="readonly", bg="white")
        readonly_check.pack(anchor="w", pady=2)
        
        # 狀態控制按鈕
        state_frame = tk.Frame(section_frame, bg="white")
        state_frame.pack(fill=tk.X, pady=5)
        
        tk.Button(state_frame, text="啓用所有", command=self.enable_all).pack(side="left", padx=2)
        tk.Button(state_frame, text="禁用所有", command=self.disable_all).pack(side="left", padx=2)
        tk.Button(state_frame, text="切換隻讀", command=self.toggle_readonly).pack(side="left", padx=2)
        
    def create_command_checkbuttons(self, parent):
        """創建帶命令的Checkbutton"""
        section_frame = tk.LabelFrame(parent, text="3. 帶命令的Checkbutton", 
                                     padx=10, pady=10, bg="white")
        section_frame.pack(fill=tk.X, pady=10)
        
        # 實時響應
        self.command_var = tk.BooleanVar()
        command_check = tk.Checkbutton(section_frame, text="實時響應複選框", 
                                      variable=self.command_var, 
                                      command=self.on_command_change, bg="white")
        command_check.pack(anchor="w", pady=2)
        
        # 命令結果顯示
        self.command_result = tk.Label(section_frame, text="狀態: 未選中", 
                                      bg="white", fg="red")
        self.command_result.pack(anchor="w", pady=5)
        
        # 帶參數的命令
        self.param_vars = []
        param_frame = tk.Frame(section_frame, bg="white")
        param_frame.pack(fill=tk.X, pady=5)
        
        tk.Label(param_frame, text="帶參數命令:", bg="white").pack(anchor="w")
        
        for i in range(3):
            var = tk.BooleanVar()
            self.param_vars.append(var)
            check = tk.Checkbutton(param_frame, text=f"選項 {i+1}", 
                                  variable=var,
                                  command=lambda idx=i: self.on_param_change(idx), 
                                  bg="white")
            check.pack(anchor="w", pady=1)
            
    def create_styled_checkbuttons(self, parent):
        """創建樣式化Checkbutton"""
        section_frame = tk.LabelFrame(parent, text="4. 樣式化Checkbutton", 
                                     padx=10, pady=10, bg="white")
        section_frame.pack(fill=tk.X, pady=10)
        
        # 不同顏色
        self.color_var = tk.BooleanVar()
        color_check = tk.Checkbutton(section_frame, text="紅色複選框", 
                                    variable=self.color_var,
                                    bg="white", fg="red", 
                                    selectcolor="lightcoral",
                                    activebackground="lightpink",
                                    activeforeground="darkred")
        color_check.pack(anchor="w", pady=2)
        
        # 不同字體
        self.font_var = tk.BooleanVar()
        font_check = tk.Checkbutton(section_frame, text="粗體複選框", 
                                   variable=self.font_var,
                                   bg="white", font=("Arial", 10, "bold"))
        font_check.pack(anchor="w", pady=2)
        
        # 帶圖標的Checkbutton
        self.icon_var = tk.BooleanVar()
        icon_check = tk.Checkbutton(section_frame, text="⭐ 帶圖標的複選框", 
                                   variable=self.icon_var, bg="white")
        icon_check.pack(anchor="w", pady=2)
        
        # 指示器位置
        self.indicator_var = tk.BooleanVar()
        indicator_check = tk.Checkbutton(section_frame, text="指示器在右側", 
                                        variable=self.indicator_var,
                                        indicatoron=False,  # 使用按鈕樣式
                                        bg="white")
        indicator_check.pack(anchor="w", pady=2)
        
    def create_practical_example(self, parent):
        """創建實際應用示例"""
        section_frame = tk.LabelFrame(parent, text="5. 實際應用示例", 
                                     padx=10, pady=10, bg="white")
        section_frame.pack(fill=tk.BOTH, expand=True, pady=10)
        
        # 設置選擇
        tk.Label(section_frame, text="選擇你的興趣:", bg="white", 
                font=("Arial", 10, "bold")).pack(anchor="w", pady=5)
        
        self.interests = []
        interests_list = ["編程", "閲讀", "音樂", "運動", "旅遊", "攝影", "美食", "遊戲"]
        
        for interest in interests_list:
            var = tk.BooleanVar()
            self.interests.append((interest, var))
            check = tk.Checkbutton(section_frame, text=interest, variable=var, bg="white")
            check.pack(anchor="w", pady=1)
            
        # 選擇結果
        result_btn = tk.Button(section_frame, text="顯示選擇的興趣", 
                              command=self.show_interests)
        result_btn.pack(anchor="w", pady=10)
        
        self.interest_result = tk.Label(section_frame, text="", bg="white", 
                                       wraplength=400, justify="left")
        self.interest_result.pack(anchor="w", fill=tk.X)
        
    def show_basic_states(self):
        """顯示基本Checkbutton狀態"""
        result = f"""
        選項1 (BooleanVar): {self.var1.get()}
        選項2 (IntVar): {self.var2.get()}
        選項3 (StringVar): {self.var3.get()}
        """
        print(result)
        
    def on_command_change(self):
        """命令回調函數"""
        state = "選中" if self.command_var.get() else "未選中"
        color = "green" if self.command_var.get() else "red"
        self.command_result.config(text=f"狀態: {state}", fg=color)
        
    def on_param_change(self, index):
        """帶參數的命令回調"""
        state = "選中" if self.param_vars[index].get() else "未選中"
        print(f"選項 {index+1} 被{state}")
        
    def enable_all(self):
        """啓用所有Checkbutton"""
        for widget in self.root.winfo_children():
            if isinstance(widget, tk.LabelFrame):
                for child in widget.winfo_children():
                    if isinstance(child, tk.Checkbutton):
                        child.config(state="normal")
                        
    def disable_all(self):
        """禁用所有Checkbutton"""
        for widget in self.root.winfo_children():
            if isinstance(widget, tk.LabelFrame):
                for child in widget.winfo_children():
                    if isinstance(child, tk.Checkbutton):
                        child.config(state="disabled")
                        
    def toggle_readonly(self):
        """切換隻讀狀態"""
        for widget in self.root.winfo_children():
            if isinstance(widget, tk.LabelFrame):
                for child in widget.winfo_children():
                    if isinstance(child, tk.Checkbutton) and "只讀狀態" in child.cget("text"):
                        current_state = child.cget("state")
                        new_state = "normal" if current_state == "readonly" else "readonly"
                        child.config(state=new_state)
                        
    def show_interests(self):
        """顯示選擇的興趣"""
        selected = [interest for interest, var in self.interests if var.get()]
        if selected:
            result = f"你選擇的興趣: {', '.join(selected)}"
        else:
            result = "你沒有選擇任何興趣"
        self.interest_result.config(text=result)

if __name__ == "__main__":
    root = tk.Tk()
    app = CheckbuttonComprehensive(root)
    root.mainloop()

實際應用示例

示例2:設置對話框

import tkinter as tk
from tkinter import messagebox

class SettingsDialog:
    def __init__(self, root):
        self.root = root
        self.setup_ui()
        
    def setup_ui(self):
        """設置用户界面"""
        self.root.title("應用程序設置")
        self.root.geometry("500x450")
        self.root.resizable(False, False)
        
        # 創建主Frame
        main_frame = tk.Frame(self.root, padx=20, pady=20, bg="#f5f5f5")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 標題
        title_label = tk.Label(main_frame, text="應用程序設置", 
                              font=("Arial", 16, "bold"), bg="#f5f5f5")
        title_label.pack(pady=(0, 20))
        
        # 常規設置
        self.create_general_settings(main_frame)
        
        # 隱私設置
        self.create_privacy_settings(main_frame)
        
        # 通知設置
        self.create_notification_settings(main_frame)
        
        # 按鈕區域
        self.create_buttons(main_frame)
        
    def create_general_settings(self, parent):
        """創建常規設置"""
        frame = tk.LabelFrame(parent, text="常規設置", padx=15, pady=15, 
                             font=("Arial", 10, "bold"), bg="white")
        frame.pack(fill=tk.X, pady=10)
        
        # 開機啓動
        self.auto_start = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="開機自動啓動", variable=self.auto_start, 
                      bg="white").pack(anchor="w", pady=2)
        
        # 顯示啓動畫面
        self.show_splash = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="顯示啓動畫面", variable=self.show_splash, 
                      bg="white").pack(anchor="w", pady=2)
        
        # 最小化到系統托盤
        self.minimize_to_tray = tk.BooleanVar()
        tk.Checkbutton(frame, text="最小化到系統托盤", variable=self.minimize_to_tray, 
                      bg="white").pack(anchor="w", pady=2)
        
        # 自動檢查更新
        self.auto_update = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="自動檢查更新", variable=self.auto_update, 
                      bg="white").pack(anchor="w", pady=2)
        
    def create_privacy_settings(self, parent):
        """創建隱私設置"""
        frame = tk.LabelFrame(parent, text="隱私設置", padx=15, pady=15, 
                             font=("Arial", 10, "bold"), bg="white")
        frame.pack(fill=tk.X, pady=10)
        
        # 數據收集
        self.collect_usage_data = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="發送匿名使用數據", 
                      variable=self.collect_usage_data, bg="white").pack(anchor="w", pady=2)
        
        # 錯誤報告
        self.send_crash_reports = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="自動發送錯誤報告", 
                      variable=self.send_crash_reports, bg="white").pack(anchor="w", pady=2)
        
        # 個性化廣告
        self.personalized_ads = tk.BooleanVar()
        tk.Checkbutton(frame, text="顯示個性化廣告", 
                      variable=self.personalized_ads, bg="white").pack(anchor="w", pady=2)
        
        # 保存搜索歷史
        self.save_search_history = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="保存搜索歷史", 
                      variable=self.save_search_history, bg="white").pack(anchor="w", pady=2)
        
    def create_notification_settings(self, parent):
        """創建通知設置"""
        frame = tk.LabelFrame(parent, text="通知設置", padx=15, pady=15, 
                             font=("Arial", 10, "bold"), bg="white")
        frame.pack(fill=tk.X, pady=10)
        
        # 郵件通知
        self.email_notifications = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="郵件通知", variable=self.email_notifications, 
                      bg="white").pack(anchor="w", pady=2)
        
        # 推送通知
        self.push_notifications = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="推送通知", variable=self.push_notifications, 
                      bg="white").pack(anchor="w", pady=2)
        
        # 聲音提醒
        self.sound_alerts = tk.BooleanVar()
        tk.Checkbutton(frame, text="聲音提醒", variable=self.sound_alerts, 
                      bg="white").pack(anchor="w", pady=2)
        
        # 桌面通知
        self.desktop_notifications = tk.BooleanVar(value=True)
        tk.Checkbutton(frame, text="桌面通知", variable=self.desktop_notifications, 
                      bg="white").pack(anchor="w", pady=2)
        
    def create_buttons(self, parent):
        """創建按鈕區域"""
        button_frame = tk.Frame(parent, bg="#f5f5f5")
        button_frame.pack(fill=tk.X, pady=20)
        
        # 保存按鈕
        save_btn = tk.Button(button_frame, text="保存設置", bg="#4CAF50", 
                           fg="white", font=("Arial", 10), padx=20,
                           command=self.save_settings)
        save_btn.pack(side=tk.RIGHT, padx=5)
        
        # 重置按鈕
        reset_btn = tk.Button(button_frame, text="重置默認", bg="#f44336", 
                            fg="white", font=("Arial", 10), padx=20,
                            command=self.reset_settings)
        reset_btn.pack(side=tk.RIGHT, padx=5)
        
        # 取消按鈕
        cancel_btn = tk.Button(button_frame, text="取消", bg="#9E9E9E", 
                             fg="white", font=("Arial", 10), padx=20,
                             command=self.root.destroy)
        cancel_btn.pack(side=tk.RIGHT, padx=5)
        
    def save_settings(self):
        """保存設置"""
        settings = {
            "auto_start": self.auto_start.get(),
            "show_splash": self.show_splash.get(),
            "minimize_to_tray": self.minimize_to_tray.get(),
            "auto_update": self.auto_update.get(),
            "collect_usage_data": self.collect_usage_data.get(),
            "send_crash_reports": self.send_crash_reports.get(),
            "personalized_ads": self.personalized_ads.get(),
            "save_search_history": self.save_search_history.get(),
            "email_notifications": self.email_notifications.get(),
            "push_notifications": self.push_notifications.get(),
            "sound_alerts": self.sound_alerts.get(),
            "desktop_notifications": self.desktop_notifications.get()
        }
        
        # 在實際應用中,這裏會將設置保存到配置文件或數據庫
        print("保存的設置:", settings)
        messagebox.showinfo("成功", "設置已保存!")
        
    def reset_settings(self):
        """重置為默認設置"""
        self.auto_start.set(True)
        self.show_splash.set(True)
        self.minimize_to_tray.set(False)
        self.auto_update.set(True)
        self.collect_usage_data.set(True)
        self.send_crash_reports.set(True)
        self.personalized_ads.set(False)
        self.save_search_history.set(True)
        self.email_notifications.set(True)
        self.push_notifications.set(True)
        self.sound_alerts.set(False)
        self.desktop_notifications.set(True)
        
        messagebox.showinfo("重置", "設置已重置為默認值!")

if __name__ == "__main__":
    root = tk.Tk()
    app = SettingsDialog(root)
    root.mainloop()

示例3:動態問卷調查

import tkinter as tk
from tkinter import messagebox
import json

class DynamicSurvey:
    def __init__(self, root):
        self.root = root
        self.current_question = 0
        self.answers = {}
        self.questions = self.load_questions()
        self.setup_ui()
        
    def load_questions(self):
        """加載問題數據"""
        questions = [
            {
                "id": 1,
                "text": "你使用哪些編程語言?",
                "type": "multiple",
                "options": ["Python", "JavaScript", "Java", "C++", "Go", "Rust", "其他"]
            },
            {
                "id": 2,
                "text": "你使用哪些開發工具?",
                "type": "multiple",
                "options": ["VS Code", "PyCharm", "IntelliJ", "Vim", "Sublime Text", "其他編輯器"]
            },
            {
                "id": 3,
                "text": "你參與過哪些類型的項目?",
                "type": "multiple",
                "options": ["Web開發", "數據分析", "機器學習", "移動開發", "桌面應用", "遊戲開發"]
            },
            {
                "id": 4,
                "text": "你使用哪些操作系統?",
                "type": "multiple",
                "options": ["Windows", "macOS", "Linux", "其他"]
            }
        ]
        return questions
        
    def setup_ui(self):
        """設置用户界面"""
        self.root.title("動態問卷調查")
        self.root.geometry("600x500")
        self.root.configure(bg="#f0f8ff")
        
        # 標題
        title_frame = tk.Frame(self.root, bg="#f0f8ff")
        title_frame.pack(pady=20)
        
        self.title_label = tk.Label(title_frame, text="開發者問卷調查", 
                                   font=("Arial", 18, "bold"), bg="#f0f8ff")
        self.title_label.pack()
        
        self.progress_label = tk.Label(title_frame, text="", 
                                      font=("Arial", 10), bg="#f0f8ff", fg="#666")
        self.progress_label.pack()
        
        # 問題顯示區域
        self.question_frame = tk.Frame(self.root, bg="white", relief=tk.GROOVE, bd=1)
        self.question_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        
        # 按鈕區域
        self.button_frame = tk.Frame(self.root, bg="#f0f8ff")
        self.button_frame.pack(fill=tk.X, padx=20, pady=10)
        
        # 初始化顯示第一個問題
        self.show_question()
        
    def show_question(self):
        """顯示當前問題"""
        # 清除之前的問題
        for widget in self.question_frame.winfo_children():
            widget.destroy()
            
        # 清除按鈕
        for widget in self.button_frame.winfo_children():
            widget.destroy()
            
        if self.current_question >= len(self.questions):
            self.show_results()
            return
            
        question = self.questions[self.current_question]
        
        # 更新進度
        self.progress_label.config(
            text=f"問題 {self.current_question + 1}/{len(self.questions)}"
        )
        
        # 顯示問題文本
        question_label = tk.Label(self.question_frame, text=question["text"], 
                                 font=("Arial", 12, "bold"), bg="white", 
                                 wraplength=500, justify="left")
        question_label.pack(anchor="w", pady=20, padx=20)
        
        # 創建複選框
        self.current_vars = []
        for option in question["options"]:
            var = tk.BooleanVar()
            self.current_vars.append((option, var))
            
            check = tk.Checkbutton(self.question_frame, text=option, 
                                  variable=var, bg="white", font=("Arial", 10),
                                  anchor="w", justify="left")
            check.pack(anchor="w", pady=5, padx=40, fill=tk.X)
            
        # 創建導航按鈕
        if self.current_question > 0:
            prev_btn = tk.Button(self.button_frame, text="上一題", 
                               bg="#2196F3", fg="white", font=("Arial", 10),
                               command=self.previous_question)
            prev_btn.pack(side=tk.LEFT, padx=5)
            
        if self.current_question < len(self.questions) - 1:
            next_btn = tk.Button(self.button_frame, text="下一題", 
                               bg="#4CAF50", fg="white", font=("Arial", 10),
                               command=self.next_question)
            next_btn.pack(side=tk.RIGHT, padx=5)
        else:
            submit_btn = tk.Button(self.button_frame, text="提交問卷", 
                                 bg="#FF9800", fg="white", font=("Arial", 10),
                                 command=self.next_question)
            submit_btn.pack(side=tk.RIGHT, padx=5)
            
        # 跳過按鈕
        skip_btn = tk.Button(self.button_frame, text="跳過", 
                           bg="#9E9E9E", fg="white", font=("Arial", 10),
                           command=self.next_question)
        skip_btn.pack(side=tk.RIGHT, padx=5)
        
    def next_question(self):
        """轉到下一題"""
        self.save_current_answers()
        self.current_question += 1
        self.show_question()
        
    def previous_question(self):
        """轉到上一題"""
        self.save_current_answers()
        self.current_question -= 1
        self.show_question()
        
    def save_current_answers(self):
        """保存當前問題的答案"""
        if self.current_question < len(self.questions):
            question = self.questions[self.current_question]
            selected_options = [option for option, var in self.current_vars if var.get()]
            self.answers[question["id"]] = {
                "question": question["text"],
                "answer": selected_options
            }
            
    def show_results(self):
        """顯示調查結果"""
        # 清除界面
        for widget in self.question_frame.winfo_children():
            widget.destroy()
            
        for widget in self.button_frame.winfo_children():
            widget.destroy()
            
        self.title_label.config(text="調查完成!")
        self.progress_label.config(text="感謝您的參與")
        
        # 顯示結果
        result_text = tk.Text(self.question_frame, wrap=tk.WORD, font=("Arial", 10),
                             bg="white", padx=20, pady=20)
        result_text.pack(fill=tk.BOTH, expand=True)
        
        result_text.insert(tk.END, "你的回答總結:\n\n")
        
        for qid, answer_data in self.answers.items():
            result_text.insert(tk.END, f"{answer_data['question']}\n")
            if answer_data["answer"]:
                result_text.insert(tk.END, f"  選擇: {', '.join(answer_data['answer'])}\n")
            else:
                result_text.insert(tk.END, "  未選擇任何選項\n")
            result_text.insert(tk.END, "\n")
            
        result_text.config(state=tk.DISABLED)
        
        # 添加滾動條
        scrollbar = tk.Scrollbar(self.question_frame, command=result_text.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        result_text.config(yscrollcommand=scrollbar.set)
        
        # 重新開始按鈕
        restart_btn = tk.Button(self.button_frame, text="重新開始", 
                              bg="#4CAF50", fg="white", font=("Arial", 10),
                              command=self.restart_survey)
        restart_btn.pack(side=tk.RIGHT, padx=5)
        
        # 導出按鈕
        export_btn = tk.Button(self.button_frame, text="導出結果", 
                             bg="#2196F3", fg="white", font=("Arial", 10),
                             command=self.export_results)
        export_btn.pack(side=tk.RIGHT, padx=5)
        
    def restart_survey(self):
        """重新開始調查"""
        self.current_question = 0
        self.answers = {}
        self.title_label.config(text="開發者問卷調查")
        self.show_question()
        
    def export_results(self):
        """導出結果"""
        try:
            with open("survey_results.json", "w", encoding="utf-8") as f:
                json.dump(self.answers, f, ensure_ascii=False, indent=2)
            messagebox.showinfo("導出成功", "結果已導出到 survey_results.json")
        except Exception as e:
            messagebox.showerror("導出失敗", f"導出時發生錯誤: {str(e)}")

if __name__ == "__main__":
    root = tk.Tk()
    app = DynamicSurvey(root)
    root.mainloop()

Checkbutton的主要方法和屬性

# 創建Checkbutton
checkbutton = tk.Checkbutton(parent, **options)

# 主要配置選項
checkbutton.config(
    text="選項文本",          # 顯示的文本
    variable=var,            # 關聯的變量 (BooleanVar, IntVar, StringVar)
    onvalue=1,               # 選中時的值 (StringVar/IntVar使用)
    offvalue=0,              # 未選中時的值 (StringVar/IntVar使用)
    command=callback,        # 狀態改變時的回調函數
    state="normal",          # 狀態: normal, disabled, active
    bg="white",              # 背景色
    fg="black",              # 前景色
    selectcolor="color",     # 選中時的背景色
    font=("Arial", 10),      # 字體
    padx=10,                 # 水平內邊距
    pady=5,                  # 垂直內邊距
    anchor="w",              # 文本對齊
    justify="left",          # 多行文本對齊
    indicatoron=True,        # 是否顯示指示器
    wraplength=200           # 文本換行長度
)

# 主要方法
checkbutton.select()         # 選中複選框
checkbutton.deselect()       # 取消選中
checkbutton.toggle()         # 切換狀態
checkbutton.invoke()         # 調用關聯的命令
checkbutton.flash()          # 閃爍顯示

# 狀態檢查
checkbutton.cget("text")     # 獲取配置值
var.get()                    # 獲取選中狀態

# 事件綁定
checkbutton.bind("<Button-1>", callback)  # 鼠標點擊事件

使用場景總結

  1. 設置對話框:應用程序的各種開關設置
  2. 問卷調查:多選問題的答案收集
  3. 過濾器:數據篩選和條件選擇
  4. 功能開關:啓用或禁用特定功能
  5. 偏好設置:用户個性化偏好配置
  6. 批量操作:選擇多個項目進行批量處理
  7. 權限管理:角色和權限的多選配置

Checkbutton是創建用户交互界面的重要組件,特別適合需要多選操作的場景。通過合理使用Checkbutton,可以創建出功能豐富、用户友好的應用程序界面。