jiateng_ws/widgets/unloading_dialog_widget.py

306 lines
14 KiB
Python
Raw Permalink 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.

from ui.unloading_dialog_ui import UnloadingDialogUI
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
from utils.modbus_utils import ModbusUtils
class UnloadingDialog(UnloadingDialogUI):
# 定义一个信号,用于向主窗口传递托盘号
tray_code_signal = Signal(str, str, str, str)
def __init__(self, parent=None, user_id=None):
"""初始化下料对话框"""
super().__init__()
self.parent = parent
self.user_id = user_id
self.current_tier = None # 添加一个变量来保存当前层数
# 初始化API
self.tary_api = TaryApi()
# 彻底禁用对话框的回车键关闭功能
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.init_pallet_types()
# 绑定事件
self.setup_connections()
def init_pallet_types(self):
"""初始化托盘类型下拉列表"""
# 从数据库获取托盘类型列表
pallet_type_manager = PalletTypeManager.get_instance()
pallet_types = pallet_type_manager.get_pallet_types()
# 清空现有选项
self.pallet_type_input.clear()
# 添加新选项
for pallet_id, pallet_name in pallet_types.items():
self.pallet_type_input.addItem(pallet_name, userData=pallet_id)
logging.info(f"从数据库加载{len(pallet_types)}个托盘类型")
def get_current_pallet_type_id(self):
"""获取当前选中的托盘类型ID"""
current_index = self.pallet_type_input.currentIndex()
if current_index >= 0:
pallet_id = self.pallet_type_input.itemData(current_index)
logging.info(f"获取当前选中的托盘类型ID: {pallet_id}")
return pallet_id
logging.warning("未获取到托盘类型ID")
return None
def get_current_tier(self):
"""获取当前托盘的层数"""
tier = self.tier_input.text().strip()
if not tier:
return self.current_tier if self.current_tier else "3"
return tier
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()
tier = self.tier_input.text().strip() # 获取用户输入的层数
pallet_type = self.pallet_type_input.currentText().strip()
if not tray_code:
return
logging.info(f"查询托盘号: {tray_code}")
# 初始化托盘类型管理器
pallet_type_manager = PalletTypeManager.get_instance()
if AppMode.is_api():
self.tary_api = TaryApi()
# 调用API获取托盘信息
response = self.tary_api.get_tary_info(tray_code)
if response.get("success", False) and response.get("data"):
tray_data = response.get("data", {})
logging.info(f"API返回托盘数据: {tray_data}")
# 如果用户输入了层数,使用用户输入的层数
if tier:
tray_data["tier"] = tier
pallet_type_manager.save_pallet_info(tray_code, tray_data, self.user_id)
else:
# API查询失败保存基本信息到数据库
logging.info(f"API查询失败保存基本信息到数据库")
# if not pallet_type or not tier:
# QMessageBox.warning(self, "提示", "请选择托盘类型和层数")
# return
pallet_info = {
"cc": pallet_type,
"cs": tier # 使用用户输入的层数
}
pallet_type_manager.save_pallet_info(tray_code, pallet_info, self.user_id)
else:
# 查询数据库中的托盘信息
pallet_info = pallet_type_manager.get_pallet_info_by_pallet_id(tray_code)
if not pallet_info:
# 数据库中没有记录,保存基本信息
logging.info(f"数据库中未找到记录,保存基本信息")
# if not pallet_type or not tier:
# QMessageBox.warning(self, "提示", "请选择托盘类型和层数")
# return
pallet_info = {
"cc": pallet_type,
"cs": tier # 使用用户输入的层数
}
pallet_type_manager.save_pallet_info(tray_code, pallet_info, self.user_id)
# 重新获取完整的托盘信息
pallet_info = pallet_type_manager.get_pallet_detail(tray_code)
if not pallet_info:
logging.warning(f"无法获取托盘详细信息: {tray_code}")
pallet_info = {
"zx_name": "--",
"cz": "--",
"weight": "0",
"amount": "0",
"tier": tier if tier else "4", # 使用用户输入的层数如果没有则默认3层
"pallet_name": pallet_type
}
# 显示托盘相关信息
axis_type = str(pallet_info.get("zx_name", "--"))
material = str(pallet_info.get("cz", "--"))
weight = str(pallet_info.get("weight", "--"))
amount = str(pallet_info.get("amount", "--"))
self.current_tier = pallet_info.get("cs", tier if tier else "4") # 优先使用数据库中的层数,其次是用户输入的层数,最后是默认值
logging.info(f"显示托盘信息: 轴型={axis_type}, 材质={material}, 重量={weight}, 层数={self.current_tier}")
# 设置显示值
self.axis_value.setText(axis_type)
self.material_tier_value.setPlaceholderText(material)
self.material_tier_value.setText("") # 清空文本,让用户输入
self.quantity_value.setText(amount)
self.weight_value.setText(f"{weight} kg")
self.tier_input.setText(str(self.current_tier)) # 设置层数输入框的值
self.pallet_type_input.setCurrentText(pallet_info.get("pallet_name", "--"))
# 发送托盘号到主窗口
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}")
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()}")
# 如果焦点在托盘输入框上,触发查询
if self.focusWidget() == self.tray_input:
# 不需要重复调用on_tray_query因为returnPressed信号已经处理了
event.accept() # 消费掉这个事件
return
# 如果焦点在确认按钮上,则允许默认行为(确认)
if self.focusWidget() == self.confirm_button:
return super().keyPressEvent(event)
# 其他情况下,阻止回车事件传播
event.accept() # 消费掉这个事件
return
# 其他键位事件交给父类处理
super().keyPressEvent(event)
def get_unloading_info(self):
"""获取当前下料信息"""
return {
'tray_code': self.tray_input.text().strip(),
'tier': self.tier_input.text().strip(),
'pallet_type': self.pallet_type_input.currentText().strip(),
'pallet_type_id': self.get_current_pallet_type_id(),
'axis_type': self.axis_value.text().strip(),
'material': self.material_tier_value.text().strip(),
'quantity': self.quantity_value.text().strip(),
'weight': self.weight_value.text().strip()
}
def set_unloading_info(self, info):
"""设置下料信息"""
if not info:
return
self.tray_input.setText(info.get('tray_code', ''))
self.tier_input.setText(info.get('tier', ''))
# 设置托盘类型
pallet_type = info.get('pallet_type', '')
index = self.pallet_type_input.findText(pallet_type)
if index >= 0:
self.pallet_type_input.setCurrentIndex(index)
# 设置其他信息
self.axis_value.setText(info.get('axis_type', '--'))
self.material_tier_value.setText(info.get('material', '--'))
self.quantity_value.setText(info.get('quantity', '0'))
self.weight_value.setText(info.get('weight', '0 kg'))
# 记录日志
logging.info(f"回显下料信息: 托盘号={info.get('tray_code', '')}, 层数={info.get('tier', '')}")
def accept(self):
"""确认按钮点击事件"""
try:
# 获取输入的值
tray_code = self.tray_input.text().strip()
tier = self.tier_input.text().strip()
pallet_type = self.pallet_type_input.currentText().strip()
# 验证输入
if not tray_code:
QMessageBox.warning(self, "提示", "请输入托盘号")
return
if not tier:
QMessageBox.warning(self, "提示", "请输入层数")
return
if not pallet_type or pallet_type == "请选择":
QMessageBox.warning(self, "提示", "请选择托盘类型")
return
# 获取托盘类型ID并写入寄存器
pallet_type_id = self.get_current_pallet_type_id()
if pallet_type_id is not None:
try:
modbus = ModbusUtils()
client = modbus.get_client()
modbus.write_register_until_success(client, 1, int(pallet_type_id))
logging.info(f"已将托盘类型ID {pallet_type_id} 写入寄存器1")
except Exception as e:
logging.error(f"写入托盘类型ID到寄存器失败: {str(e)}")
QMessageBox.critical(self, "Modbus通信错误", f"写入托盘类型ID失败: {str(e)}")
# 即使失败也允许继续,但给与提示
finally:
if 'modbus' in locals() and client:
modbus.close_client(client)
else:
QMessageBox.warning(self, "提示", "无法获取托盘类型ID请检查配置")
# 保存托盘档案信息
try:
pallet_type_manager = PalletTypeManager.get_instance()
material = self.material_tier_value.text().strip()
pallet_info = {"cc": pallet_type, "cs": tier, "cz": material}
pallet_type_manager.save_pallet_info(tray_code, pallet_info, self.user_id)
logging.info(f"已保存下料托盘信息: {tray_code}, 层数={tier}, 托盘类型={pallet_type}, 材质={material}")
except Exception as e:
logging.error(f"保存下料托盘信息失败: {str(e)}")
# 调用父类的accept方法关闭对话框由主窗口处理后续逻辑
super().accept()
except Exception as e:
logging.error(f"下料对话框确认时发生错误: {str(e)}")
QMessageBox.critical(self, "错误", f"确认下料失败: {str(e)}")