jiateng_ws/widgets/camera_display_widget.py

152 lines
5.2 KiB
Python
Raw Normal View History

2025-06-07 10:45:09 +08:00
import sys
import os
import logging
from ctypes import *
# 确定使用哪个UI框架
try:
from PySide6.QtWidgets import QWidget, QVBoxLayout, QFrame
2025-06-30 18:40:50 +08:00
from PySide6.QtCore import Qt, Signal, QSize
from PySide6.QtGui import QPalette, QColor
2025-06-07 10:45:09 +08:00
except ImportError:
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QFrame
2025-06-30 18:40:50 +08:00
from PyQt5.QtCore import Qt, pyqtSignal as Signal, QSize
from PyQt5.QtGui import QPalette, QColor
2025-06-07 10:45:09 +08:00
# 添加相机模块路径
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
2025-06-30 18:40:50 +08:00
# 设置固定尺寸策略,防止超出父容器
self.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding)
# 设置最小尺寸
self.setMinimumSize(QSize(320, 240))
2025-06-07 10:45:09 +08:00
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;")
2025-06-30 18:40:50 +08:00
# 设置框架的尺寸策略
self.frame.setSizePolicy(QWidget.sizePolicy().Expanding, QWidget.sizePolicy().Expanding)
2025-06-07 10:45:09 +08:00
# 添加到布局
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:
2025-06-30 18:40:50 +08:00
logging.info(f"相机画面显示开始,显示区域大小: {self.frame.width()}x{self.frame.height()}")
2025-06-07 10:45:09 +08:00
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)
2025-06-30 18:40:50 +08:00
# 记录大小变化
logging.debug(f"相机显示区域大小变化为: {self.width()}x{self.height()}")
# 当尺寸变化超过一定阈值时,重新调整相机显示
2025-06-07 10:45:09 +08:00
if self.camera_manager.isGrabbing:
# 停止当前显示
self.stop_display()
# 使用新尺寸重新开始显示
self.start_display()
def closeEvent(self, event):
"""窗口关闭事件"""
self.stop_display()
super().closeEvent(event)