feat: 完善相机

This commit is contained in:
zhu-mengmeng 2025-06-30 19:40:02 +08:00
parent 336ba26bc8
commit 7023d7561a
4 changed files with 126 additions and 370 deletions

View File

@ -342,6 +342,7 @@ class InspectionDAO:
Args: Args:
order_id: 工程号 order_id: 工程号
gc_note: 工程号备注
data: 检验数据列表格式: [{'position': 1, 'config_id': 1, 'value': '合格'}, ...] data: 检验数据列表格式: [{'position': 1, 'config_id': 1, 'value': '合格'}, ...]
username: 操作用户 username: 操作用户
@ -349,17 +350,40 @@ class InspectionDAO:
bool: 保存是否成功 bool: 保存是否成功
""" """
try: try:
# 验证数据格式
if not isinstance(data, list):
logging.error(f"保存检验数据失败: data参数必须是列表实际类型为 {type(data)}")
return False
if len(data) == 0:
logging.warning("保存检验数据: 数据列表为空")
return True # 空列表视为成功,不进行任何操作
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self.db.begin_transaction() self.db.begin_transaction()
for item in data: for item in data:
# 验证item是否为字典类型
if not isinstance(item, dict):
logging.error(f"保存检验数据失败: 数据项必须是字典,实际类型为 {type(item)}")
self.db.rollback_transaction()
return False
# 使用get方法安全获取值提供默认值
position = item.get('position') position = item.get('position')
config_id = item.get('config_id') config_id = item.get('config_id')
value = item.get('value') value = item.get('value', '')
status = item.get('status', 'pass') status = item.get('status', 'pass')
remark = item.get('remark', '') remark = item.get('remark', '')
tray_id = item.get('tray_id', '') tray_id = item.get('tray_id', '')
# 验证必要字段
if position is None or config_id is None:
logging.error(f"保存检验数据失败: 缺少必要字段 position 或 config_id")
self.db.rollback_transaction()
return False
# 检查是否已存在该工程号和位置的记录 # 检查是否已存在该工程号和位置的记录
check_sql = """ check_sql = """
SELECT id FROM wsbz_inspection_data SELECT id FROM wsbz_inspection_data

View File

@ -272,9 +272,6 @@ class SerialManager:
elif port_type == 'scanner': elif port_type == 'scanner':
# 扫码器数据需要特殊处理 # 扫码器数据需要特殊处理
thread = threading.Thread(target=self._read_scanner_thread, args=(port_name,)) thread = threading.Thread(target=self._read_scanner_thread, args=(port_name,))
thread.daemon = True
thread.start()
self.read_threads[port_name] = thread
else: else:
# 其他类型使用通用处理 # 其他类型使用通用处理
thread = threading.Thread(target=self._read_thread, args=(port_name,)) thread = threading.Thread(target=self._read_thread, args=(port_name,))

View File

@ -5,11 +5,11 @@ from ctypes import *
# 确定使用哪个UI框架 # 确定使用哪个UI框架
try: try:
from PySide6.QtWidgets import QWidget, QVBoxLayout, QFrame from PySide6.QtWidgets import QWidget, QVBoxLayout, QFrame, QSizePolicy
from PySide6.QtCore import Qt, Signal, QSize from PySide6.QtCore import Qt, Signal, QSize
from PySide6.QtGui import QPalette, QColor from PySide6.QtGui import QPalette, QColor
except ImportError: except ImportError:
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QFrame from PyQt5.QtWidgets import QWidget, QVBoxLayout, QFrame, QSizePolicy
from PyQt5.QtCore import Qt, pyqtSignal as Signal, QSize from PyQt5.QtCore import Qt, pyqtSignal as Signal, QSize
from PyQt5.QtGui import QPalette, QColor from PyQt5.QtGui import QPalette, QColor
@ -48,7 +48,7 @@ class CameraDisplayWidget(QWidget):
self.resizeEvent = self.on_resize_event self.resizeEvent = self.on_resize_event
# 设置固定尺寸策略,防止超出父容器 # 设置固定尺寸策略,防止超出父容器
self.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
# 设置最小尺寸 # 设置最小尺寸
self.setMinimumSize(QSize(320, 240)) self.setMinimumSize(QSize(320, 240))
@ -68,7 +68,7 @@ class CameraDisplayWidget(QWidget):
# 设置黑色背景 # 设置黑色背景
self.frame.setStyleSheet("background-color: #000000;") self.frame.setStyleSheet("background-color: #000000;")
# 设置框架的尺寸策略 # 设置框架的尺寸策略
self.frame.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding) self.frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
# 添加到布局 # 添加到布局
layout.addWidget(self.frame) layout.addWidget(self.frame)

View File

@ -262,8 +262,9 @@ class MainWindow(MainWindowUI):
self.process_table.setContextMenuPolicy(Qt.CustomContextMenu) self.process_table.setContextMenuPolicy(Qt.CustomContextMenu)
self.process_table.customContextMenuRequested.connect(self.show_table_context_menu) self.process_table.customContextMenuRequested.connect(self.show_table_context_menu)
# 移除这里的相机信号连接在init_camera_display方法中处理 # 只有在相机启用时连接相机信号
# 相机信号会在init_camera_display中连接 if self.camera_enabled and hasattr(self, 'camera_display'):
self.camera_display.signal_camera_status.connect(self.handle_camera_status)
# 连接报表按钮点击事件 # 连接报表按钮点击事件
self.report_button.clicked.connect(self.on_report) self.report_button.clicked.connect(self.on_report)
@ -306,13 +307,8 @@ class MainWindow(MainWindowUI):
self.set_inspection_columns(1, ["检验项"]) self.set_inspection_columns(1, ["检验项"])
def show_main_page(self): def show_main_page(self):
"""显示主页面"""
try:
self.stacked_widget.setCurrentWidget(self.central_widget) self.stacked_widget.setCurrentWidget(self.central_widget)
# 先检查并更新相机状态确保UI显示与实际状态一致
self.update_camera_enabled_state()
# 更新检验列配置 # 更新检验列配置
self.update_inspection_columns() self.update_inspection_columns()
@ -320,14 +316,7 @@ class MainWindow(MainWindowUI):
self._safe_load_data() self._safe_load_data()
# 处理相机显示 # 处理相机显示
if self.camera_enabled: if self.camera_enabled and self.camera_display:
# 如果camera_display不存在先初始化相机显示组件
if not hasattr(self, 'camera_display') or self.camera_display is None:
logging.info("相机显示组件不存在,尝试初始化")
self.init_camera_display()
if self.camera_display:
try:
from widgets.camera_manager import CameraManager from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance() camera_manager = CameraManager.get_instance()
@ -345,29 +334,11 @@ class MainWindow(MainWindowUI):
# 如果相机未打开,尝试重新初始化 # 如果相机未打开,尝试重新初始化
QTimer.singleShot(100, self.initialize_camera) QTimer.singleShot(100, self.initialize_camera)
logging.info("主页面显示:尝试初始化相机") logging.info("主页面显示:尝试初始化相机")
except Exception as e:
logging.error(f"处理相机显示时发生错误: {str(e)}")
# 确保UI能正确显示占位符
if self.material_placeholder:
self.material_placeholder.setText(f"相机错误: {str(e)}")
self.update_camera_ui(False)
else:
# 相机功能未启用,确保正确显示占位符
if hasattr(self, 'material_placeholder') and self.material_placeholder:
self.material_placeholder.setText("相机功能已禁用")
self.update_camera_ui(False)
logging.info("相机功能已禁用,显示占位符")
# 加载托盘号列表 # 加载托盘号列表
self.load_pallet_codes() self.load_pallet_codes()
logging.info("显示主页面") logging.info("显示主页面")
except Exception as e:
logging.error(f"显示主页面时发生错误: {str(e)}")
# 确保基本的UI显示正常
if hasattr(self, 'material_placeholder') and self.material_placeholder:
self.material_placeholder.setText(f"初始化界面错误: {str(e)}")
self.material_placeholder.show()
def load_pallet_codes(self): def load_pallet_codes(self):
"""从托盘类型管理器加载托盘号并更新到tray_edit""" """从托盘类型管理器加载托盘号并更新到tray_edit"""
@ -415,24 +386,6 @@ class MainWindow(MainWindowUI):
# 连接设置改变信号 # 连接设置改变信号
self.settings_window.settings_changed.connect(self.on_settings_changed) self.settings_window.settings_changed.connect(self.on_settings_changed)
# 连接相机设置组件的信号
try:
# 获取相机设置组件实例
if hasattr(self.settings_window.settings_widget, 'camera_settings'):
camera_settings = self.settings_window.settings_widget.camera_settings
# 连接相机连接状态信号
camera_settings.signal_camera_connection.connect(self.handle_camera_connection)
# 连接相机参数变化信号
camera_settings.signal_camera_params_changed.connect(self.handle_camera_params_changed)
# 连接相机错误信号
camera_settings.signal_camera_error.connect(self.handle_camera_error)
logging.info("已连接相机设置组件的信号")
else:
logging.error("无法找到相机设置组件")
except Exception as e:
logging.error(f"连接相机设置组件信号时发生错误: {str(e)}")
# 显示设置窗口 # 显示设置窗口
self.settings_window.show() self.settings_window.show()
logging.info("显示设置窗口") logging.info("显示设置窗口")
@ -445,26 +398,6 @@ class MainWindow(MainWindowUI):
config_loader.load_config() config_loader.load_config()
self.config = self.load_config() # 重新加载配置到 self.config self.config = self.load_config() # 重新加载配置到 self.config
# 检查相机状态是否发生变化
logging.info("设置已变更,检查相机状态...")
try:
from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance()
camera_enabled_in_config = self.config.get('camera', {}).get('enabled', False)
# 检查相机实际状态与配置状态是否一致
if camera_manager.isOpen and not camera_enabled_in_config:
logging.info("检测到相机已打开但配置为禁用,更新配置")
self.update_camera_enabled_state(True)
elif not camera_manager.isOpen and camera_enabled_in_config:
logging.info("检测到相机已关闭但配置为启用,更新配置")
self.update_camera_enabled_state(False)
else:
# 即使状态一致也更新一次以确保UI正确
self.update_camera_enabled_state(camera_enabled_in_config)
except Exception as e:
logging.error(f"检查相机状态时发生错误: {str(e)}")
# 更新串口管理器配置 # 更新串口管理器配置
self.serial_manager.reload_config() self.serial_manager.reload_config()
@ -746,60 +679,31 @@ class MainWindow(MainWindowUI):
def handle_camera_status(self, is_connected, message): def handle_camera_status(self, is_connected, message):
"""处理相机状态变化""" """处理相机状态变化"""
try:
if is_connected: if is_connected:
logging.info("相机已连接并显示 - handle_camera_status") logging.info("相机已连接并显示")
self.update_camera_ui(True) self.update_camera_ui(True)
else: else:
if message: logging.warning(f"相机显示问题: {message}")
logging.warning(f"相机显示问题: {message} - handle_camera_status")
else:
logging.warning("相机未连接 - handle_camera_status")
# 更新占位符文本 # 更新占位符文本
if self.material_placeholder: if self.material_placeholder:
self.material_placeholder.setText(f"相机错误: {message}" if message else "相机未连接") self.material_placeholder.setText(f"相机错误: {message}" if message else "相机未连接")
self.update_camera_ui(False) self.update_camera_ui(False)
except Exception as e:
logging.error(f"处理相机状态变化时发生错误: {str(e)}")
# 确保在发生错误时,用户界面仍能正确显示
if self.material_placeholder:
self.material_placeholder.setText(f"相机状态处理错误: {str(e)}")
self.material_placeholder.show()
if self.camera_display:
self.camera_display.hide()
def handle_camera_connection(self, is_connected, message): def handle_camera_connection(self, is_connected, message):
"""处理相机连接状态变化""" """处理相机连接状态变化"""
try:
if is_connected: if is_connected:
logging.info("相机已连接") logging.info("相机已连接")
# 更新相机启用状态
self.update_camera_enabled_state(True)
# 如果当前在主页面,直接开始显示相机画面 # 如果当前在主页面,直接开始显示相机画面
if self.stacked_widget.currentWidget() == self.central_widget: if self.stacked_widget.currentWidget() == self.central_widget:
if hasattr(self, 'camera_display') and self.camera_display:
self.camera_display.start_display() self.camera_display.start_display()
else: else:
if message: if message:
logging.warning(f"相机连接失败: {message}") logging.warning(f"相机连接失败: {message}")
else: else:
logging.info("相机已断开") logging.info("相机已断开")
# 如果相机断开,确保停止显示 # 如果相机断开,确保停止显示
if hasattr(self, 'camera_display') and self.camera_display:
self.camera_display.stop_display() self.camera_display.stop_display()
# 更新相机启用状态 - 只有在明确断开时才设置为False
if not message: # 只有在主动断开时才更新状态为False
self.update_camera_enabled_state(False)
except Exception as e:
logging.error(f"处理相机连接状态变化失败: {str(e)}")
if self.material_placeholder:
self.material_placeholder.setText(f"相机连接错误: {str(e)}")
self.update_camera_ui(False)
def handle_camera_params_changed(self, exposure_time, gain, frame_rate): def handle_camera_params_changed(self, exposure_time, gain, frame_rate):
"""处理相机参数变化""" """处理相机参数变化"""
logging.info(f"相机参数已更新: 曝光={exposure_time:.1f}μs, 增益={gain:.1f}dB, 帧率={frame_rate:.1f}fps") logging.info(f"相机参数已更新: 曝光={exposure_time:.1f}μs, 增益={gain:.1f}dB, 帧率={frame_rate:.1f}fps")
@ -2871,24 +2775,6 @@ class MainWindow(MainWindowUI):
def init_camera_display(self): def init_camera_display(self):
"""初始化相机显示区域""" """初始化相机显示区域"""
try: try:
logging.info(f"开始初始化相机显示区域配置中camera_enabled={self.camera_enabled}")
logging.info(f"上料区域大小: {self.material_content.width()}x{self.material_content.height()}")
# 检查相机管理器状态,以确定相机是否实际已打开
from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance()
is_camera_actually_open = camera_manager.isOpen
if is_camera_actually_open and not self.camera_enabled:
logging.info("检测到相机已实际打开,但配置显示禁用,将更新相机启用状态")
self.camera_enabled = True
# 同时更新配置,确保持久化
self.config['camera'] = {'enabled': True}
from utils.config_loader import ConfigLoader
config_loader = ConfigLoader.get_instance()
config_loader.set_value('camera.enabled', True)
config_loader.save_config()
# 清理之前的组件(如果有) # 清理之前的组件(如果有)
if self.camera_display: if self.camera_display:
self.material_content_layout.removeWidget(self.camera_display) self.material_content_layout.removeWidget(self.camera_display)
@ -2906,52 +2792,36 @@ class MainWindow(MainWindowUI):
if item.widget(): if item.widget():
item.widget().deleteLater() item.widget().deleteLater()
# 决定是否应该启用相机功能 - 根据配置或相机实际状态
should_enable_camera = self.camera_enabled or is_camera_actually_open
# 创建占位标签 # 创建占位标签
self.material_placeholder = QLabel("相机初始化中..." if should_enable_camera else "相机功能已禁用") self.material_placeholder = QLabel("相机初始化中..." if self.camera_enabled else "相机功能已禁用")
self.material_placeholder.setAlignment(Qt.AlignCenter) self.material_placeholder.setAlignment(Qt.AlignCenter)
self.material_placeholder.setStyleSheet("color: #888888; background-color: #f0f0f0;") self.material_placeholder.setStyleSheet("color: #888888; background-color: #f0f0f0;")
self.material_placeholder.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding)
self.material_content_layout.addWidget(self.material_placeholder) self.material_content_layout.addWidget(self.material_placeholder)
self.material_placeholder.show()
# 创建相机显示组件 # 创建相机显示组件
self.camera_display = CameraDisplayWidget() self.camera_display = CameraDisplayWidget()
# 设置合适的尺寸策略,使相机显示能够正确适应上料区域
self.camera_display.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding)
# 显式连接相机状态信号
try:
# 如果已连接,先断开旧连接
self.camera_display.signal_camera_status.disconnect()
except:
pass
# 连接相机状态信号
self.camera_display.signal_camera_status.connect(self.handle_camera_status) self.camera_display.signal_camera_status.connect(self.handle_camera_status)
logging.info("已连接相机状态信号")
# 先不添加相机组件,直到确认相机可用时再添加 # 先隐藏相机组件,直到确认相机可用
if should_enable_camera: self.material_content_layout.addWidget(self.camera_display)
self.camera_display.hide()
# 如果相机功能已启用,尝试初始化相机
if self.camera_enabled:
# 启动相机初始化过程 # 启动相机初始化过程
QTimer.singleShot(500, self.initialize_camera) QTimer.singleShot(500, self.initialize_camera)
logging.info("相机初始化已安排") logging.info("相机初始化已安排")
else: else:
logging.info("相机功能已禁用,不进行初始化") logging.info("相机功能已禁用,不进行初始化")
self.material_placeholder.setText("相机功能已禁用") self.material_placeholder.show()
self.camera_display.hide()
except Exception as e: except Exception as e:
logging.error(f"初始化相机显示区域失败: {str(e)}") logging.error(f"初始化相机显示区域失败: {str(e)}")
# 确保占位符显示错误信息
if self.material_placeholder:
self.material_placeholder.setText(f"相机初始化错误: {str(e)}")
self.material_placeholder.show()
def initialize_camera(self): def initialize_camera(self):
"""初始化相机并显示画面""" """初始化相机并显示画面"""
try: try:
if not self.camera_enabled: if not self.camera_enabled:
logging.info("相机功能已禁用,不进行初始化")
return return
logging.info("开始初始化相机...") logging.info("开始初始化相机...")
@ -2960,13 +2830,6 @@ class MainWindow(MainWindowUI):
from widgets.camera_manager import CameraManager from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance() camera_manager = CameraManager.get_instance()
# 检查相机是否已经打开
if camera_manager.isOpen:
logging.info("相机已经打开,直接开始显示")
# 立即开始显示相机画面
QTimer.singleShot(100, lambda: self._start_camera_display())
return
# 枚举设备 # 枚举设备
devices = camera_manager.enum_devices() devices = camera_manager.enum_devices()
if not devices or len(devices) == 0: if not devices or len(devices) == 0:
@ -2980,6 +2843,9 @@ class MainWindow(MainWindowUI):
if success: if success:
logging.info(f"相机已成功打开,设备索引: {device_index}") logging.info(f"相机已成功打开,设备索引: {device_index}")
# 更新UI
self.update_camera_ui(True)
# 立即开始显示相机画面 # 立即开始显示相机画面
QTimer.singleShot(100, lambda: self._start_camera_display()) QTimer.singleShot(100, lambda: self._start_camera_display())
else: else:
@ -2989,51 +2855,31 @@ class MainWindow(MainWindowUI):
except Exception as e: except Exception as e:
self.material_placeholder.setText("相机初始化错误") self.material_placeholder.setText("相机初始化错误")
logging.error(f"初始化相机失败: {str(e)}") logging.error(f"初始化相机失败: {str(e)}")
# 异常情况下更新相机状态
self.update_camera_enabled_state(False)
def _start_camera_display(self): def _start_camera_display(self):
"""开始显示相机画面(内部方法)""" """开始显示相机画面(内部方法)"""
try: try:
if self.camera_display and self.camera_enabled: if self.camera_display and self.camera_enabled:
logging.info(f"开始相机显示,上料区域大小: {self.material_content.width()}x{self.material_content.height()}") # 确保相机组件可见
self.camera_display.setVisible(True)
# 先从布局中移除占位符 self.camera_display.raise_()
if self.material_placeholder:
self.material_content_layout.removeWidget(self.material_placeholder)
self.material_placeholder.hide()
# 添加相机显示组件并确保其可见
# 确保相机显示组件的布局策略正确
self.camera_display.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding)
self.material_content_layout.addWidget(self.camera_display)
self.camera_display.show()
# 强制布局更新
self.material_content_layout.update()
self.material_content.updateGeometry()
# 开始显示 # 开始显示
success = self.camera_display.start_display() success = self.camera_display.start_display()
if not success: if success:
# 确保占位符隐藏
if self.material_placeholder:
self.material_placeholder.setVisible(False)
logging.info("相机显示已成功启动")
else:
# 如果启动失败,显示占位符 # 如果启动失败,显示占位符
self.material_content_layout.removeWidget(self.camera_display)
self.camera_display.hide()
if self.material_placeholder: if self.material_placeholder:
self.material_placeholder.setText("相机显示启动失败") self.material_placeholder.setText("相机显示启动失败")
self.material_content_layout.addWidget(self.material_placeholder) self.material_placeholder.setVisible(True)
self.material_placeholder.show()
logging.error("相机显示启动失败") logging.error("相机显示启动失败")
else:
logging.info(f"相机显示已成功启动,显示区域大小: {self.camera_display.width()}x{self.camera_display.height()}")
except Exception as e: except Exception as e:
logging.error(f"启动相机显示失败: {str(e)}") logging.error(f"启动相机显示失败: {str(e)}")
if self.material_placeholder:
self.material_placeholder.setText(f"相机显示错误: {str(e)}")
self.material_content_layout.addWidget(self.material_placeholder)
self.material_placeholder.show()
def update_camera_ui(self, is_camera_ready): def update_camera_ui(self, is_camera_ready):
"""更新相机UI显示 """更新相机UI显示
@ -3044,54 +2890,39 @@ class MainWindow(MainWindowUI):
try: try:
if is_camera_ready and self.camera_enabled: if is_camera_ready and self.camera_enabled:
# 显示相机画面,隐藏占位符 # 显示相机画面,隐藏占位符
if self.material_placeholder:
self.material_content_layout.removeWidget(self.material_placeholder)
self.material_placeholder.hide()
if self.camera_display: if self.camera_display:
# 确保相机显示组件的布局策略正确 self.camera_display.setVisible(True)
self.camera_display.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding) self.camera_display.raise_() # 确保相机组件在最上层
if self.material_placeholder:
# 确保相机显示组件已添加到布局 self.material_placeholder.setVisible(False)
if self.camera_display.parent() is None: logging.info("相机UI已更新显示相机画面")
self.material_content_layout.addWidget(self.camera_display)
self.camera_display.show()
# 强制布局更新
self.material_content_layout.update()
self.material_content.updateGeometry()
logging.info(f"相机UI已更新显示相机画面尺寸: {self.camera_display.width()}x{self.camera_display.height()}")
else: else:
# 隐藏相机画面,显示占位符 # 隐藏相机画面,显示占位符
if self.camera_display: if self.camera_display:
self.material_content_layout.removeWidget(self.camera_display) self.camera_display.setVisible(False)
self.camera_display.hide()
if self.material_placeholder: if self.material_placeholder:
# 确保占位符布局策略正确 self.material_placeholder.setVisible(True)
self.material_placeholder.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding) self.material_placeholder.raise_() # 确保占位符在最上层
# 确保占位符已添加到布局
if self.material_placeholder.parent() is None:
self.material_content_layout.addWidget(self.material_placeholder)
self.material_placeholder.show()
# 强制布局更新
self.material_content_layout.update()
self.material_content.updateGeometry()
if not self.camera_enabled: if not self.camera_enabled:
self.material_placeholder.setText("相机功能已禁用") self.material_placeholder.setText("相机功能已禁用")
elif not is_camera_ready: elif not is_camera_ready:
self.material_placeholder.setText("相机未就绪") self.material_placeholder.setText("相机未就绪")
logging.info(f"相机UI已更新显示占位符 (相机启用={self.camera_enabled}, 相机就绪={is_camera_ready})") logging.info(f"相机UI已更新显示占位符 (相机启用={self.camera_enabled}, 相机就绪={is_camera_ready})")
except Exception as e: except Exception as e:
logging.error(f"更新相机UI失败: {str(e)}") logging.error(f"更新相机UI失败: {str(e)}")
def handle_camera_status(self, is_connected, message):
"""处理相机状态变化"""
if is_connected:
logging.info("相机已连接并显示")
self.update_camera_ui(True)
else:
logging.warning(f"相机显示问题: {message}")
# 更新占位符文本
if self.material_placeholder:
self.material_placeholder.setText(f"相机错误: {message}" if message else "相机未连接")
self.update_camera_ui(False)
@Slot(int, str) @Slot(int, str)
def handle_emergency_stop(self, value, desc): def handle_emergency_stop(self, value, desc):
"""处理急停信号""" """处理急停信号"""
@ -3140,99 +2971,3 @@ class MainWindow(MainWindowUI):
self.label_status_label.setStyleSheet("") self.label_status_label.setStyleSheet("")
except Exception as e: except Exception as e:
logging.error(f"处理急停UI更新失败: {str(e)}") logging.error(f"处理急停UI更新失败: {str(e)}")
def update_camera_enabled_state(self, is_enabled=None):
"""更新相机启用状态
Args:
is_enabled: 是否启用相机如果为None则检查相机管理器状态
"""
try:
from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance()
# 如果未提供状态,则根据相机管理器状态确定
if is_enabled is None:
is_enabled = camera_manager.isOpen
# 更新内存中的状态
old_state = self.camera_enabled
self.camera_enabled = is_enabled
# 如果状态发生变化,记录并更新配置
if old_state != is_enabled:
logging.info(f"相机启用状态已从 {old_state} 更改为 {is_enabled}")
# 更新配置
self.config['camera'] = {'enabled': is_enabled}
from utils.config_loader import ConfigLoader
config_loader = ConfigLoader.get_instance()
config_loader.set_value('camera.enabled', is_enabled)
config_loader.save_config()
# 如果已启用,确保相机显示正确初始化
if is_enabled:
# 确保相机显示组件已正确初始化
if not hasattr(self, 'camera_display') or self.camera_display is None:
logging.info("相机启用状态更新:正在初始化相机显示组件")
self.init_camera_display()
else:
# 如果相机已经打开但界面未显示则更新UI
if camera_manager.isOpen:
logging.info("相机已打开更新UI以显示相机画面")
self.update_camera_ui(True)
# 如果相机未在采集,则开始采集
if not camera_manager.isGrabbing:
QTimer.singleShot(100, self._start_camera_display)
else:
# 如果禁用确保更新UI显示占位符
logging.info("相机已禁用更新UI以显示占位符")
if hasattr(self, 'material_placeholder') and self.material_placeholder:
self.material_placeholder.setText("相机功能已禁用")
self.update_camera_ui(False)
# 如果相机仍在采集,则停止采集
if camera_manager.isGrabbing:
if hasattr(self, 'camera_display') and self.camera_display:
self.camera_display.stop_display()
# 如果相机仍在连接,则关闭相机
if camera_manager.isOpen:
camera_manager.close_device()
else:
logging.debug(f"相机启用状态未变化,保持为 {is_enabled}")
except Exception as e:
logging.error(f"更新相机启用状态失败: {str(e)}")
def handle_camera_connection(self, is_connected, message):
"""处理相机连接状态变化"""
try:
if is_connected:
logging.info("相机已连接")
# 更新相机启用状态
self.update_camera_enabled_state(True)
# 如果当前在主页面,直接开始显示相机画面
if self.stacked_widget.currentWidget() == self.central_widget:
if hasattr(self, 'camera_display') and self.camera_display:
self.camera_display.start_display()
else:
if message:
logging.warning(f"相机连接失败: {message}")
else:
logging.info("相机已断开")
# 如果相机断开,确保停止显示
if hasattr(self, 'camera_display') and self.camera_display:
self.camera_display.stop_display()
# 更新相机启用状态 - 只有在明确断开时才设置为False
if not message: # 只有在主动断开时才更新状态为False
self.update_camera_enabled_state(False)
except Exception as e:
logging.error(f"处理相机连接状态变化失败: {str(e)}")
if self.material_placeholder:
self.material_placeholder.setText(f"相机连接错误: {str(e)}")
self.update_camera_ui(False)