diff --git a/gui/material_validation_tab.py b/gui/material_validation_tab.py index ba41695..b24edbb 100644 --- a/gui/material_validation_tab.py +++ b/gui/material_validation_tab.py @@ -308,7 +308,7 @@ class MaterialValidationTab(ttk.Frame): manager_filter_frame = ttk.LabelFrame( main_container, text="筛选(按负责人)", - padding=10 + padding=(10, 10, 10, 10) # 左、上、右、下 - 底部padding减小 ) manager_filter_frame.pack(fill=tk.X, pady=(0, 10)) else: @@ -341,7 +341,7 @@ class MaterialValidationTab(ttk.Frame): self.source_mode = tk.StringVar(value="database_full") - # 数据库模式 + # 左侧:数据库模式单选按钮 ttk.Radiobutton( source_group, text="数据库 - 全表校验", @@ -356,15 +356,11 @@ class MaterialValidationTab(ttk.Frame): variable=self.source_mode, value="database_filtered", command=self._on_source_mode_change, - ).grid(row=0, column=1, sticky="w", padx=5) - else: - # 普通用户:默认使用 database_filtered 模式 - self.source_mode = tk.StringVar(value="database_filtered") + ).grid(row=1, column=0, sticky="w", padx=5) - # Production ID 数据源(仅 Admin) - if self.session_manager.is_admin(): - self.source_frame = ttk.Frame(parent) - self.source_frame.pack(fill=tk.X, pady=5) + # 右侧:Production ID 数据源选择区域 + self.source_frame = ttk.Frame(source_group) + self.source_frame.grid(row=0, column=1, rowspan=2, sticky="nsew", padx=(20, 0)) # Production ID 数据源选择 self.production_id_source_var = tk.StringVar(value="shared") @@ -384,24 +380,27 @@ class MaterialValidationTab(ttk.Frame): command=self._on_production_id_source_changed ).pack(side=tk.LEFT, padx=10) - # 文件选择器 + # 文件选择器(放在 source_group 下方,当选择文件时显示) self.db_filtered_production_id_selector = FileSelector( - parent, + source_group, label_text="", file_type="file", file_types=[("文本文件", "*.txt"), ("所有文件", "*.*")], initial_dir="D:/python/playwrite/", ) - self.db_filtered_production_id_selector.pack(fill=tk.X) # 共享 Production ID 提示标签 self.shared_ids_info_label = ttk.Label( - parent, + source_group, text="", foreground="blue" ) # 初始时不显示 + else: + # 普通用户:默认使用 database_filtered 模式 + self.source_mode = tk.StringVar(value="database_filtered") + # 控制按钮 button_frame = ttk.Frame(parent) button_frame.pack(fill=tk.X, pady=10) @@ -545,15 +544,15 @@ class MaterialValidationTab(ttk.Frame): if mode == "database_full": # 全表模式:隐藏所有 Production ID 相关控件 if hasattr(self, 'source_frame') and self.source_frame: - self.source_frame.pack_forget() + self.source_frame.grid_forget() if hasattr(self, 'db_filtered_production_id_selector'): - self.db_filtered_production_id_selector.pack_forget() + self.db_filtered_production_id_selector.grid_forget() if hasattr(self, 'shared_ids_info_label'): - self.shared_ids_info_label.pack_forget() + self.shared_ids_info_label.grid_forget() elif mode == "database_filtered": # 过滤模式:显示数据源选择 if hasattr(self, 'source_frame') and self.source_frame: - self.source_frame.pack(fill=tk.X, pady=5) + self.source_frame.grid(row=0, column=1, rowspan=2, sticky="nsew", padx=(20, 0)) # 根据 Production ID 数据源选择显示对应控件 self._on_production_id_source_changed() @@ -566,12 +565,12 @@ class MaterialValidationTab(ttk.Frame): source = self.production_id_source_var.get() if source == "shared": # 使用共享 Production ID - self.db_filtered_production_id_selector.pack_forget() - self.shared_ids_info_label.pack(anchor="w", pady=(0, 5)) + self.db_filtered_production_id_selector.grid_forget() + self.shared_ids_info_label.grid(row=2, column=0, columnspan=2, sticky="w", pady=(5, 0)) else: # 使用文件 - self.shared_ids_info_label.pack_forget() - self.db_filtered_production_id_selector.pack(fill=tk.X) + self.shared_ids_info_label.grid_forget() + self.db_filtered_production_id_selector.grid(row=2, column=0, columnspan=2, sticky="ew", pady=(5, 0)) def on_production_ids_updated(self, production_ids: list): """当数据提取页面的 Production ID 更新时调用""" @@ -625,38 +624,23 @@ class MaterialValidationTab(ttk.Frame): self.filter_canvas = None return - # 创建复选框容器 - canvas_container = ttk.Frame(parent) - canvas_container.pack(fill=tk.BOTH, expand=True) + # 主容器:左右两列布局 + main_container = ttk.Frame(parent) + main_container.pack(fill=tk.BOTH, expand=True) - # Canvas和滚动条 - self.filter_canvas = tk.Canvas(canvas_container, height=80) - scrollbar = ttk.Scrollbar(canvas_container, orient="vertical", command=self.filter_canvas.yview) - self.filter_frame = ttk.Frame(self.filter_canvas) + # 左侧:按钮区域(竖向排列) + button_frame = ttk.Frame(main_container) + button_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10)) - self.filter_frame.bind( - "", - lambda e: self.filter_canvas.configure(scrollregion=self.filter_frame.bbox("all")) - ) + ttk.Button(button_frame, text="全选", command=self._select_all_managers_button).pack(fill=tk.X, pady=2) + ttk.Button(button_frame, text="取消全选", command=self._deselect_all_managers_button).pack(fill=tk.X, pady=2) - self.filter_canvas.create_window((0, 0), window=self.filter_frame, anchor="nw") - self.filter_canvas.configure(yscrollcommand=scrollbar.set) + # 右侧:负责人复选框区域(简化为直接使用 Frame) + self.filter_frame = ttk.Frame(main_container) + self.filter_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) - # 布局 - self.filter_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) - scrollbar.pack(side=tk.RIGHT, fill=tk.Y) - - # 鼠标滚轮支持 - def _on_mousewheel(event): - self.filter_canvas.yview_scroll(int(-1*(event.delta/120)), "units") - self.filter_canvas.bind("", _on_mousewheel) - - # 快捷按钮 - button_frame = ttk.Frame(parent) - button_frame.pack(fill=tk.X, pady=(5, 0)) - - ttk.Button(button_frame, text="全选", command=self._select_all_managers_button).pack(side=tk.LEFT, padx=5) - ttk.Button(button_frame, text="取消全选", command=self._deselect_all_managers_button).pack(side=tk.LEFT, padx=5) + # 保留 filter_canvas 属性设为 None(兼容性考虑) + self.filter_canvas = None def _create_manager_checkboxes(self): """创建负责人复选框""" @@ -692,20 +676,12 @@ class MaterialValidationTab(ttk.Frame): items_per_column = 6 - # 全选复选框 - ttk.Checkbutton( - self.filter_frame, - text="全选", - variable=self.select_all_managers_var, - command=self._on_select_all_managers_toggle - ).grid(row=0, column=0, sticky="w", padx=5, pady=2) - # 负责人复选框 for idx, manager in enumerate(self.managers): var = tk.BooleanVar(value=True) self.manager_checkboxes[manager] = var - row = (idx // items_per_column) + 1 + row = idx // items_per_column col = idx % items_per_column ttk.Checkbutton(