From f851b80ea8d9cd808628163d0b4b4b3230bcf8d3 Mon Sep 17 00:00:00 2001 From: 27942 <1313123@342> Date: Mon, 26 Jan 2026 01:38:36 +0800 Subject: [PATCH] =?UTF-8?q?gui=20=E7=AC=AC=E4=B8=80=E7=89=88=E5=AE=8C?= =?UTF-8?q?=E6=95=B4=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gui_app.py | 294 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 249 insertions(+), 45 deletions(-) diff --git a/gui_app.py b/gui_app.py index 213ab18..c7ef924 100644 --- a/gui_app.py +++ b/gui_app.py @@ -773,11 +773,27 @@ class MainWindow(QMainWindow): self.log_match_index = -1 self.is_updating_table = False self._is_closing = False # 标记是否正在关闭窗口 + self._column_width_ratios = {} # 存储列宽比例,用于自动调整 + self._is_manual_resize = False # 标记是否正在手动调整列宽 # 任务执行时用于“多多ID+序号 -> 行号”的映射(用于精确回写状态) self._row_map_by_user_index = {} self.init_ui() def init_ui(self): + # 初始化列宽调整相关的变量和定时器 + if not hasattr(self, '_table_view_column_width_ratios'): + self._table_view_column_width_ratios = {} + if not hasattr(self, '_is_table_view_manual_resize'): + self._is_table_view_manual_resize = False + if not hasattr(self, '_resize_timer'): + self._resize_timer = QTimer() + self._resize_timer.setSingleShot(True) + self._resize_timer.timeout.connect(self._delayed_update_ratios) + if not hasattr(self, '_table_view_resize_timer'): + self._table_view_resize_timer = QTimer() + self._table_view_resize_timer.setSingleShot(True) + self._table_view_resize_timer.timeout.connect(self._delayed_update_table_view_ratios) + self.setWindowTitle("拼多多自动化发布工具") self.setGeometry(100, 100, 1000, 800) @@ -1170,12 +1186,11 @@ class MainWindow(QMainWindow): if self._filter_table_columns and self._filter_table_columns[0] == 1: self.table_column_filter.setCurrentIndex(1) header = self.config_table.horizontalHeader() - header.setStretchLastSection(False) - # 设置列的调整模式 - header.setSectionResizeMode(QHeaderView.Interactive) # 默认交互模式 - # 多多ID和序号列自动拉伸填充剩余空间 - header.setSectionResizeMode(1, QHeaderView.Stretch) # 多多ID - header.setSectionResizeMode(2, QHeaderView.Stretch) # 序号 + header.setStretchLastSection(True) + # 设置所有列为Interactive模式,允许用户拖拽调整宽度 + header.setSectionResizeMode(QHeaderView.Interactive) + # 设置最小列宽,确保内容可见 + header.setMinimumSectionSize(50) # 设置文本省略模式(超长文本显示省略号) self.config_table.setTextElideMode(Qt.ElideRight) self.config_table.setAlternatingRowColors(True) @@ -1191,6 +1206,10 @@ class MainWindow(QMainWindow): self.config_table.customContextMenuRequested.connect(self.show_table_context_menu) self.config_table.itemChanged.connect(self.on_table_item_changed) self.config_table.horizontalHeader().sectionClicked.connect(self.on_header_clicked) + # 连接列宽调整信号,用于跟踪手动调整和自动调整 + self.config_table.horizontalHeader().sectionResized.connect(self.on_column_resized) + # 连接表格resize事件,用于自动按比例调整列宽 + self.config_table.horizontalHeader().geometriesChanged.connect(self.on_table_geometry_changed) # 设置表格最小高度,确保显示更多行 self.config_table.setMinimumHeight(600) # 最小高度600像素 # 点击空白区域或按Esc键时退出编辑状态 @@ -1318,6 +1337,9 @@ class MainWindow(QMainWindow): self.log_match_status = QLabel("匹配: 0") self.log_match_status.setStyleSheet("color: #666; font-size: 10px;") log_header.addWidget(self.log_match_status) + + # 初始化表格列宽比例 + QTimer.singleShot(100, self._apply_table_column_widths) self.log_export_btn = PushButton("导出日志") self.log_export_btn.clicked.connect(self.export_log) log_header.addWidget(self.log_export_btn) @@ -2794,51 +2816,230 @@ class MainWindow(QMainWindow): self.log_match_status.setText(f"匹配: {count}") def _apply_table_column_widths(self): - """应用配置表列宽(多多ID和序号自适应,操作列无留白)""" - widths = { + """应用配置表列宽(根据内容自适应,所有列按比例填充剩余空间)""" + header = self.config_table.horizontalHeader() + header.setStretchLastSection(True) + + # 先使用ResizeToContents模式根据内容自适应列宽 + header.setSectionResizeMode(QHeaderView.ResizeToContents) + + # 设置最小列宽,确保内容可见 + min_widths = { 0: 50, # 勾选框 - # 1: 多多ID - Stretch模式,自适应 - # 2: 序号 - Stretch模式,自适应 - 3: 160, # 话题 - 4: 160, # 定时发布 - 5: 110, # 间隔时间 - 6: 200, # 达人链接(固定宽度,超长显示省略号) - 7: 120, # 执行人 - 8: 100, # 情况 - 9: 220, # 文件路径 - 10: 90, # 进度 - 11: 140 # 操作 + 1: 80, # 多多ID + 2: 60, # 序号 + 3: 100, # 话题 + 4: 100, # 定时发布 + 5: 80, # 间隔时间 + 6: 120, # 达人链接 + 7: 80, # 执行人 + 8: 80, # 情况 + 9: 150, # 文件路径 + 10: 70, # 进度 + 11: 100 # 操作 } - for col, width in widths.items(): + + # 应用最小宽度限制 + for col, min_width in min_widths.items(): if col < self.config_table.columnCount(): - self.config_table.setColumnWidth(col, width) - # 多多ID和序号列使用Stretch模式,会自动填充剩余空间 - # 设置最小列宽确保内容可见 - if self.config_table.columnCount() > 1: - self.config_table.setColumnWidth(1, 120) # 多多ID最小宽度 - if self.config_table.columnCount() > 2: - self.config_table.setColumnWidth(2, 80) # 序号最小宽度 + current_width = self.config_table.columnWidth(col) + if current_width < min_width: + self.config_table.setColumnWidth(col, min_width) + + # 切换到Interactive模式,允许手动拖拽调整 + header.setSectionResizeMode(0, QHeaderView.Fixed) # 勾选框固定 + for col in range(1, self.config_table.columnCount()): + header.setSectionResizeMode(col, QHeaderView.Interactive) + + # 计算并保存列宽比例(用于自动调整) + self._update_column_width_ratios() + + def _update_column_width_ratios(self): + """更新列宽比例""" + if self.config_table.columnCount() == 0: + return + + total_width = 0 + widths = {} + # 计算所有列的总宽度(不包括勾选框) + for col in range(1, self.config_table.columnCount()): + width = self.config_table.columnWidth(col) + widths[col] = width + total_width += width + + # 计算比例 + if total_width > 0: + self._column_width_ratios = {} + for col, width in widths.items(): + self._column_width_ratios[col] = width / total_width + + def _auto_resize_table_columns(self): + """根据比例自动调整表格列宽""" + if not self._column_width_ratios or self._is_manual_resize: + return + + header = self.config_table.horizontalHeader() + if header.sectionResizeMode(1) != QHeaderView.Interactive: + return + + # 获取表格可用宽度 + table_width = self.config_table.viewport().width() + checkbox_width = self.config_table.columnWidth(0) if self.config_table.columnCount() > 0 else 0 + available_width = table_width - checkbox_width + + if available_width <= 0: + return + + # 按比例分配宽度 + self._is_manual_resize = True # 临时标记,避免触发信号 + columns = sorted(self._column_width_ratios.keys()) + assigned_width = 0 + + for i, col in enumerate(columns): + if col < self.config_table.columnCount(): + ratio = self._column_width_ratios[col] + # 最后一列取剩余所有宽度,确保填满 + if i == len(columns) - 1: + new_width = max(60, available_width - assigned_width) + else: + new_width = int(available_width * ratio) + min_width = 60 + if new_width < min_width: + new_width = min_width + + self.config_table.setColumnWidth(col, new_width) + assigned_width += new_width + self._is_manual_resize = False + + def on_column_resized(self, logical_index, old_size, new_size): + """列宽调整时的回调(手动或自动)""" + if not self._is_manual_resize and logical_index > 0: + # 用户手动调整了列宽,延迟更新比例(避免拖拽时频繁更新) + self._resize_timer.stop() + self._resize_timer.start(300) # 300ms后更新比例 + + def _delayed_update_ratios(self): + """延迟更新列宽比例""" + if not self._is_manual_resize: + self._update_column_width_ratios() + + def on_table_geometry_changed(self): + """表格几何形状改变时的回调(窗口大小改变)""" + if not self._is_manual_resize: + # 延迟执行自动调整,避免频繁触发 + QTimer.singleShot(50, self._auto_resize_table_columns) def _apply_table_view_column_widths(self): - """应用 Model/View 列宽""" - widths = { - 0: 120, - 1: 80, - 2: 160, - 3: 160, - 4: 110, - 5: 200, # 达人链接(固定宽度) - 6: 120, - 7: 100, - 8: 220, - 9: 90, - 10: 140 + """应用 Model/View 列宽(根据内容自适应,所有列按比例填充剩余空间)""" + if not self.table_view.model(): + return + + header = self.table_view.horizontalHeader() + header.setStretchLastSection(True) + + # 先使用ResizeToContents模式根据内容自适应列宽 + header.setSectionResizeMode(QHeaderView.ResizeToContents) + + # 设置最小列宽,确保内容可见 + min_widths = { + 0: 80, # 多多ID + 1: 60, # 序号 + 2: 100, # 话题 + 3: 100, # 定时发布 + 4: 80, # 间隔时间 + 5: 120, # 达人链接 + 6: 80, # 执行人 + 7: 80, # 情况 + 8: 150, # 文件路径 + 9: 70, # 进度 + 10: 100 # 操作 } - for col, width in widths.items(): - if self.table_view.model() and col < self.table_view.model().columnCount(): - self.table_view.setColumnWidth(col, width) - # 所有列都可以手动调整宽度(Interactive模式) + + # 应用最小宽度限制 + for col, min_width in min_widths.items(): + if col < self.table_view.model().columnCount(): + current_width = self.table_view.columnWidth(col) + if current_width < min_width: + self.table_view.setColumnWidth(col, min_width) + + # 切换到Interactive模式,允许手动拖拽调整 + for col in range(self.table_view.model().columnCount()): + header.setSectionResizeMode(col, QHeaderView.Interactive) + + # 计算并保存列宽比例(用于自动调整) + self._update_table_view_column_width_ratios() + def _update_table_view_column_width_ratios(self): + """更新Model/View模式的列宽比例""" + if not self.table_view.model() or self.table_view.model().columnCount() == 0: + return + + total_width = 0 + widths = {} + # 计算所有列的总宽度 + for col in range(self.table_view.model().columnCount()): + width = self.table_view.columnWidth(col) + widths[col] = width + total_width += width + + # 计算比例 + if total_width > 0: + self._table_view_column_width_ratios = {} + for col, width in widths.items(): + self._table_view_column_width_ratios[col] = width / total_width + + def _auto_resize_table_view_columns(self): + """根据比例自动调整Model/View表格列宽""" + if not self._table_view_column_width_ratios or self._is_table_view_manual_resize: + return + + header = self.table_view.horizontalHeader() + if not header or header.sectionResizeMode(0) != QHeaderView.Interactive: + return + + # 获取表格可用宽度 + table_width = self.table_view.viewport().width() + if table_width <= 0: + return + + # 按比例分配宽度 + self._is_table_view_manual_resize = True # 临时标记,避免触发信号 + columns = sorted(self._table_view_column_width_ratios.keys()) + assigned_width = 0 + + for i, col in enumerate(columns): + if col < self.table_view.model().columnCount(): + ratio = self._table_view_column_width_ratios[col] + # 最后一列取剩余所有宽度,确保填满 + if i == len(columns) - 1: + new_width = max(60, table_width - assigned_width) + else: + new_width = int(table_width * ratio) + min_width = 60 + if new_width < min_width: + new_width = min_width + + self.table_view.setColumnWidth(col, new_width) + assigned_width += new_width + self._is_table_view_manual_resize = False + + def on_table_view_column_resized(self, logical_index, old_size, new_size): + """Model/View模式列宽调整时的回调(手动或自动)""" + if not self._is_table_view_manual_resize: + # 用户手动调整了列宽,延迟更新比例(避免拖拽时频繁更新) + self._table_view_resize_timer.stop() + self._table_view_resize_timer.start(300) # 300ms后更新比例 + + def _delayed_update_table_view_ratios(self): + """延迟更新Model/View模式的列宽比例""" + if not self._is_table_view_manual_resize: + self._update_table_view_column_width_ratios() + + def on_table_view_geometry_changed(self): + """Model/View模式表格几何形状改变时的回调(窗口大小改变)""" + if not self._is_table_view_manual_resize: + # 延迟执行自动调整,避免频繁触发 + QTimer.singleShot(50, self._auto_resize_table_view_columns) def _show_infobar(self, level, title, content): """显示提示条""" @@ -3190,8 +3391,11 @@ class MainWindow(QMainWindow): self._delete_row_from_view) self.table_view.setItemDelegate(self.table_delegate) header = self.table_view.horizontalHeader() - header.setStretchLastSection(False) + header.setStretchLastSection(True) header.setSectionResizeMode(QHeaderView.Interactive) + # 连接列宽调整信号,用于跟踪手动调整和自动调整 + header.sectionResized.connect(self.on_table_view_column_resized) + header.geometriesChanged.connect(self.on_table_view_geometry_changed) self._apply_table_view_column_widths() else: self.table_model.update_data(self.configs)