如何在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
相关产品推荐
相关产品推荐

