第一步优化勾选功能

This commit is contained in:
27942
2026-02-08 19:52:51 +08:00
parent 1def24a130
commit b8113f8e37
8 changed files with 6788 additions and 6869 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -51,6 +51,7 @@ class MainWindow(QMainWindow):
self.page_size = 20
self.current_page = 1
self.page_row_indices = []
self.filtered_config_indices = None # 文本/状态筛选后的配置索引None 表示未筛选(显示全部)
self.use_model_view = False
# 批量任务队列相关
self.batch_task_queue = [] # 任务队列
@@ -1000,16 +1001,14 @@ class MainWindow(QMainWindow):
def _clear_filter_and_selection(self):
"""清空筛选并取消所有勾选"""
# 取消所有勾选
for config in self.configs:
config['勾选'] = False
# 取消全选复选框
if hasattr(self, 'table_select_all_checkbox'):
self.table_select_all_checkbox.setChecked(False)
# 清空搜索框(会触发 filter_table 显示所有行)
self._current_status_filter = None
self.filtered_config_indices = None
# 清空搜索框会触发 filter_table(""),从而刷新为全量显示
self.table_search_input.setText("")
# 刷新表格显示
self.update_table()
self._update_checked_count()
self._show_infobar("info", "已清空", "筛选条件和勾选已清空")
@@ -1018,97 +1017,24 @@ class MainWindow(QMainWindow):
is_checked = self.table_select_all_checkbox.isChecked()
visible_count = 0
# 检查是否有筛选条件(搜索关键词或状态筛选)
has_search_filter = hasattr(self, 'table_search_input') and self.table_search_input.text().strip()
has_status_filter = hasattr(self, '_current_status_filter') and self._current_status_filter
if has_search_filter or has_status_filter:
# 有筛选条件:只操作筛选后的数据
# 遍历所有配置,只操作符合筛选条件的
for config_index, config in enumerate(self.configs):
# 检查是否符合搜索筛选(支持多关键词,所有关键词都要匹配)
if has_search_filter:
search_text = self.table_search_input.text().strip()
terms_raw = [t for t in search_text.split() if t]
if terms_raw:
# 根据当前视图类型选择列索引映射
if self.use_model_view:
column_index = self._filter_model_column_index()
col_key_map = {
0: '多多id', 1: '序号', 2: '话题', 3: '定时发布',
4: '间隔时间', 5: '达人链接', 6: '执行人', 7: '情况', 8: '文件路径'
}
else:
column_index = self._filter_column_index()
col_key_map = {
1: '多多id', 2: '序号', 3: '话题', 4: '定时发布',
5: '间隔时间', 6: '达人链接', 7: '执行人', 8: '情况', 9: '文件路径'
}
match = False
if column_index >= 0:
# 按指定列筛选
if column_index in col_key_map:
cell_value = str(config.get(col_key_map[column_index], '')).lower()
# 所有关键词都要在单元格中
if all(term.lower() in cell_value for term in terms_raw):
match = True
else:
# 全列搜索
all_text = ' '.join([str(config.get(k, '')) for k in
['多多id', '序号', '话题', '定时发布', '间隔时间',
'达人链接', '执行人', '情况', '文件路径']]).lower()
# 所有关键词都要在文本中
if all(term.lower() in all_text for term in terms_raw):
match = True
if not match:
continue
# 检查是否符合状态筛选(使用与 _filter_by_status 相同的匹配逻辑)
if has_status_filter:
config_status = config.get('情况', '待执行')
if self._current_status_filter == "成功":
status_match = "完成" in config_status or "成功" in config_status
elif self._current_status_filter == "失败":
status_match = "失败" in config_status or "错误" in config_status
else:
status_match = self._current_status_filter in config_status
if not status_match:
continue
# 符合筛选条件,更新勾选状态
self.configs[config_index]['勾选'] = is_checked
visible_count += 1
# 有筛选时只操作筛选结果filtered_config_indices否则操作全部
indices = getattr(self, 'filtered_config_indices', None)
if indices is not None:
for config_index in indices:
if 0 <= config_index < len(self.configs):
self.configs[config_index]['勾选'] = is_checked
visible_count += 1
else:
# 无筛选条件:操作所有数据(跨页)
for config_index in range(len(self.configs)):
self.configs[config_index]['勾选'] = is_checked
visible_count += 1
# 刷新表格显示
self.update_table()
self._update_checked_count()
# 更新状态统计
self._update_status_statistics()
# 重新应用筛选和高亮(保持原有的筛选状态)
if has_search_filter:
if hasattr(self, 'table_search_input') and self.table_search_input.text().strip():
self._suppress_filter_clear_once = True
self.filter_table(self.table_search_input.text())
elif has_status_filter:
# 重新应用状态筛选(隐藏不匹配的行,使用与 _filter_by_status 相同的匹配逻辑)
for row in range(self.config_table.rowCount()):
if row < len(self.page_row_indices):
config_index = self.page_row_indices[row]
if config_index < len(self.configs):
config_status = self.configs[config_index].get('情况', '待执行')
# 使用相同的状态匹配逻辑
if self._current_status_filter == "成功":
status_match = "完成" in config_status or "成功" in config_status
elif self._current_status_filter == "失败":
status_match = "失败" in config_status or "错误" in config_status
else:
status_match = self._current_status_filter in config_status
self.config_table.setRowHidden(row, not status_match)
if is_checked:
self._show_infobar("success", "提示", f"已勾选 {visible_count} 行(跨页操作)")
@@ -1720,10 +1646,10 @@ class MainWindow(QMainWindow):
suppress_clear = getattr(self, "_suppress_filter_clear_once", False)
if suppress_clear:
self._suppress_filter_clear_once = False
# 清除状态筛选,确保每次筛选基于全量数据
# 清除状态筛选,确保文本筛选基于全量数据
if hasattr(self, '_current_status_filter') and self._current_status_filter:
self._current_status_filter = None
# 先显示所有行,再根据文本筛选
self.filtered_config_indices = None
if not self.use_model_view and hasattr(self, 'config_table'):
for row in range(self.config_table.rowCount()):
self.config_table.setRowHidden(row, False)
@@ -1763,10 +1689,15 @@ class MainWindow(QMainWindow):
self.table_proxy.setFilterKeyColumn(column_index)
self.table_proxy.setFilterRegularExpression(regex)
return
if not self.config_table or self.config_table.rowCount() == 0:
if not self.config_table:
return
# 表格列与 config 键的对应(列 1~9
_table_config_keys = ('多多id', '序号', '话题', '定时发布', '间隔时间', '达人链接', '执行人', '情况', '文件路径')
if not keyword_raw:
# 清空筛选
# 清空筛选:在全量数据上显示,并清除高亮
self.filtered_config_indices = None
self.current_page = 1
self.update_table()
for row in range(self.config_table.rowCount()):
for col in range(self.config_table.columnCount()):
item = self.config_table.item(row, col)
@@ -1776,13 +1707,25 @@ class MainWindow(QMainWindow):
self.table_match_rows = []
self.table_match_index = -1
return
# 在全量 configs 上计算匹配的配置索引(不限于当前页)
terms_raw = [t for t in keyword_raw.split() if t]
keyword = keyword_raw.lower()
terms_lower = [t.lower() for t in terms_raw]
column_index = self._filter_column_index()
match_count = 0
matched_rows = []
matching_indices = []
for i, config in enumerate(self.configs):
if column_index >= 1 and column_index <= 9:
key = _table_config_keys[column_index - 1]
cell_text = str(config.get(key, ''))
else:
cell_text = ' '.join(str(config.get(k, '')) for k in _table_config_keys)
cell_compare = cell_text.lower()
if all(term in cell_compare for term in terms_lower):
matching_indices.append(i)
self.filtered_config_indices = matching_indices
self.current_page = 1
self.update_table()
# 当前页均为匹配行,应用高亮
for row in range(self.config_table.rowCount()):
match = False
for col in range(self.config_table.columnCount()):
if column_index >= 0 and col != column_index:
try:
@@ -1797,27 +1740,13 @@ class MainWindow(QMainWindow):
if item:
cell_text = item.text()
cell_compare = cell_text.lower()
if keyword:
terms = [t.lower() for t in terms_raw]
term_hit = all(term in cell_compare for term in terms)
if term_hit:
match = True
if self.table_highlight.isChecked():
item.setBackground(self._highlight_color())
match_count += 1
else:
item.setBackground(self._default_color())
if all(term in cell_compare for term in terms_lower) and self.table_highlight.isChecked():
item.setBackground(self._highlight_color())
else:
item.setBackground(self._default_color())
except RuntimeError:
# item 已被删除,跳过
continue
only_match = self.table_only_match.isChecked() if hasattr(self, 'table_only_match') else False
self.config_table.setRowHidden(row, (not match) if (keyword and only_match) else False)
if keyword and match:
matched_rows.append(row)
# 更新匹配行列表
self.table_match_rows = matched_rows
self.table_match_rows = list(range(self.config_table.rowCount()))
self.table_match_index = -1
def next_table_match(self):
@@ -2128,61 +2057,47 @@ class MainWindow(QMainWindow):
self.config_table.setRowHidden(row, False)
def _filter_by_status(self, status):
"""按状态筛选表格行"""
if not hasattr(self, 'config_table') or self.config_table.rowCount() == 0:
"""按状态筛选表格行(在全量数据上计算,分页显示筛选结果)"""
if not getattr(self, 'configs', None) or not self.configs:
self._show_infobar("warning", "提示", "暂无数据")
return
# 清除文本筛选,确保每次筛选都基于全量数据
if hasattr(self, 'table_search_input') and self.table_search_input.text().strip():
self.table_search_input.blockSignals(True)
self.table_search_input.clear()
self.table_search_input.blockSignals(False)
# 清除高亮和显示所有行
for row in range(self.config_table.rowCount()):
for col in range(self.config_table.columnCount()):
item = self.config_table.item(row, col)
if item:
item.setBackground(self._default_color())
self.config_table.setRowHidden(row, False)
self.filtered_config_indices = None
self.table_match_rows = []
self.table_match_index = -1
# 切换筛选状态
current_filter = getattr(self, '_current_status_filter', None)
if current_filter == status:
# 再次点击同一状态,取消筛选,显示全部
self._current_status_filter = None
self._show_all_rows()
self.filtered_config_indices = None
self.current_page = 1
self.update_table()
self._show_infobar("success", "提示", "已显示全部记录")
return
self._current_status_filter = status
visible_count = 0
total_count = self.config_table.rowCount()
for row in range(total_count):
item = self.config_table.item(row, 8) # 第8列是"情况"列第0列为勾选框
if item:
cell_text = item.text()
# 根据状态匹配
if status == "成功":
match = "完成" in cell_text or "成功" in cell_text
elif status == "失败":
match = "失败" in cell_text or "错误" in cell_text
else:
match = status in cell_text
self.config_table.setRowHidden(row, not match)
if match:
visible_count += 1
# 在全量 configs 上计算匹配的配置索引
matching_indices = []
for i, config in enumerate(self.configs):
config_status = str(config.get('情况', ''))
if status == "成功":
match = "完成" in config_status or "成功" in config_status
elif status == "失败":
match = "失败" in config_status or "错误" in config_status
else:
self.config_table.setRowHidden(row, True)
if visible_count == 0:
match = status in config_status
if match:
matching_indices.append(i)
self.filtered_config_indices = matching_indices
self.current_page = 1
self.update_table()
if not matching_indices:
self._show_infobar("warning", "提示", f"没有{status}的记录")
else:
self._show_infobar("success", "筛选", f"已筛选出 {visible_count}{status}记录,再次点击取消筛选")
self._show_infobar("success", "筛选", f"已筛选出 {len(matching_indices)}{status}记录,再次点击取消筛选")
def _update_status_statistics(self):
"""更新状态统计(成功/失败/待执行数量)- 统计所有配置的真实状态
@@ -2968,11 +2883,13 @@ class MainWindow(QMainWindow):
self._sync_configs_from_table()
self.is_updating_table = True
total_rows = len(self.configs)
# 使用筛选后的索引或全部索引进行分页(筛选在全量数据上计算,分页只切当前页)
effective_indices = self.filtered_config_indices if getattr(self, 'filtered_config_indices', None) is not None else list(range(len(self.configs)))
total_rows = len(effective_indices)
# 设置最小显示行数,即使没有数据也显示空行
min_display_rows = 15 # 最少显示15行
if total_rows > 1000:
if len(self.configs) > 1000:
self._setup_model_view()
self.is_updating_table = False
return
@@ -2990,7 +2907,7 @@ class MainWindow(QMainWindow):
self.current_page = total_pages
start = (self.current_page - 1) * self.page_size
end = min(start + self.page_size, total_rows)
self.page_row_indices = list(range(start, end))
self.page_row_indices = list(effective_indices[start:end])
# 临时禁用排序,防止填充数据时自动排序打乱顺序
self.config_table.setSortingEnabled(False)
@@ -3226,12 +3143,14 @@ class MainWindow(QMainWindow):
self.log_text.append(f" · {s}")
if len(no_match_log) > 20:
self.log_text.append(f" ... 还有 {len(no_match_log) - 20}")
total_rows = len(self.configs)
self.log_text.append("=" * 50)
self.log_text.append(f"更新完成!总计: {rows_with_files}/{len(self.configs)} 行匹配到文件,共 {total_found_files} 个文件")
self.log_text.append(f"更新完成!数据 {total_rows} 条,文件 {total_found_files} 个,匹配 {rows_with_files} ")
self.update_status_label.setText(f"已更新: {rows_with_files}行,{total_found_files}个文件")
status_msg = f"数据 {total_rows} 条,文件 {total_found_files} 个,匹配 {rows_with_files}"
self.update_status_label.setText(status_msg)
self.update_status_label.setStyleSheet("color: #4CAF50; font-size: 10px;")
self.set_status_cards(update_text=f"已更新: {rows_with_files}")
self.set_status_cards(update_text=status_msg)
self._update_status_statistics()
# 更新映射
@@ -3254,7 +3173,7 @@ class MainWindow(QMainWindow):
self.log_text.append("=" * 50)
self._show_infobar("success", "成功",
f"文件查找完成:{rows_with_files}行匹配,共 {total_found_files}文件")
f"数据 {total_rows} 条,文件 {total_found_files},匹配 {rows_with_files}")
return
except Exception as e: