jiateng_ws/widgets/loading_dialog_widget.py
2025-07-19 02:00:22 +08:00

355 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import logging
from PySide6.QtWidgets import QMessageBox
from PySide6.QtCore import Qt, Signal
from ui.loading_dialog_ui import LoadingDialogUI
from widgets.order_query_dialog import OrderQueryDialog
from utils.app_mode import AppMode
from utils.pallet_type_manager import PalletTypeManager
from apis.gc_api import GcApi
class LoadingDialog(LoadingDialogUI):
"""上料操作对话框"""
# 定义信号,用于向主窗口传递托盘号
tray_code_signal = Signal(str, str, str, str)
# 定义信号,用于向主窗口传递订单号
order_code_signal = Signal(str)
def __init__(self, parent=None, user_id=None, user_name=None, corp_id=None):
super().__init__()
self.parent = parent
self.user_id = user_id,
self.user_name = user_name
self.corp_id = corp_id
# 存储订单数据
# self.order_data = None
# 彻底禁用对话框的回车键关闭功能
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)
# 确保焦点跟踪器能够跟踪此对话框中的输入框
from utils.focus_tracker import FocusTracker
self.focus_tracker = FocusTracker.get_instance()
# 连接信号和槽
self.connect_signals()
def connect_signals(self):
"""连接信号和槽"""
# 订单查询按钮点击事件
self.order_query_btn.clicked.connect(self.show_order_query_dialog)
# 订单号输入框回车事件触发查询
self.order_input.returnPressed.connect(self.handle_order_return_pressed)
# 确认按钮点击事件
self.confirm_button.clicked.connect(self.accept)
# 取消按钮点击事件
self.cancel_button.clicked.connect(self.reject)
# 托盘号输入框回车事件
self.tray_input.returnPressed.connect(self.on_tray_entered)
def handle_order_return_pressed(self):
"""处理订单输入框的回车事件"""
logging.info("订单输入框回车事件触发")
# 获取当前订单号值
order_code = self.order_input.text().strip()
if not order_code:
QMessageBox.warning(self, "提示", "请输入订单号")
return
# 发送订单号到主窗口
from widgets.main_window import MainWindow
main_window = self.parent
if main_window and isinstance(main_window, MainWindow):
logging.info(f"发送订单号到主窗口: {order_code}")
self.order_code_signal.emit(order_code)
# 查询订单信息
self.on_order_query(order_code)
# 阻止事件继续传播
return True
def show_order_query_dialog(self):
"""显示订单查询对话框"""
try:
# 创建订单查询对话框
dialog = OrderQueryDialog(self)
# 连接订单选择信号
dialog.order_selected.connect(self.on_order_selected)
# 显示对话框
dialog.exec()
except Exception as e:
logging.error(f"显示订单查询对话框失败: {e}")
QMessageBox.critical(self, "错误", f"显示订单查询对话框失败: {str(e)}")
def on_order_selected(self, order_data):
"""处理订单选择事件
Args:
order_data: 订单数据字典
"""
try:
# 存储订单数据
self.order_data = order_data
# 更新UI
# 注意此时order_data["note"]已经被修改为order_data["mo"]的值
self.order_input.setText(order_data.get("note", ""))
# 更新轴型
self.axis_value.setText(order_data.get("zx_name", "--"))
# 更新数量
self.quantity_value.setText(str(order_data.get("sl", "--")))
# 更新重量
self.weight_value.setText(str(order_data.get("zx_zl", "--")))
# 自动填充托盘号
if "xpack" in order_data:
self.tray_input.setText(order_data["xpack"])
# 发送订单号到主窗口
from widgets.main_window import MainWindow
main_window = self.parent
if main_window and isinstance(main_window, MainWindow):
# 使用note字段作为订单号已经被修改为mo的值
order_code = order_data.get("note", "")
logging.info(f"发送订单号到主窗口: {order_code}")
self.order_code_signal.emit(order_code)
# 设置焦点到托盘号输入框
self.tray_input.setFocus()
except Exception as e:
logging.error(f"处理订单选择事件失败: {e}")
QMessageBox.critical(self, "错误", f"处理订单选择事件失败: {str(e)}")
def on_order_query(self, order_code):
"""查询订单信息,同时生成托盘号,并且回显到页面上"""
try:
# 构建查询参数
query_params = {
"srch_mo": order_code,
"srch_note": order_code,
"corp_id": self.corp_id
}
# 创建订单查询对话框(仅用于执行查询)
dialog = OrderQueryDialog(self)
# 执行查询
results = dialog.query_orders(query_params)
# 处理查询结果
if results:
# 如果只有一个结果,直接使用
if len(results) == 1:
self.on_order_selected(results[0])
return
else:
# 如果有多个结果,显示查询对话框让用户选择
dialog.update_result_table(results)
dialog.order_selected.connect(self.on_order_selected)
dialog.exec()
return
# 如果没有结果并且不是API模式显示提示
if not AppMode.is_api():
QMessageBox.warning(self, "提示", f"未找到订单: {order_code}")
return
# 如果是API模式尝试使用旧的API方式查询
# 调用接口
gc_api = GcApi()
# 防止response为None导致异常
# 获取工程号信息,并且初始化数据
order_response = gc_api.get_order_info(order_code, self.corp_id)
# 生成托盘号
if order_response and order_response.get("status", False):
# 将接口数据保存到数据库,用于后续的关联使用
from dao.inspection_dao import InspectionDAO
inspection_dao = InspectionDAO()
order_info = order_response.get("data", {})[0]
# 设置轴数
order_info['user_id'] = self.user_id[0]
order_info['user_name'] = self.user_name
order_info['data_corp'] = self.corp_id
inspection_dao.save_order_info(order_code, order_info)
self.axis_value.setText(order_info['zx_name'])
self.quantity_value.setText(str(order_info['sl']))
self.weight_value.setText(str(order_info['zx_zl']))
# 存储订单数据
self.order_data = order_info
else:
QMessageBox.warning(self, "提示", f"未找到订单: {order_code}")
return
xpack_response = gc_api.get_xpack(order_code, self.corp_id)
if xpack_response and xpack_response.get("status", False):
xpack = xpack_response['xpack']
self.tray_input.setText(xpack)
self.pallet_tier_value.setText('3')
# 发送托盘号到主窗口
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) == xpack:
existed = True
break
# 如果不存在,则添加
if not existed:
logging.info(f"添加托盘号到主窗口: {xpack}")
main_window.tray_edit.addItem(xpack)
# 设置当前选中的托盘号
main_window.tray_edit.setCurrentText(xpack)
logging.info(f"设置主窗口当前托盘号: {xpack}")
return order_info
except Exception as e:
logging.error(f"查询订单信息失败: {e}")
QMessageBox.critical(self, "错误", f"查询订单信息失败: {str(e)}")
def on_tray_entered(self):
"""处理托盘号输入框回车事件"""
tray_id = self.tray_input.text().strip()
if not tray_id:
QMessageBox.warning(self, "提示", "请输入托盘号")
return
# 设置焦点到托盘料输入框
self.pallet_tier_value.setFocus()
def keyPressEvent(self, event):
"""重写键盘事件处理,防止回车关闭对话框"""
# 如果按下回车键
if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
logging.info(f"捕获到回车键事件,当前焦点部件: {self.focusWidget()}")
# 如果焦点在托盘输入框上,触发查询
if self.focusWidget() == self.tray_input:
event.accept() # 消费掉这个事件
return
# 如果焦点在确认按钮上,则允许默认行为(确认)
if self.focusWidget() == self.confirm_button:
return super().keyPressEvent(event)
# 其他情况下,阻止回车事件传播
event.accept() # 消费掉这个事件
return
# 其他键位事件交给父类处理
super().keyPressEvent(event)
def accept(self):
"""重写接受方法,确保在确认前所有数据都已处理"""
logging.info("确认按钮被点击或回车触发确认")
# 检查托盘层数是否有值
tier_value = self.pallet_tier_value.text().strip()
if not tier_value:
QMessageBox.warning(self, "提示", "请输入托盘层数")
return
# 获取包装号
pallet_code = self.tray_input.text().strip()
if not pallet_code:
QMessageBox.warning(self, "提示", "请输入托盘号")
return
# 检查订单号
order_id = self.order_input.text().strip()
if not order_id:
QMessageBox.warning(self, "提示", "请输入订单号")
self.order_input.setFocus()
return
# if not self.order_data:
# QMessageBox.warning(self, "提示", "请先查询订单信息")
# return
try:
# 保存托盘档案信息
pallet_manager = PalletTypeManager.get_instance()
success = pallet_manager.save_pallet_archives(
pallet_code=pallet_code,
tier=int(tier_value),
user_id=self.user_id[0],
user_name=self.user_name
)
if not success:
QMessageBox.warning(self, "提示", "保存托盘档案失败")
return
logging.info(f"已保存托盘档案:托盘号={pallet_code}, 层数={tier_value}")
except Exception as e:
logging.error(f"保存托盘档案时发生错误: {str(e)}")
QMessageBox.warning(self, "错误", f"保存托盘档案失败: {str(e)}")
return
# 确保主窗口启动了监听
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()
def get_loading_data(self):
"""获取上料数据
Returns:
dict: 上料数据字典
"""
return {
"order_id": self.order_input.text().strip(),
"tray_id": self.tray_input.text().strip(),
"pallet_tier": self.pallet_tier_value.text().strip(),
"order_data": self.order_data
}