Commit b3b8ed72 by Yuhaibo

修改

parent 13c76314
...@@ -1211,12 +1211,28 @@ class ModelTestHandler: ...@@ -1211,12 +1211,28 @@ class ModelTestHandler:
fixed_bottoms = [bottom[1] if isinstance(bottom, (tuple, list)) else bottom for bottom in bottoms] fixed_bottoms = [bottom[1] if isinstance(bottom, (tuple, list)) else bottom for bottom in bottoms]
fixed_tops = [top[1] if isinstance(top, (tuple, list)) else top for top in tops] fixed_tops = [top[1] if isinstance(top, (tuple, list)) else top for top in tops]
# 🔥 调试:打印标注数据
print(f"\n{'='*60}")
print(f"[标注数据验证] 检查容器标注坐标")
print(f"{'='*60}")
for i in range(len(boxes)):
if i < len(fixed_bottoms) and i < len(fixed_tops):
print(f"区域{i}:")
print(f" - top (容器顶部) Y坐标: {fixed_tops[i]}")
print(f" - bottom (容器底部) Y坐标: {fixed_bottoms[i]}")
container_height_px = fixed_bottoms[i] - fixed_tops[i]
print(f" - 容器像素高度: {container_height_px}px")
if container_height_px < 0:
print(f" ⚠️ 警告:容器高度为负数!top 和 bottom 可能标反了!")
print(f"{'='*60}\n")
# 初始化检测引擎 # 初始化检测引擎
detection_engine = LiquidDetectionEngine(model_path) detection_engine = LiquidDetectionEngine(model_path)
detection_engine.load_model(model_path) detection_engine.load_model(model_path)
# 配置标注数据 # 配置标注数据
actual_heights = annotation_data[test_model_key].get('actual_heights', [20.0] * len(boxes)) actual_heights = annotation_data[test_model_key].get('actual_heights', [20.0] * len(boxes))
print(f"[标注数据验证] 容器实际高度: {actual_heights}")
detection_engine.configure(boxes, fixed_bottoms, fixed_tops, actual_heights) detection_engine.configure(boxes, fixed_bottoms, fixed_tops, actual_heights)
# 暂不创建输出视频,先进行检测以计算实际帧率 # 暂不创建输出视频,先进行检测以计算实际帧率
......
...@@ -27,11 +27,17 @@ import yaml ...@@ -27,11 +27,17 @@ import yaml
from datetime import datetime from datetime import datetime
from typing import Dict, Optional, Callable from typing import Dict, Optional, Callable
from collections import deque from collections import deque
from qtpy import QtCore
# 导入独立的ChannelThreadContext类 # 导入独立的ChannelThreadContext类
from .channel_thread_context import ChannelThreadContext from .channel_thread_context import ChannelThreadContext
class ProgressSignal(QtCore.QObject):
"""进度信号类,用于跨线程更新进度条"""
progress_updated = QtCore.Signal(int, str) # (进度值, 进度文本)
class ChannelThreadManager: class ChannelThreadManager:
"""通道线程管理器 """通道线程管理器
...@@ -378,6 +384,9 @@ class ChannelThreadManager: ...@@ -378,6 +384,9 @@ class ChannelThreadManager:
print(f"ℹ️ [跳过进度条] 单个CSV文件 ({file_size_mb:.2f}MB),直接加载") print(f"ℹ️ [跳过进度条] 单个CSV文件 ({file_size_mb:.2f}MB),直接加载")
# 🔥 创建进度对话框(仅在需要时) # 🔥 创建进度对话框(仅在需要时)
progress_dialog = None
progress_signal = None
if show_progress: if show_progress:
try: try:
from qtpy import QtWidgets, QtCore from qtpy import QtWidgets, QtCore
...@@ -403,13 +412,28 @@ class ChannelThreadManager: ...@@ -403,13 +412,28 @@ class ChannelThreadManager:
QtWidgets.QApplication.processEvents() QtWidgets.QApplication.processEvents()
print(f"✅ [进度条] 已显示进度对话框") print(f"✅ [进度条] 已显示进度对话框")
# 🔥 设置进度回调到全局曲线线程 # 🔥 创建进度信号对象并连接到槽函数
progress_signal = ProgressSignal()
progress_signal.progress_updated.connect(
lambda value, text: self._updateProgressDialog(progress_dialog, value, text)
)
# 🔥 设置进度回调到全局曲线线程(使用信号发射)
CurveThread.set_progress_callback( CurveThread.set_progress_callback(
lambda value, text: self._onCurveLoadProgress(progress_dialog, value, text) lambda value, text: progress_signal.progress_updated.emit(value, text)
) )
# 🔥 强制刷新UI,确保进度对话框完全显示
QtWidgets.QApplication.processEvents()
import time
time.sleep(0.05) # 给进度对话框50ms时间完全显示
print(f"✅ [进度条] 进度对话框已完全显示,准备启动线程")
except Exception as e: except Exception as e:
print(f"⚠️ [进度条] 创建失败: {e}") print(f"⚠️ [进度条] 创建失败: {e}")
import traceback
traceback.print_exc()
progress_dialog = None progress_dialog = None
progress_signal = None
# 使用统一的回调函数(回调函数内部根据channel_id参数区分通道) # 使用统一的回调函数(回调函数内部根据channel_id参数区分通道)
callback = self.on_curve_updated if self.on_curve_updated else None callback = self.on_curve_updated if self.on_curve_updated else None
...@@ -422,37 +446,49 @@ class ChannelThreadManager: ...@@ -422,37 +446,49 @@ class ChannelThreadManager:
daemon=True daemon=True
) )
curve_thread.start() curve_thread.start()
print(f"✅ [线程管理器] 全局曲线线程已启动")
return True return True
def _onCurveLoadProgress(self, progress_dialog, value, text): def _updateProgressDialog(self, progress_dialog, value, text):
"""处理曲线加载进度更新(确保在主线程执行)""" """更新进度对话框(通过Qt信号机制,确保在主线程执行)"""
try: try:
if not progress_dialog: if not progress_dialog:
print(f"⚠️ [进度条UI更新] 进度对话框为空,跳过更新")
return return
# 🔥 使用 QTimer.singleShot 确保在主线程执行UI更新 print(f"📊 [进度条UI更新] 开始更新进度: {value}% - {text}")
from qtpy import QtCore print(f"📊 [进度条UI更新] 当前线程: {threading.current_thread().name}")
# 🔥 直接更新进度条(已经通过信号机制在主线程中)
from qtpy import QtWidgets, QtCore
def update_ui():
try:
if progress_dialog:
progress_dialog.setValue(value) progress_dialog.setValue(value)
progress_dialog.setLabelText(text) progress_dialog.setLabelText(text)
# 强制刷新UI,确保进度条立即显示
QtWidgets.QApplication.processEvents()
print(f"✅ [进度条UI更新] 已更新进度: {value}% - {text}")
# 加载完成时关闭进度条 # 加载完成时关闭进度条
if value >= 100: if value >= 100:
progress_dialog.close() QtCore.QTimer.singleShot(100, lambda: self._closeProgressDialog(progress_dialog))
progress_dialog.deleteLater()
print(f"✅ [进度条] 加载完成,已关闭进度对话框")
except Exception as e: except Exception as e:
print(f"⚠️ [进度条] UI更新失败: {e}") print(f"⚠️ [进度条] UI更新失败: {e}")
import traceback
traceback.print_exc()
# 在主线程执行UI更新(延迟0ms,确保在主线程的事件循环中执行) def _closeProgressDialog(self, progress_dialog):
QtCore.QTimer.singleShot(0, update_ui) """关闭进度对话框"""
try:
if progress_dialog:
progress_dialog.close()
progress_dialog.deleteLater()
print(f"✅ [进度条] 加载完成,已关闭进度对话框")
except Exception as e: except Exception as e:
print(f"⚠️ [进度条] 更新失败: {e}") print(f"⚠️ [进度条] 关闭失败: {e}")
def start_storage_thread(self, channel_id: str, storage_path: str = None): def start_storage_thread(self, channel_id: str, storage_path: str = None):
"""启动存储线程 """启动存储线程
......
...@@ -287,6 +287,10 @@ class ViewHandler: ...@@ -287,6 +287,10 @@ class ViewHandler:
print(f" 索引{i}: {widget} (可见: {widget.isVisible() if widget else 'None'})") print(f" 索引{i}: {widget} (可见: {widget.isVisible() if widget else 'None'})")
# 🔥 停止所有曲线线程(切换回默认布局时)
self._stopAllCurveThreads()
print(f"[布局切换] 已停止所有曲线线程")
# 🔥 切换曲线绘制模式为实时模式 # 🔥 切换曲线绘制模式为实时模式
if hasattr(self, 'curvePanelHandler'): if hasattr(self, 'curvePanelHandler'):
self.curvePanelHandler.setCurveLoadMode('realtime') self.curvePanelHandler.setCurveLoadMode('realtime')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment