import sys import os import logging from ctypes import * # 确定使用哪个UI框架 try: from PySide6.QtWidgets import QWidget, QVBoxLayout, QFrame, QSizePolicy from PySide6.QtCore import Qt, Signal, QSize from PySide6.QtGui import QPalette, QColor except ImportError: from PyQt5.QtWidgets import QWidget, QVBoxLayout, QFrame, QSizePolicy from PyQt5.QtCore import Qt, pyqtSignal as Signal, QSize from PyQt5.QtGui import QPalette, QColor # 添加相机模块路径 sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "camera")) # 导入相机相关模块 from camera.MvCameraControl_class import MvCamera from camera.CamOperation_class import CameraOperation from camera.MvErrorDefine_const import * from camera.CameraParams_header import * # 导入相机管理器 from widgets.camera_manager import CameraManager class CameraDisplayWidget(QWidget): """相机显示组件,用于在主窗口显示相机图像""" # 状态信号 signal_camera_status = Signal(bool, str) # 相机状态信号 (是否连接, 状态消息) def __init__(self, parent=None): super().__init__(parent) # 获取相机管理器实例 self.camera_manager = CameraManager.get_instance() # 初始化UI self.init_ui() # 设置显示事件处理 self.showEvent = self.on_show_event # 设置大小变化事件处理 self.resizeEvent = self.on_resize_event # 设置固定尺寸策略,防止超出父容器 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # 设置最小尺寸 self.setMinimumSize(QSize(320, 240)) def init_ui(self): """初始化UI - 只包含相机显示框架""" # 创建布局 layout = QVBoxLayout() # 移除所有边距和间距 layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) # 创建相机画面显示框架 self.frame = QFrame() # 去掉边框 self.frame.setFrameShape(QFrame.NoFrame) # 设置黑色背景 self.frame.setStyleSheet("background-color: #000000;") # 设置框架的尺寸策略 self.frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # 添加到布局 layout.addWidget(self.frame) # 设置布局 self.setLayout(layout) def start_display(self): """开始显示相机图像""" if not self.camera_manager.isOpen: logging.error("相机未打开,无法开始显示") self.signal_camera_status.emit(False, "相机未打开") return False try: # 获取窗口句柄 try: # PySide6 window_id = int(self.frame.winId()) except: try: # PyQt5 window_id = self.frame.winId().__int__() except: # 其他情况 window_id = int(self.frame.winId()) # 开始取图 success = self.camera_manager.start_grabbing(window_id) if success: logging.info(f"相机画面显示开始,显示区域大小: {self.frame.width()}x{self.frame.height()}") self.signal_camera_status.emit(True, "") else: logging.error("开始显示相机画面失败") self.signal_camera_status.emit(False, "开始显示失败") return success except Exception as e: logging.error(f"开始显示时发生异常: {str(e)}") self.signal_camera_status.emit(False, str(e)) return False def stop_display(self): """停止显示相机图像""" if not self.camera_manager.isGrabbing: return True try: success = self.camera_manager.stop_grabbing() if not success: logging.error("停止显示失败") return success except Exception as e: logging.error(f"停止显示时发生异常: {str(e)}") return False def on_show_event(self, event): """当组件显示时检查相机状态并自动开始显示""" if self.camera_manager.isOpen and not self.camera_manager.isGrabbing: self.start_display() super().showEvent(event) def on_resize_event(self, event): """处理大小变化事件,确保相机画面适配上料区""" super().resizeEvent(event) # 记录大小变化 logging.debug(f"相机显示区域大小变化为: {self.width()}x{self.height()}") # 当尺寸变化超过一定阈值时,重新调整相机显示 if self.camera_manager.isGrabbing: # 停止当前显示 self.stop_display() # 使用新尺寸重新开始显示 self.start_display() def closeEvent(self, event): """窗口关闭事件""" self.stop_display() super().closeEvent(event)