feat: 完善相机
This commit is contained in:
parent
336ba26bc8
commit
7023d7561a
@ -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
|
||||||
|
|||||||
@ -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,))
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
|
||||||
Loading…
Reference in New Issue
Block a user