测试修改
This commit is contained in:
@ -458,52 +458,65 @@ class WaterQualityGUI(QMainWindow):
|
||||
# ================================================================
|
||||
|
||||
def _on_step_list_changed(self, index):
|
||||
"""左侧导航 → 右侧 Tab 单向路由(Tab 头部已隐藏,无反向同步)。"""
|
||||
if index < 0:
|
||||
return
|
||||
from PyQt5.QtCore import Qt
|
||||
if index < 0: return
|
||||
item = self._step_list.item(index)
|
||||
if not item:
|
||||
return
|
||||
if not item: return
|
||||
item_data = item.data(Qt.UserRole)
|
||||
if item_data == "stage_header" or item_data is None:
|
||||
return
|
||||
from src.gui.core.panel_registry import get_tab_index
|
||||
|
||||
if item_data in (None, "stage_header"): return # 跳过阶段标题
|
||||
|
||||
from src.gui.core.panel_registry import get_tab_index, PANEL_REGISTRY
|
||||
tab_index = get_tab_index(item_data)
|
||||
if tab_index < 0:
|
||||
return
|
||||
if tab_index < 0: return
|
||||
|
||||
try:
|
||||
# 先触发懒加载再切 Tab,避免 removeTab/insertTab 与导航事件重叠
|
||||
# 1. 触发懒加载生成面板
|
||||
self._panel_factory.get_panel(item_data)
|
||||
self._tab_widget.setCurrentIndex(tab_index)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
QMessageBox.critical(self, "面板加载失败",
|
||||
f"加载页面时发生严重错误:\n{e}\n\n详见终端日志。")
|
||||
|
||||
# 🚨 核心防卡死补丁:如果目标 Tab 被后台任务异常永久锁定,强制撬开!
|
||||
if not self._tab_widget.isTabEnabled(tab_index):
|
||||
self._log_manager.info(f"检测到 {item_data} 处于异常锁定状态,已执行强制解锁。")
|
||||
self._tab_widget.setTabEnabled(tab_index, True)
|
||||
|
||||
# ====== 终极状态回滚机制 ======
|
||||
self._step_list.blockSignals(True)
|
||||
# 【新增修复】:在跳之前,再核实一遍要去的 tab_index 和 item_data 的 step_id 是否吻合!
|
||||
# 如果因为删除了死文件导致索引错位,这里强行用真实 step_id 再找一遍!
|
||||
try:
|
||||
current_tab_idx = self._tab_widget.currentIndex()
|
||||
from src.gui.core.panel_registry import PANEL_REGISTRY
|
||||
if 0 <= current_tab_idx < len(PANEL_REGISTRY):
|
||||
correct_step_id = PANEL_REGISTRY[current_tab_idx]['step_id']
|
||||
for i in range(self._step_list.count()):
|
||||
item_node = self._step_list.item(i)
|
||||
if item_node and item_node.data(Qt.UserRole) == correct_step_id:
|
||||
self._step_list.setCurrentRow(i)
|
||||
self._panel_factory.get_panel(item_data)
|
||||
# 遍历右侧所有已加载的 Tab,找到属于当前 step_id 的那个正确的 Tab 索引
|
||||
for i in range(self._tab_widget.count()):
|
||||
scroll_area = self._tab_widget.widget(i)
|
||||
if scroll_area and hasattr(scroll_area, 'widget'):
|
||||
real_panel = scroll_area.widget()
|
||||
# 如果这个 panel 就是我们要找的 panel,强制更新 tab_index
|
||||
if real_panel == self._panel_factory.get_panel(item_data):
|
||||
tab_index = i
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
except Exception as e:
|
||||
self._log_manager.error(f"页面实例化失败: {str(e)}")
|
||||
return
|
||||
|
||||
# 2. 强制使用注册表的固定索引进行跳转
|
||||
self._tab_widget.setCurrentIndex(tab_index)
|
||||
|
||||
# 【新增修复】:每次切页时,强制重播所有面板的输入值!
|
||||
# 原理:打破 preload_window 造成的时序差,确保目标页面能拿到源页面最新填写的值
|
||||
if hasattr(self, '_panel_factory'):
|
||||
self._panel_factory._replay_live_panel_inputs()
|
||||
|
||||
# 3. 防撕裂回弹机制:如果由于某种原因没跳过去,把左边的蓝条强行拽回当前真实页面
|
||||
if self._tab_widget.currentIndex() != tab_index:
|
||||
self._step_list.blockSignals(True)
|
||||
current_step_id = PANEL_REGISTRY[self._tab_widget.currentIndex()]['step_id']
|
||||
for i in range(self._step_list.count()):
|
||||
list_item = self._step_list.item(i)
|
||||
if list_item and list_item.data(Qt.UserRole) == current_step_id:
|
||||
self._step_list.setCurrentRow(i)
|
||||
break
|
||||
self._step_list.blockSignals(False)
|
||||
|
||||
return
|
||||
|
||||
# 动态更新上一步/下一步按钮可用状态
|
||||
self._prev_btn.setEnabled(self._find_prev_step_row(index) is not None)
|
||||
self._next_btn.setEnabled(self._find_next_step_row(index) is not None)
|
||||
|
||||
except Exception as e:
|
||||
self._log_manager.error(f"页面跳转失败: {str(e)}")
|
||||
|
||||
def _find_prev_step_row(self, current_row):
|
||||
"""从 current_row 向上遍历,跳过 stage_header 和空分隔符,返回上一个有效 step 的行号。"""
|
||||
|
||||
Reference in New Issue
Block a user