第一版完整版
This commit is contained in:
27942
2026-01-26 01:38:36 +08:00
parent 78a246e19b
commit f851b80ea8

View File

@@ -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)