feat: 更新InspectionDAO以支持新字段,修改主窗口UI以添加订单信息表格和托盘完成按钮

This commit is contained in:
zhu-mengmeng 2025-07-15 15:48:14 +08:00
parent 4495b1683d
commit f1540ec0c3
4 changed files with 293 additions and 373 deletions

View File

@ -253,7 +253,7 @@ class InspectionDAO:
gzl = ?, maxsl = ?, cz = ?, size = ?, cd = ?, luno = ?,
qfqd = ?, pono = ?, xj = ?, ysl = ?, dycz = ?,
zx_code = ?, edit_id = ?, remarks = ?, zx_name = ?,
bccd = ? ,tccd = ?, zzyq = ?
bccd = ? ,tccd = ?, zzyq = ?, customer = ?,customerexp = ?,bz_bqd = ?,bz_tqd = ?,type_name = ?,remarks_hb=?
WHERE ddmo = ?
"""
params = (
@ -289,6 +289,12 @@ class InspectionDAO:
data.get("bccd", ""),
data.get("tccd", ""),
data.get("zzyq", ""),
data.get("customer", ""),
data.get("customerexp", ""),
data.get("bz_bqd", ""),
data.get("bz_tqd", ""),
data.get("type_name", ""),
data.get("remarks_hb", ""),
data.get("mo", "") # WHERE 条件参数
)
logging.info(f"更新订单信息: ddmo={data.get('mo', '')}")
@ -299,10 +305,10 @@ class InspectionDAO:
data_corp, user_id, user_name, gzl_zl, ddmo, xpack,
qd, spack_type, mxzs, jt, ddnote, code, type,
lable, lib, gzl, maxsl, cz, size, cd, luno, qfqd,
pono, xj, ysl, dycz, zx_code, edit_id, remarks,zx_name,bccd,tccd,zzyq
pono, xj, ysl, dycz, zx_code, edit_id, remarks,zx_name,bccd,tccd,zzyq,customer,customerexp,bz_bqd,bz_tqd,type_name,remarks_hb
) VALUES (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)
"""
params = (
@ -338,7 +344,13 @@ class InspectionDAO:
data.get("zx_name", ""),
data.get("bccd", ""),
data.get("tccd", ""),
data.get("zzyq", "")
data.get("zzyq", ""),
data.get("customer", ""),
data.get("customerexp", ""),
data.get("bz_bqd", ""),
data.get("bz_tqd", ""),
data.get("type_name", ""),
data.get("remarks_hb", "")
)
logging.info(f"插入新订单信息: ddmo={data.get('mo', '')}")

Binary file not shown.

View File

@ -1,7 +1,7 @@
from PySide6.QtWidgets import (
QMainWindow, QWidget, QLabel, QGridLayout, QVBoxLayout, QHBoxLayout,
QTableWidget, QTableWidgetItem, QHeaderView, QFrame, QSplitter,
QPushButton, QLineEdit, QAbstractItemView, QComboBox
QPushButton, QLineEdit, QAbstractItemView, QComboBox, QSizePolicy
)
from PySide6.QtGui import QFont, QAction, QBrush, QColor
from PySide6.QtCore import Qt, QDateTime, QTimer
@ -217,19 +217,164 @@ class MainWindowUI(QMainWindow):
self.material_layout.setSpacing(0)
# 上料区标签
self.material_label = QLabel("上料区")
self.material_label = QLabel("托盘入库")
self.material_label.setFont(self.normal_font)
self.material_label.setAlignment(Qt.AlignCenter)
self.material_label.setFixedWidth(100) # 设置固定宽度
self.material_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;")
self.material_layout.addWidget(self.material_label)
# 上料区内容 - 这里可以添加更多控件
# 上料区内容 - 订单信息表格
self.material_content = QWidget()
# 使用透明背景,让相机画面可以正常显示
self.material_content.setStyleSheet("background-color: transparent;")
self.material_content.setStyleSheet("background-color: white;")
self.material_content_layout = QVBoxLayout(self.material_content)
self.material_content_layout.setContentsMargins(0, 0, 0, 0) # 移除内边距以便相机画面填满
self.material_content_layout.setContentsMargins(10, 10, 10, 10)
# 创建订单号输入框
self.order_info_layout = QHBoxLayout()
self.order_no_label = QLabel("订单号:")
self.order_no_label.setFont(self.normal_font)
self.order_no_label.setFixedWidth(60)
self.order_no_input = QLineEdit()
self.order_no_input.setFont(self.normal_font)
self.order_no_input.setReadOnly(True)
self.order_no_input.setStyleSheet("background-color: #f5f5f5; border: 1px solid #cccccc; padding: 3px;")
self.order_info_layout.addWidget(self.order_no_label)
self.order_info_layout.addWidget(self.order_no_input)
self.order_info_layout.addStretch()
# 添加托盘完成按钮
self.tray_complete_button = QPushButton("托盘完成")
self.tray_complete_button.setFont(self.normal_font)
self.tray_complete_button.setStyleSheet("""
QPushButton {
padding: 5px 8px;
background-color: #e8f5e9;
border: 1px solid #4caf50;
}
QPushButton:hover {
background-color: #c8e6c9;
}
""")
self.order_info_layout.addWidget(self.tray_complete_button)
self.material_content_layout.addLayout(self.order_info_layout)
# 创建信息表格 - 使用QTableWidget实现
self.info_table = QTableWidget()
self.info_table.setRowCount(9) # 8行常规字段 + 1行备注
self.info_table.setColumnCount(4) # 4列标签1, 值1, 标签2, 值2
self.info_table.setShowGrid(True) # 显示网格线
self.info_table.horizontalHeader().setVisible(False) # 隐藏水平表头
self.info_table.verticalHeader().setVisible(False) # 隐藏垂直表头
# 设置表格样式
self.info_table.setStyleSheet("""
QTableWidget {
border-top: 1px solid #cccccc;
border-left: 1px solid #cccccc;
border-right: none;
border-bottom: none;
gridline-color: #cccccc;
}
""")
# 定义字段和对应的数据键
field_mapping = {
"客户": "customerexp",
"规格": "size",
"材质": "cz",
"种类": "type_name",
"钢厂": "cd",
"炉号": "luno",
"轴型": "zx_name",
"标签": "lable",
"打印材质": "cz",
"底托类型": "spack_type",
"强度范围": "qx",
"强度": "qd",
"延伸要求": "ysl",
"线材类型": "jz",
"轴重要求": "zq",
"线径公差": "xj",
"备注": "remarks_hb"
}
# 创建标签和值的字典,用于后续更新
self.info_labels = {}
self.info_values = {}
# 填充表格内容
row = 0
col = 0
for i, field_name in enumerate(field_mapping.keys()):
if field_name == "备注": # 备注行特殊处理
# 创建标签
label = QLabel("备注")
label.setFont(self.normal_font)
label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
label.setStyleSheet("background-color: #FAFAFA; padding: 5px;")
# 创建值
value = QLabel("")
value.setFont(self.normal_font)
value.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
value.setStyleSheet("background-color: white; padding: 5px;")
# 保存引用
self.info_labels["备注"] = label
self.info_values["备注"] = value
# 添加到表格
self.info_table.setCellWidget(row, 0, label)
self.info_table.setCellWidget(row, 1, value)
self.info_table.setSpan(row, 1, 1, 3) # 值跨越3列
else:
# 创建标签
label = QLabel(field_name)
label.setFont(self.normal_font)
label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
label.setStyleSheet("background-color: #FAFAFA; padding: 5px;")
# 创建值
value = QLabel("")
value.setFont(self.normal_font)
value.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
value.setStyleSheet("background-color: white; padding: 5px;")
# 保存引用
self.info_labels[field_name] = label
self.info_values[field_name] = value
# 添加到表格
self.info_table.setCellWidget(row, col * 2, label)
self.info_table.setCellWidget(row, col * 2 + 1, value)
# 更新行列索引
col += 1
if col >= 2: # 每行两组数据
col = 0
row += 1
# 设置行高
for i in range(self.info_table.rowCount()):
self.info_table.setRowHeight(i, 35) # 普通行高度调高
# 设置表格自适应
self.info_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 列宽自适应
# 设置表格填充整个容器
self.info_table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
# 禁用滚动条,避免用户误触
self.info_table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.info_table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# 添加表格到主布局
self.material_content_layout.addWidget(self.info_table)
self.material_layout.addWidget(self.material_content)
self.left_layout.addWidget(self.material_frame)
@ -551,29 +696,8 @@ class MainWindowUI(QMainWindow):
# 添加标题到布局
self.record_title_layout.addWidget(self.record_title)
# 创建托盘完成按钮
self.tray_complete_button = QPushButton("托盘完成")
self.tray_complete_button.setFont(self.normal_font)
self.tray_complete_button.setFixedSize(100, 30)
self.tray_complete_button.setStyleSheet("""
QPushButton {
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
padding: 5px 10px;
}
QPushButton:hover {
background-color: #45a049;
}
QPushButton:pressed {
background-color: #3d8b40;
}
""")
# 添加按钮到布局,并设置右对齐
self.record_title_layout.addStretch() # 添加弹性空间,将按钮推到右侧
self.record_title_layout.addWidget(self.tray_complete_button)
# 添加弹性空间,确保标题居左
self.record_title_layout.addStretch() # 添加弹性空间
# 将标题容器添加到记录布局
self.record_layout.addWidget(self.record_title_container)

View File

@ -106,7 +106,6 @@ class MainWindow(MainWindowUI):
# 加载配置文件
self.config = self.load_config()
self.camera_enabled = self.config.get('camera', {}).get('enabled', False)
# 初始化检验配置管理器
self.inspection_manager = InspectionConfigManager.get_instance()
@ -121,13 +120,6 @@ class MainWindow(MainWindowUI):
self.output_form_layout = QFormLayout()
self.output_content_layout.addLayout(self.output_form_layout)
# 创建相机显示组件和占位标签
self.camera_display = None
self.material_placeholder = None
# 初始化上料区显示
self.init_camera_display()
# 为下料区添加占位标签,确保它保持为空
self.output_placeholder = QWidget()
self.output_placeholder.setStyleSheet("background-color: #f0f0f0;")
@ -157,10 +149,6 @@ class MainWindow(MainWindowUI):
self.stacked_widget = QStackedWidget()
self.stacked_widget.addWidget(self.central_widget) # 主页面
# 不在这里直接初始化相机设置组件
# 延迟创建保证创建的时候SettingsUI的所有控件都已经准备好
self.camera_settings = None
# 设置中央部件为堆叠部件
self.setCentralWidget(self.stacked_widget)
@ -277,9 +265,7 @@ class MainWindow(MainWindowUI):
self.process_table.setContextMenuPolicy(Qt.CustomContextMenu)
self.process_table.customContextMenuRequested.connect(self.show_table_context_menu)
# 只有在相机启用时连接相机信号
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)
@ -330,26 +316,6 @@ class MainWindow(MainWindowUI):
# 加载未完成的检验数据
self._safe_load_data()
# 处理相机显示
if self.camera_enabled and self.camera_display:
from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance()
# 检查相机是否已打开
if camera_manager.isOpen:
# 更新UI显示相机画面
self.update_camera_ui(True)
# 如果相机未在采集,则开始采集
if not camera_manager.isGrabbing:
# 使用内部方法启动相机显示
QTimer.singleShot(100, self._start_camera_display)
logging.info("主页面显示:启动相机显示")
else:
# 如果相机未打开,尝试重新初始化
QTimer.singleShot(100, self.initialize_camera)
logging.info("主页面显示:尝试初始化相机")
# 加载托盘号列表
self.load_pallet_codes()
@ -400,17 +366,6 @@ class MainWindow(MainWindowUI):
self.settings_window = SettingsWindow(self)
# 连接设置改变信号
self.settings_window.settings_changed.connect(self.on_settings_changed)
# 连接相机设置控制器的信号
if hasattr(self.settings_window, 'camera_settings'):
# 连接相机连接状态变化信号
self.settings_window.camera_settings.signal_camera_connection.connect(self.handle_camera_connection)
# 连接相机参数变化信号
self.settings_window.camera_settings.signal_camera_params_changed.connect(self.handle_camera_params_changed)
# 连接相机错误信号
self.settings_window.camera_settings.signal_camera_error.connect(self.handle_camera_error)
# 连接本地图像模式变更信号
self.settings_window.camera_settings.signal_local_mode_changed.connect(self.handle_local_mode_changed)
# 显示设置窗口
self.settings_window.show()
@ -713,41 +668,20 @@ class MainWindow(MainWindowUI):
pass # Failsafe
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)
"""相机状态处理的空方法,保留是为了兼容性"""
pass
def handle_camera_connection(self, is_connected, message):
"""处理相机连接状态变化"""
if is_connected:
logging.info("相机已连接")
# 如果当前在主页面,直接开始显示相机画面
if self.stacked_widget.currentWidget() == self.central_widget:
self.camera_display.start_display()
else:
if message:
logging.warning(f"相机连接失败: {message}")
else:
logging.info("相机已断开")
# 如果相机断开,确保停止显示
self.camera_display.stop_display()
"""相机连接处理的空方法,保留是为了兼容性"""
pass
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")
# 这里可以添加对相机参数变化的处理逻辑
"""相机参数变更处理的空方法,保留是为了兼容性"""
pass
def handle_camera_error(self, error_msg):
"""处理相机错误"""
logging.error(f"相机错误: {error_msg}")
QMessageBox.warning(self, "相机错误", error_msg)
"""相机错误处理的空方法,保留是为了兼容性"""
pass
def closeEvent(self, event):
"""窗口关闭事件"""
@ -756,21 +690,6 @@ class MainWindow(MainWindowUI):
logging.info("停止Modbus监控")
self.modbus_monitor.stop()
# 处理相机关闭
if self.camera_enabled and self.camera_display:
# 停止相机显示
self.camera_display.stop_display()
# 关闭相机设备
try:
from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance()
if camera_manager.isOpen:
camera_manager.close_device()
logging.info("相机设备已关闭")
except Exception as e:
logging.error(f"关闭相机设备失败: {str(e)}")
# 停止串口监听
self.serial_manager.stop_keyboard_listener()
self.serial_manager.close_all_ports()
@ -3062,6 +2981,31 @@ class MainWindow(MainWindowUI):
logging.info(f"主窗口接收到订单号: {order_code}")
# 存储当前订单号
self._current_order_code = order_code
# 更新订单号输入框
self.order_no_input.setText(order_code)
# 如果是接口模式
if AppMode.is_api():
# 获取订单的详细信息
from apis.gc_api import GcApi
gc_api = GcApi()
# 获取工程号信息
order_response = gc_api.get_order_info(order_code, self.corp_id)
if order_response.get("status", False):
# 获取订单的工程号数据
gc_notes = order_response.get("data", [])
if gc_notes and len(gc_notes) > 0:
# 更新上料区域信息表格
self.update_info_table(gc_notes[0])
else:
# 非接口模式,获取本地数据库中的订单信息
from dao.inspection_dao import InspectionDAO
inspection_dao = InspectionDAO()
order_info = inspection_dao.get_order_info(order_code)
# 更新上料区域信息表格
self.update_info_table(order_info)
def on_report(self):
"""报表按钮点击处理"""
@ -3073,164 +3017,26 @@ class MainWindow(MainWindowUI):
QMessageBox.warning(self, "错误", f"打开报表对话框失败: {str(e)}")
def init_camera_display(self):
"""初始化相机显示区域"""
try:
# 清理之前的组件(如果有)
if self.camera_display:
self.material_content_layout.removeWidget(self.camera_display)
self.camera_display.deleteLater()
self.camera_display = None
if self.material_placeholder:
self.material_content_layout.removeWidget(self.material_placeholder)
self.material_placeholder.deleteLater()
self.material_placeholder = None
# 清空布局中的所有项目
while self.material_content_layout.count():
item = self.material_content_layout.takeAt(0)
if item.widget():
item.widget().deleteLater()
# 创建占位标签
self.material_placeholder = QLabel("相机初始化中..." if self.camera_enabled else "相机功能已禁用")
self.material_placeholder.setAlignment(Qt.AlignCenter)
self.material_placeholder.setStyleSheet("color: #888888; background-color: #f0f0f0;")
self.material_content_layout.addWidget(self.material_placeholder)
# 创建相机显示组件
self.camera_display = CameraDisplayWidget()
self.camera_display.signal_camera_status.connect(self.handle_camera_status)
# 先隐藏相机组件,直到确认相机可用
self.material_content_layout.addWidget(self.camera_display)
self.camera_display.hide()
# 如果相机功能已启用,尝试初始化相机
if self.camera_enabled:
# 启动相机初始化过程
QTimer.singleShot(500, self.initialize_camera)
logging.info("相机初始化已安排")
else:
logging.info("相机功能已禁用,不进行初始化")
self.material_placeholder.show()
self.camera_display.hide()
except Exception as e:
logging.error(f"初始化相机显示区域失败: {str(e)}")
"""初始化上料区信息表格,不包含任何相机相关代码"""
# 上料区的信息表格已经在UI类的create_left_panel方法中初始化
# 这个方法保留是为了兼容性,但不做任何操作
pass
def initialize_camera(self):
"""初始化相机并显示画面"""
try:
if not self.camera_enabled:
self.material_placeholder.setText("相机功能已禁用")
logging.info("开始初始化相机...")
# 获取相机管理器实例
from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance()
# 枚举设备
devices = camera_manager.enum_devices()
if not devices or len(devices) == 0:
self.material_placeholder.setText("未检测到相机设备")
logging.warning("未检测到相机设备")
return
# 打开第一个相机设备
device_index = 0
success = camera_manager.open_device(device_index)
if success:
logging.info(f"相机已成功打开,设备索引: {device_index}")
# 更新UI
self.update_camera_ui(True)
# 立即开始显示相机画面
QTimer.singleShot(100, lambda: self._start_camera_display())
else:
self.material_placeholder.setText("相机打开失败")
logging.error("相机打开失败")
except Exception as e:
self.material_placeholder.setText("相机初始化错误")
logging.error(f"初始化相机失败: {str(e)}")
"""初始化相机的空方法,保留是为了兼容性"""
pass
def _start_camera_display(self):
"""开始显示相机画面(内部方法)"""
try:
if self.camera_display and self.camera_enabled:
# 确保相机组件可见
self.camera_display.setVisible(True)
self.camera_display.raise_()
# 开始显示
success = self.camera_display.start_display()
if success:
# 确保占位符隐藏
if self.material_placeholder:
self.material_placeholder.setVisible(False)
logging.info("相机显示已成功启动")
else:
# 如果启动失败,显示占位符
if self.material_placeholder:
self.material_placeholder.setText("相机显示启动失败")
self.material_placeholder.setVisible(True)
logging.error("相机显示启动失败")
except Exception as e:
logging.error(f"启动相机显示失败: {str(e)}")
"""相机显示的空方法,保留是为了兼容性"""
pass
def update_camera_ui(self, is_camera_ready):
"""更新相机UI显示
Args:
is_camera_ready: 相机是否准备就绪
"""
try:
from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance()
local_mode_active = getattr(camera_manager, 'local_mode', False)
# 关键修复:如果本地模式激活,则强制认为相机已就绪
camera_feature_enabled = self.camera_enabled or local_mode_active
if local_mode_active:
is_camera_ready = True
if is_camera_ready and camera_feature_enabled:
# 显示相机画面,隐藏占位符
if self.camera_display:
self.camera_display.setVisible(True)
self.camera_display.raise_() # 确保相机组件在最上层
if self.material_placeholder:
self.material_placeholder.setVisible(False)
logging.info("相机UI已更新显示相机画面")
else:
# 显示占位符,隐藏相机画面
if self.camera_display:
self.camera_display.setVisible(False)
if self.material_placeholder:
self.material_placeholder.setVisible(True)
self.material_placeholder.raise_() # 确保占位符在最上层
if not self.camera_enabled:
self.material_placeholder.setText("相机功能已禁用")
elif not is_camera_ready:
self.material_placeholder.setText("相机未就绪")
logging.info(f"相机UI已更新显示占位符 (相机启用={self.camera_enabled}, 相机就绪={is_camera_ready})")
except Exception as e:
logging.error(f"更新相机UI时出错: {e}")
"""相机UI更新的空方法保留是为了兼容性"""
pass
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)
"""相机状态处理的空方法,保留是为了兼容性"""
pass
@Slot(int, str)
def handle_emergency_stop(self, value, desc):
@ -3447,104 +3253,7 @@ class MainWindow(MainWindowUI):
logging.error(f"删除数据失败: {str(e)}")
QMessageBox.critical(self, "错误", f"删除数据失败: {str(e)}")
# 在MainWindow类中添加处理本地图像模式变更的代码
# 在init_settings_window()方法中添加信号连接
def init_settings_window(self):
# 创建设置窗口
from widgets.settings_window import SettingsWindow
self.settings_window = SettingsWindow(self)
self.settings_window.setWindowTitle("系统设置")
# 设置窗口大小
self.settings_window.resize(900, 650)
# 连接设置变更信号
self.settings_window.settings_changed.connect(self.handle_settings_changed)
# 连接相机设置控制器
if hasattr(self.settings_window, 'camera_settings'):
# 连接相机连接状态变化信号
self.settings_window.camera_settings.signal_camera_connection.connect(self.handle_camera_connection)
# 连接相机参数变化信号
self.settings_window.camera_settings.signal_camera_params_changed.connect(self.handle_camera_params_changed)
# 连接相机错误信号
self.settings_window.camera_settings.signal_camera_error.connect(self.handle_camera_error)
# 连接本地图像模式变更信号
self.settings_window.camera_settings.signal_local_mode_changed.connect(self.handle_local_mode_changed)
# 添加处理本地图像模式变更的方法
def handle_local_mode_changed(self, enabled):
"""处理本地图像模式变更
Args:
enabled: 是否启用本地图像模式
"""
try:
logging.warning(f"====> 主窗口处理本地图像模式变更: {enabled}")
# 关键修复只要启用本地模式就认为相机功能已就绪并强制更新UI
if enabled:
self.camera_enabled = True
self.update_camera_ui(True) # 强制刷新UI隐藏占位符
if self.camera_display:
self.camera_display.setVisible(True) # 确保相机显示区域可见
# 获取相机管理器
from widgets.camera_manager import CameraManager
camera_manager = CameraManager.get_instance()
# 设置相机管理器的本地模式
camera_manager.set_local_mode(enabled)
# 如果当前在主页面,更新相机显示
if hasattr(self, 'camera_display') and self.camera_display and self.stacked_widget.currentWidget() == self.central_widget:
# 确保相机显示组件可见
self.camera_display.setVisible(True)
self.camera_display.raise_()
if self.material_placeholder:
self.material_placeholder.setVisible(False)
# 确保相机显示组件连接了本地图像帧信号
if enabled:
# 本地模式下,停止实时相机显示但保持相机显示组件可见
if camera_manager.isGrabbing and not camera_manager.local_mode:
self.camera_display.stop_display()
# 确保本地图像帧能够被显示
if hasattr(self.settings_window, 'camera_settings'):
camera_settings = self.settings_window.camera_settings
if hasattr(camera_settings, 'local_player') and camera_settings.local_player:
# 直接连接本地播放器的信号到相机显示组件
try:
if hasattr(camera_settings.local_player, 'signal_frame_ready'):
# 先断开可能存在的连接,避免重复
try:
camera_settings.local_player.signal_frame_ready.disconnect()
except Exception as e:
logging.debug(f"断开信号连接时发生异常(这是正常的): {e}")
# 建立新的连接
camera_settings.local_player.signal_frame_ready.connect(self.camera_display.update_local_frame)
logging.warning("====> 已直接连接本地播放器信号到相机显示组件")
# 确认显示区域已准备好
self.camera_display._current_pixmap = None
self.camera_display.update()
# 如果已在播放,确保信号重新连接后再次触发更新
if camera_settings.is_playing and camera_settings.local_player.last_frame is not None:
QTimer.singleShot(100, lambda: self.camera_display.update_local_frame(camera_settings.local_player.last_frame))
except Exception as e:
logging.error(f"连接本地播放器信号失败: {e}")
logging.warning("====> 已切换到本地图像模式,等待本地图像播放")
else:
# 非本地模式下,如果相机已打开则开始显示
if camera_manager.isOpen:
self.camera_display.start_display()
logging.warning("====> 已切换到实时相机模式")
except Exception as e:
logging.error(f"处理本地图像模式变更时发生错误: {e}")
def handle_tray_complete(self):
"""处理托盘完成按钮点击事件"""
@ -3593,4 +3302,79 @@ class MainWindow(MainWindowUI):
except Exception as e:
logging.error(f"处理托盘完成失败: {str(e)}")
QMessageBox.critical(self, "错误", f"处理托盘完成失败: {str(e)}")
QMessageBox.critical(self, "错误", f"处理托盘完成失败: {str(e)}")
def update_info_table(self, order_info):
"""根据订单信息更新上料区域的信息表格
Args:
order_info: 订单信息字典
"""
try:
if not order_info:
logging.warning("订单信息为空,无法更新上料区域信息表格")
return
logging.info(f"更新上料区域信息表格: {order_info}")
# 获取表格中的映射关系
field_mapping = {
"客户": "customerexp",
"规格": "size",
"材质": "cz",
"种类": "type_name",
"钢厂": "cd",
"炉号": "luno",
"轴型": "zx_name",
"标签": "template_name",
"打印材质": "cz",
"底托类型": "spack_type",
"强度范围": "qx",
"强度": "qd",
"延伸要求": "ysl",
"检验员": "jz",
"轴重要求": "zzyq",
"线径公差": "xj",
"备注": "remarks_hb"
}
# 更新表格内容
for field_name, field_key in field_mapping.items():
if field_name in self.info_values:
value = ""
if field_key and field_key in order_info:
value = str(order_info[field_key])
# 特殊处理线径公差
if field_name == "线径公差" and "bccd" in order_info and "tccd" in order_info:
bccd = order_info.get("bccd")
tccd = order_info.get("tccd")
if bccd is not None and tccd is not None:
value = f"{bccd} - {tccd}"
if field_name == "强度范围" and "bqd" in order_info and "tqd" in order_info:
bqd = order_info.get("bqd")
tqd = order_info.get("tqd")
if bqd is not None and tqd is not None:
value = f"{bqd} - {tqd}"
self.info_values[field_name].setText(value)
logging.info("上料区域信息表格更新完成")
# 为了演示如果没有真实数据填充一些mock数据
if not any(order_info.values()):
mock_data = {
"customerexp": "示例客户",
"size": "1.2mm",
"cz": "不锈钢",
"type_name": "A型",
"cd": "上海钢厂",
"luno": "LN20230501",
"zx_name": "标准轴",
"lable": "标签A",
"spack_type": "标准底托",
"bccd": "0.7",
"tccd": "0.9"
}
self.update_info_table(mock_data)
except Exception as e:
logging.error(f"更新上料区域信息表格失败: {str(e)}")