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

如何在Tkinter中将8个分类器类别分为两行(每行4个)展示?

解决Tkinter中AEON分类器GUI横向过宽问题:两行布局实现方案

以下是调整后的完整代码,实现了8个分类器类别分为两行(每行4个)的布局,同时保留所有分类器选项:

import tkinter as tk
from tkinter import ttk, filedialog

class ClassifierSelectionApp:
    def __init__(self, root):
        self.root = root
        root.title("AEON时间序列分类器选择")
        style = ttk.Style()
        style.configure("TButton", font=("Arial", 11), padding=5)
        style.configure("TLabel", font=("Arial", 11))

        # 主框架
        main_frame = ttk.Frame(root, padding="10 10 10 10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        root.columnconfigure(0, weight=1)
        root.rowconfigure(0, weight=1)

        # 配置网格:4列(对应每行4个类别),预留足够行数
        for i in range(4):
            main_frame.columnconfigure(i, weight=1)
        for i in range(12):
            main_frame.rowconfigure(i, weight=1)

        # 训练数据选择
        self.label_train = ttk.Label(main_frame, text="选择训练数据:", style="TLabel")
        self.label_train.grid(row=0, column=0, sticky='w', padx=5, pady=5)
        self.button_train = ttk.Button(main_frame, text="浏览", command=self.browse_train, style="TButton")
        self.button_train.grid(row=1, column=0, padx=5, pady=5)

        # 测试数据选择
        self.label_test = ttk.Label(main_frame, text="选择测试数据:", style="TLabel")
        self.label_test.grid(row=0, column=1, sticky='w', padx=5, pady=5)
        self.button_test = ttk.Button(main_frame, text="浏览", command=self.browse_test, style="TButton")
        self.button_test.grid(row=1, column=1, padx=5, pady=5)

        # 分类器类别标签:分成两行展示
        categories = ["卷积基", "深度学习", "字典基", 
                      "距离基", "特征基", "区间基", 
                      "形状基", "混合"]
        # 第一行:前4个类别
        for i in range(4):
            label = ttk.Label(main_frame, text=categories[i], font=("Arial", 11, "bold"))
            label.grid(row=2, column=i, padx=10, pady=5, sticky='w')
        # 第二行:后4个类别
        for i in range(4):
            label = ttk.Label(main_frame, text=categories[4+i], font=("Arial", 11, "bold"))
            label.grid(row=6, column=i, padx=10, pady=5, sticky='w')

        # 分类器数据按类别分组
        # 第一行类别对应的分类器(列0-3:卷积基、深度学习、字典基、距离基)
        group1_classifiers = [
            ["Rocket Classifier", "CNN", "MUSE", "K-NN"],
            ["Arsenal", "", "WEASEL", "Elastic Ensemble"],
            ["", "", "BOSS Ensemble", ""]
        ]
        # 字典基额外分类器
        dict_extra = ["Contractable BOSS", "Individual BOSS", "Temporal Dictionary Ensemble"]
        # 第二行类别对应的分类器(列0-3:特征基、区间基、形状基、混合)
        group2_classifiers = [
            ["Catch22", "Canonical Interval Forest", "Random Forest", "HIVECOTEV2"],
            ["Fresh PRINCE", "DrCIF", "", ""],
            ["", "RandomIntervalSpectralEnsemble", "", ""],
            ["", "SupervisedTimeSeriesForest", "", ""],
            ["", "TimeSeriesForestClassifier", "", ""]
        ]

        self.check_vars = []

        # 渲染第一组分类器
        for row_idx, row in enumerate(group1_classifiers):
            var_row = []
            for col_idx, classifier in enumerate(row):
                if classifier:
                    var = tk.BooleanVar()
                    cb = ttk.Checkbutton(main_frame, text=classifier, variable=var)
                    cb.grid(row=row_idx+3, column=col_idx, padx=5, pady=2, sticky='w')
                    var_row.append(var)
                else:
                    var_row.append(None)
            self.check_vars.append(var_row)

        # 渲染字典基额外分类器
        for row_idx, classifier in enumerate(dict_extra):
            var = tk.BooleanVar()
            cb = ttk.Checkbutton(main_frame, text=classifier, variable=var)
            cb.grid(row=3+len(group1_classifiers)+row_idx, column=2, padx=5, pady=2, sticky='w')
            # 对齐check_vars索引
            while len(self.check_vars) <= row_idx+len(group1_classifiers):
                self.check_vars.append([None]*4)
            self.check_vars[row_idx+len(group1_classifiers)][2] = var

        # 渲染第二组分类器
        for row_idx, row in enumerate(group2_classifiers):
            var_row = []
            for col_idx, classifier in enumerate(row):
                if classifier:
                    var = tk.BooleanVar()
                    cb = ttk.Checkbutton(main_frame, text=classifier, variable=var)
                    cb.grid(row=row_idx+7, column=col_idx, padx=5, pady=2, sticky='w')
                    var_row.append(var)
                else:
                    var_row.append(None)
            self.check_vars.append(var_row)

    def browse_train(self):
        file_path = filedialog.askopenfilename()
        print(f"训练数据已选择: {file_path}")
        
    def browse_test(self):
        file_path = filedialog.askopenfilename()
        print(f"测试数据已选择: {file_path}")

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

关键修改说明

  • 网格布局重构:将主框架列数从8改为4,适配每行4个类别布局,同时调整行配置以容纳两行类别及对应分类器。
  • 类别标签分行:将8个类别拆分为两组,前4个放置在第3行,后4个放置在第7行,中间预留空间展示第一组分类器。
  • 分类器分组对齐:将原分类器按对应类别重新分组,针对字典基的额外分类器,单独追加到对应列的下方,保证类别与分类器的对应关系。
  • 窗口自适应:添加主窗口的行列权重配置,让界面可随窗口大小自动调整。

界面优化建议

  • 用Frame分组类别:为每个分类器类别创建独立ttk.Frame,将类别标签和复选框放入其中,提升布局层次感和可维护性。
  • 添加滚动容器:如果分类器数量较多,可将分类器区域放入滚动容器,避免窗口过长。
  • 统一组件间距:通过Style统一配置padx、pady值,减少重复代码,让界面更规整。
  • 选中状态反馈:为选中的复选框设置差异化样式,或在底部显示已选中的分类器列表,提升用户体验。
  • 设置初始窗口大小:通过root.geometry("800x700")设置窗口初始尺寸,避免默认大小不合理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 12:19:50