from ui.loading_dialog_ui import LoadingDialogUI from apis.tary_api import TaryApi from PySide6.QtCore import Qt, Signal from PySide6.QtWidgets import QMessageBox, QDialog import logging from utils.app_mode import AppMode from utils.pallet_type_manager import PalletTypeManager class LoadingDialog(LoadingDialogUI): # 定义一个信号,用于向主窗口传递托盘号 tray_code_signal = Signal(str, str, str, str) def __init__(self, parent=None): """初始化加载对话框""" super().__init__() self.parent = parent # 彻底禁用对话框的回车键关闭功能 self.setModal(True) # 禁用所有按钮的默认行为 self.confirm_button.setAutoDefault(False) self.confirm_button.setDefault(False) self.cancel_button.setAutoDefault(False) self.cancel_button.setDefault(False) # 设置对话框特性,按下Escape键才能关闭 self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) # 绑定事件 self.setup_connections() def setup_connections(self): """设置事件连接""" # 托盘号输入框回车事件触发查询 self.tray_input.returnPressed.connect(self.handle_tray_return_pressed) # 移除editingFinished事件,避免重复触发查询 # self.tray_input.editingFinished.connect(self.on_tray_query) # 确认按钮点击事件 self.confirm_button.clicked.connect(self.accept) # 取消按钮点击事件 self.cancel_button.clicked.connect(self.reject) def handle_tray_return_pressed(self): """处理托盘输入框的回车事件""" # 阻止事件传播 logging.info("托盘输入框回车事件触发") self.on_tray_query() # 阻止事件继续传播 return True def on_tray_query(self): """查询托盘信息""" try: tray_code = self.tray_input.text().strip() if not tray_code: return logging.info(f"查询托盘号: {tray_code}") if AppMode.is_api(): self.tary_api = TaryApi() # 调用API获取托盘信息 response = self.tary_api.get_tary_info(tray_code) else: pallet_type_manager = PalletTypeManager.get_instance() pallet_info = pallet_type_manager.get_pallet_info_by_pallet_id(tray_code) # 检查返回的数据类型并进行适当处理 if pallet_info is None: response = { "success": False, "message": "未找到托盘信息" } else: # 如果返回的是元组(数据库查询结果),将其转换为字典 # 根据dao/pallet_type_dao.py中get_pallet_info_by_pallet_id方法的SQL查询 # 返回的字段顺序为:pallet_code, pallet_name, description, axios_name, axios_type, tier, size, amount, weight try: response = { "success": True, "data": { "tp_note": pallet_info[0] if isinstance(pallet_info, tuple) and len(pallet_info) > 0 else "", "product_name": pallet_info[1] if isinstance(pallet_info, tuple) and len(pallet_info) > 1 else "", "axis_type": pallet_info[4] if isinstance(pallet_info, tuple) and len(pallet_info) > 4 else "", "tier": str(pallet_info[5]) if isinstance(pallet_info, tuple) and len(pallet_info) > 5 else "", "weight": str(pallet_info[8]) if isinstance(pallet_info, tuple) and len(pallet_info) > 8 else "", "quantity": "" } } except (IndexError, TypeError) as e: logging.warning(f"处理托盘信息时出错: {str(e)}, pallet_info类型: {type(pallet_info)}") # 如果pallet_info是字符串或其他非元组类型,创建一个基本响应 response = { "success": True, "data": { "tp_note": tray_code, "product_name": "", "axis_type": "", "tier": "", "weight": "", "quantity": "" } } logging.info(f"托盘信息响应: {response}") logging.info(f"response.success={response.get('success')}, response.data存在={response.get('data') is not None}") if response.get("success", False) and response.get("data"): tray_data = response.get("data", {}) logging.info(f"托盘数据: {tray_data}") # 显示托盘相关信息 - 只更新轴型、托盘料和重量,不更新订单号和产品 axis_type = str(tray_data.get("axis_type", "--")) tier = str(tray_data.get("tier", "--")) weight = str(tray_data.get("weight", "--")) logging.info(f"显示托盘信息: 轴型={axis_type}, 托盘料={tier}, 重量={weight}") # 只设置轴型、托盘料和重量字段,不设置产品名称 self.axis_value.setText(axis_type) self.pallet_tier_value.setText(tier) self.quantity_value.setText("") # 数量为空 self.weight_value.setText(f"{weight} kg") # 发送托盘号到主窗口 from widgets.main_window import MainWindow main_window = self.parent if main_window and isinstance(main_window, MainWindow): # 检查托盘号是否已存在 existed = False for i in range(main_window.tray_edit.count()): if main_window.tray_edit.itemText(i) == tray_code: existed = True break # 如果不存在,则添加 if not existed: logging.info(f"添加托盘号到主窗口: {tray_code}") main_window.tray_edit.addItem(tray_code) # 设置当前选中的托盘号 main_window.tray_edit.setCurrentText(tray_code) logging.info(f"设置主窗口当前托盘号: {tray_code}") else: # 获取托盘信息失败 error_msg = response.get("message", "获取托盘信息失败") logging.warning(f"查询失败: {error_msg}") QMessageBox.warning(self, "查询失败", error_msg) except Exception as e: logging.error(f"查询托盘信息异常: {str(e)}") QMessageBox.critical(self, "查询异常", f"查询托盘信息时发生异常: {str(e)}") def keyPressEvent(self, event): """重写键盘事件处理,防止回车关闭对话框""" # 如果按下回车键 if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter: logging.info(f"捕获到回车键事件,当前焦点部件: {self.focusWidget()}") # 如果焦点在托盘输入框上,触发查询 # 注释掉此处的on_tray_query调用,因为已经通过returnPressed信号处理了 if self.focusWidget() == self.tray_input: # self.on_tray_query() - 通过returnPressed信号已经处理,这里不需要再调用 event.accept() # 消费掉这个事件 return # 如果焦点在确认按钮上,则允许默认行为(确认) if self.focusWidget() == self.confirm_button: return super().keyPressEvent(event) # 其他情况下,阻止回车事件传播 event.accept() # 消费掉这个事件 return # 其他键位事件交给父类处理 super().keyPressEvent(event) def accept(self): """重写接受方法,确保在确认前所有数据都已处理""" logging.info("确认按钮被点击或回车触发确认") # 确保主窗口启动了监听 from widgets.main_window import MainWindow main_window = self.parent if main_window and isinstance(main_window, MainWindow): # 确保主窗口已启动监听 try: if not hasattr(main_window, 'modbus_monitor') or not main_window.modbus_monitor.is_running(): main_window.setup_modbus_monitor() logging.info("已在LoadingDialog确认时启动Modbus监控") # 启动串口监听 main_window.serial_manager.auto_open_configured_ports() # 启动键盘监听器 main_window.serial_manager.start_keyboard_listener() logging.info("已在LoadingDialog确认时启动键盘监听器") except Exception as e: logging.error(f"LoadingDialog确认时启动监听失败: {str(e)}") # 调用父类的accept方法关闭对话框 super().accept() def reject(self): """重写拒绝方法""" logging.info("取消按钮被点击或ESC触发取消") # 调用父类的reject方法关闭对话框 super().reject()