From 584f98a1a258942f7da82531635b6520d9f8348a Mon Sep 17 00:00:00 2001
From: zhu-mengmeng <15588200382@163.com>
Date: Tue, 24 Jun 2025 16:33:33 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E4=B8=8B=E6=96=99?=
=?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=B8=8B=E6=96=99?=
=?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=9B=9E=E6=98=BE=E5=8A=9F=E8=83=BD=EF=BC=8C?=
=?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8B=E6=96=99=E7=8A=B6=E6=80=81=E5=8F=8D?=
=?UTF-8?q?=E9=A6=88=E4=B8=8EUI=E6=9B=B4=E6=96=B0=EF=BC=8C=E5=A2=9E?=
=?UTF-8?q?=E5=BC=BA=E7=94=A8=E6=88=B7=E4=BA=A4=E4=BA=92=E4=BD=93=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
dao/inspection_dao.py | 11 +-
db/jtDB.db | Bin 77824 -> 77824 bytes
from pymodbus.py | 12 +-
utils/register_handlers.py | 16 +-
widgets/loading_dialog_widget.py | 2 +-
widgets/main_window.py | 360 ++++++++++++++++++++---------
widgets/unloading_dialog_widget.py | 104 ++++++++-
7 files changed, 367 insertions(+), 138 deletions(-)
diff --git a/dao/inspection_dao.py b/dao/inspection_dao.py
index e6d0ad2..26f58f4 100644
--- a/dao/inspection_dao.py
+++ b/dao/inspection_dao.py
@@ -242,6 +242,7 @@ class InspectionDAO:
gzl = ?, maxsl = ?, cz = ?, size = ?, cd = ?, luno = ?,
qfqd = ?, pono = ?, xj = ?, ysl = ?, dycz = ?,
zx_code = ?, edit_id = ?, remarks = ?, zx_name = ?
+ bccd = ? ,tccd = ?
WHERE ddmo = ?
"""
params = (
@@ -274,6 +275,8 @@ class InspectionDAO:
data.get("edit_id", ""),
data.get("remarks", ""),
data.get("zx_name", ""),
+ data.get("bccd", ""),
+ data.get("tccd", ""),
data.get("mo", "") # WHERE 条件参数
)
logging.info(f"更新订单信息: ddmo={data.get('mo', '')}")
@@ -284,10 +287,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
+ pono, xj, ysl, dycz, zx_code, edit_id, remarks,zx_name,bccd,tccd
) VALUES (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
- ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
+ ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)
"""
params = (
@@ -320,7 +323,9 @@ class InspectionDAO:
data.get("zx_code", ""),
data.get("edit_id", ""),
data.get("remarks", ""),
- data.get("zx_name", "")
+ data.get("zx_name", ""),
+ data.get("bccd", ""),
+ data.get("tccd", "")
)
logging.info(f"插入新订单信息: ddmo={data.get('mo', '')}")
diff --git a/db/jtDB.db b/db/jtDB.db
index 96af15d3b5c1bf3b08fff990e976c796d19a58d4..1083177bf6366a5769f78d7b15b07ae0cefe8890 100644
GIT binary patch
delta 893
zcmaiy&ubGw6vrpoG^S~0^P`C&hSWq2Sn})b?966&J%pHgNT?y=9;7MM7!Mw`h#nKs
zQi5131*0M&c
+kUU85`~
z5>aI&E(o$jdx*;5UFeXO0gJ@h9=D$#Y0i#K42bQA!*~!ys49@|r2R*d3bIP&&QT?s
z@8^SJcXseaNB1(r@j`o2MWIP14Y%k6klxDrC5+v(pTHxH-(OvvmBaIh|He<@`3Aq6
z$KgjQ?wm6a@u2e<`!GK1_k^*}=kfSL2zwCHqf1`zT6)i40hZI+YX&hUwBD|_YOi`h
zrU3dvrMX#v=ChSwAKv}=ywQ5OJa+>?kdvUqWkm!!tM6TG?kqJwzR^Jh90Y
zKiFFLuwo()Fx@t~Ll6W%T%$M}MAI-3Y%JxjZR82k24
I5yo<900Ts1B>(^b
diff --git a/from pymodbus.py b/from pymodbus.py
index 6c291ff..072c855 100644
--- a/from pymodbus.py
+++ b/from pymodbus.py
@@ -1,17 +1,21 @@
from pymodbus.client import ModbusTcpClient
-
+import time
client = ModbusTcpClient('localhost', port=5020)
client.connect()
-client.write_registers(address=11, values=[2223])
+client.write_registers(address=11, values=[2222])
client.write_registers(address=13, values=[0])
-client.write_registers(address=20, values=[1])
+client.write_registers(address=21, values=[0])
+time.sleep(2)
+# client.write_registers(address=21, values=[1])
+
+client.write_registers(address=20, values=[0])
# client.write_registers(address=5, values=[16])
# 贴标完成
# client.write_registers(address=24, values=[1])
# client.write_registers(address=13, values=[0])
-result = client.read_holding_registers(address=13, count=1)
+result = client.read_holding_registers(address=1, count=1)
print(result.registers[0],"123===")
client.close()
\ No newline at end of file
diff --git a/utils/register_handlers.py b/utils/register_handlers.py
index d28acfc..f2b44a8 100644
--- a/utils/register_handlers.py
+++ b/utils/register_handlers.py
@@ -126,12 +126,10 @@ class LoadingFeedbackHandler(RegisterHandler):
self.callback = callback
def handle_change(self, value):
- feedback = "上料" if value == 1 else "无操作"
- logging.info(f"上料信息反馈: {feedback}")
-
- # 如果有回调函数,则调用
- if self.callback:
+ if value == 1: # Only emit signal when loading is complete
+ feedback = "上料完成"
self.callback(value, feedback)
+ logging.info(f"Loading feedback: {feedback} (value: {value})")
class UnloadingFeedbackHandler(RegisterHandler):
@@ -141,12 +139,10 @@ class UnloadingFeedbackHandler(RegisterHandler):
self.callback = callback
def handle_change(self, value):
- feedback = "下料" if value == 1 else "无操作"
- logging.info(f"下料信息反馈: {feedback}")
-
- # 如果有回调函数,则调用
- if self.callback:
+ if value == 1: # Only emit signal when unloading is complete
+ feedback = "下料完成"
self.callback(value, feedback)
+ logging.info(f"Unloading feedback: {feedback} (value: {value})")
class Error1Handler(RegisterHandler):
diff --git a/widgets/loading_dialog_widget.py b/widgets/loading_dialog_widget.py
index 0f44bd4..e8b45d0 100644
--- a/widgets/loading_dialog_widget.py
+++ b/widgets/loading_dialog_widget.py
@@ -36,7 +36,7 @@ class LoadingDialog(LoadingDialogUI):
def setup_connections(self):
"""设置事件连接"""
- # 托盘号输入框回车事件触发查询
+ # 订单号输入框回车事件触发查询
self.order_input.returnPressed.connect(self.handle_order_return_pressed)
# 确认按钮点击事件
diff --git a/widgets/main_window.py b/widgets/main_window.py
index 2e2e9d6..942005d 100644
--- a/widgets/main_window.py
+++ b/widgets/main_window.py
@@ -44,30 +44,43 @@ from utils.pallet_type_manager import PalletTypeManager
# 导入串口管理
from utils.serial_manager import SerialManager
from widgets.report_dialog import ReportDialog
+from widgets.unloading_dialog_widget import UnloadingDialog
class MainWindow(MainWindowUI):
"""主窗口"""
# 定义信号作为类变量
loading_feedback_signal = Signal(str, str) # 参数:status_type, desc
+ unloading_feedback_signal = Signal(str, str) # 参数:status_type, desc
+ unloading_level_ui_signal = Signal(int) # 用于在主线程中更新下料层数UI
+ unloading_position_ui_signal = Signal(int) # 用于在主线程中更新下料位置UI
def __init__(self, user_id=None, user_name=None, corp_name=None, corp_id=None):
- super().__init__(user_name)
-
+ """初始化主窗口"""
+ super().__init__(username=user_name) # 将 user_name 作为 username 参数传递给父类
self.user_id = user_id
self.user_name = user_name
self.corp_name = corp_name
self.corp_id = corp_id
- self.init_seq = {} # 初始化轴包装的序号
- self._loading_data_in_progress = False # 数据加载状态标志,防止循环调用
- self._current_order_code = None # 存储当前订单号
- # 添加拆垛相关的属性
+ # 初始化数据加载状态标志
+ self._loading_data_in_progress = False # 数据加载状态标志,防止循环调用
+ self._current_order_code = None # 存储当前订单号
+ self.init_seq = {} # 初始化轴包装的序号
+
+ # 初始化拆垛和下料相关的属性
self._current_stow_num = 0 # 当前拆垛层数
+ self._current_unload_num = 0 # 当前下料层数
+ self._total_unload_num = 0 # 总下料层数
+ self._current_unload_info = None # 存储当前下料信息
self._loading_info = None # 存储上料对话框的信息
# 连接信号到槽
self.loading_feedback_signal.connect(self._handle_loading_feedback_ui)
+ self.unloading_feedback_signal.connect(self._handle_unloading_feedback_ui)
+ # 连接新增的信号
+ self.unloading_level_ui_signal.connect(self.handle_unloading_level_ui)
+ self.unloading_position_ui_signal.connect(self.handle_unloading_position_ui)
# 称重相关变量
self._current_weight = None # 当前称重值(千克)
@@ -450,94 +463,84 @@ class MainWindow(MainWindowUI):
def handle_output(self):
"""处理下料按钮点击事件"""
- # 获取托盘号
- tray_id = self.tray_edit.currentText()
-
- # 启动监听(不论后续是否确认下料)
- # 启动Modbus监控
- if not hasattr(self, 'modbus_monitor') or not self.modbus_monitor.is_running():
- self.setup_modbus_monitor()
- logging.info("已在下料操作前启动Modbus监控")
-
- # 启动串口监听
- self.serial_manager.auto_open_configured_ports()
-
- # 启动键盘监听器
- self.serial_manager.start_keyboard_listener()
- logging.info("已在下料操作前启动键盘监听器")
-
- # 创建下料对话框
- from widgets.unloading_dialog_widget import UnloadingDialog
- dialog = UnloadingDialog(parent=self, user_id=self.user_id)
-
- # 显示对话框
- result = dialog.exec()
-
- # 如果用户确认,则执行下料操作
- if result == QDialog.Accepted:
- # 获取托盘料值作为下料层数
- pallet_type_id = dialog.get_current_pallet_type_id() # 获取托盘类型ID
- tier_num = dialog.get_current_tier() # 获取托盘层数
-
- if not pallet_type_id:
- QMessageBox.warning(self, "错误", "未获取到托盘类型信息,请重试")
- return
-
- if not tier_num:
- QMessageBox.warning(self, "错误", "未获取到托盘层数信息,请重试")
- return
-
- # 获取托盘号对应的托盘类型
- pallet_type = self.pallet_type_manager.get_pallet_type_by_pallet_id(tray_id)
- # 初始化托盘号对应的序号
- if tray_id not in self.init_seq:
- self.init_seq[tray_id] = 1
+ try:
+ # 启动监听(不论后续是否确认下料)
+ if not hasattr(self, 'modbus_monitor') or not self.modbus_monitor.is_running():
+ self.setup_modbus_monitor()
+ self.serial_manager.auto_open_configured_ports()
+ self.serial_manager.start_keyboard_listener()
- if not pallet_type:
- QMessageBox.warning(self, "错误", "未查到对应下料托盘类型")
- return
-
- # 执行Modbus操作
- modbus = ModbusUtils()
- client = modbus.get_client()
- try:
- # 下料 D3 寄存器写入 1 D1 寄存器写入托盘类型 D0 寄存器写入层数
- success0 = modbus.write_register_until_success(client, 0, int(tier_num)) # 写入层数
- success1 = modbus.write_register_until_success(client, 1, int(pallet_type_id)) # 写入托盘类型ID
- success3 = modbus.write_register_until_success(client, 3, 1)
+ dialog = UnloadingDialog(self, self.user_id)
+
+ # 如果是同一下料任务(_current_unload_info不为空),则回显信息
+ if self._current_unload_info:
+ # 关键:确保回显到对话框的是固定的总层数
+ self._current_unload_info['tier'] = str(self._total_unload_num)
+ dialog.set_unloading_info(self._current_unload_info)
+ logging.info(f"回显下料信息:当前层数={self._current_unload_num}, 总层数={self._total_unload_num}")
+
+ if dialog.exec_() == QDialog.Accepted:
+ unloading_info = dialog.get_unloading_info()
- if success0 and success1 and success3:
- # 创建状态标签并显示在右上角
- self.show_operation_status("码垛层数", "output", tier_num)
+ # 仅当开始一次全新的下料时(没有进行中的任务),才设置总层数
+ is_new_task = not self._current_unload_info or self._current_unload_num == 0
+ if is_new_task:
+ self._total_unload_num = int(unloading_info.get('tier', '3'))
+ self._current_unload_num = 1
+ self._current_unload_info = unloading_info
+ logging.info(f"新的下料任务开始:总层数={self._total_unload_num}, 当前层数={self._current_unload_num}")
+
+ # 将初始层数(1)写入寄存器
+ modbus = ModbusUtils()
+ client = modbus.get_client()
+ try:
+ modbus.write_register_until_success(client, 4, self._current_unload_num)
+ logging.info(f"下料初始化成功:层数 {self._current_unload_num} 已写入寄存器4")
+ finally:
+ modbus.close_client(client)
else:
- QMessageBox.information(self, "操作提示", "码垛层数设置失败")
- except Exception as e:
- logging.error(f"码垛层数操作失败: {str(e)}")
- QMessageBox.critical(self, "错误", f"码垛失败: {str(e)}")
- finally:
- modbus.close_client(client)
-
+ logging.info(f"继续下料任务:总层数={self._total_unload_num}, 当前层数={self._current_unload_num}")
+
+ # 统一更新UI显示
+ tray_code = self._current_unload_info.get('tray_code', '')
+ self.show_operation_status("下料层数", "output", f"{self._current_unload_num}/{self._total_unload_num} ")
+ else:
+ logging.info("下料对话框已取消")
+ except Exception as e:
+ logging.error(f"处理下料操作失败: {str(e)}")
+ QMessageBox.critical(self, "错误", f"处理下料操作失败: {str(e)}")
+
def handle_start(self):
"""
处理开始按钮点击事件
- 每次点击开始时,将当前层数写入D0寄存器,并将D2,D3寄存器设置为1
+ 根据当前操作类型(上料/下料)写入相应的寄存器
+ - 上料: 将当前层数写入D0寄存器,并将D2寄存器设置为1
+ - 下料: 确保D3寄存器设置为1,D4寄存器已包含当前下料层数
"""
- if self._current_stow_num <= 0:
- QMessageBox.warning(self, "提示", "请先进行上料操作")
- return
-
modbus = ModbusUtils()
client = modbus.get_client()
try:
- # 写入当前层数到D0寄存器
- success0 = modbus.write_register_until_success(client, 0, self._current_stow_num)
- success2 = modbus.write_register_until_success(client, 2, 1)
- success3 = modbus.write_register_until_success(client, 3, 1)
-
- if success0 and success2 and success3:
- logging.info(f"开始操作:当前层数 {self._current_stow_num}")
+ # 判断当前操作类型(通过检查当前下料信息是否存在)
+ if self._current_unload_info and self._current_unload_num > 0:
+ # 下料模式 - 开始下料操作
+ # 确保寄存器3(下料启动)设为1,寄存器4已在handle_output中设置了当前层数
+ success3 = modbus.write_register_until_success(client, 3, 1)
+
+ if success3:
+ logging.info(f"开始下料操作:当前层数 {self._current_unload_num}/{self._total_unload_num}")
+ QMessageBox.information(self, "操作提示", f"开始下料操作:当前第{self._current_unload_num}层")
+ else:
+ QMessageBox.warning(self, "错误", "开始下料操作失败")
else:
- QMessageBox.warning(self, "错误", "开始操作失败")
+ # 上料模式 - 默认操作
+ # 写入当前层数到D0寄存器
+ success0 = modbus.write_register_until_success(client, 0, self._current_stow_num)
+ success2 = modbus.write_register_until_success(client, 2, 1)
+
+ if success0 and success2:
+ logging.info(f"开始上料操作:当前层数 {self._current_stow_num}")
+ else:
+ QMessageBox.warning(self, "错误", "开始上料操作失败")
except Exception as e:
logging.error(f"开始操作失败: {str(e)}")
QMessageBox.critical(self, "错误", f"开始操作失败: {str(e)}")
@@ -545,28 +548,53 @@ class MainWindow(MainWindowUI):
modbus.close_client(client)
def handle_stop(self):
- """处理停止按钮点击事件,并关闭 modbus 监控"""
+ """处理停止按钮点击事件,根据当前操作类型(上料/下料)停止相应的操作并关闭modbus监控"""
modbus = ModbusUtils()
client = modbus.get_client()
try:
- success2 = modbus.write_register_until_success(client, 2, 0)
- success3 = modbus.write_register_until_success(client, 3, 0)
- # 停止 D1 寄存器2、3写入 0
- if not success2 and not success3:
- QMessageBox.information(self, "操作提示", "停止失败")
+ # 判断当前操作类型(通过检查当前下料信息是否存在)
+ if self._current_unload_info and self._current_unload_num > 0:
+ # 下料模式 - 停止下料操作
+ success3 = modbus.write_register_until_success(client, 3, 0)
+
+ if success3:
+ logging.info(f"停止下料操作:当前层数 {self._current_unload_num}/{self._total_unload_num}")
+ QMessageBox.information(self, "操作提示", "已停止下料操作")
+ else:
+ QMessageBox.warning(self, "错误", "停止下料操作失败")
+ else:
+ # 上料模式 - 停止上料操作
+ success2 = modbus.write_register_until_success(client, 2, 0)
+
+ if success2:
+ logging.info("停止上料操作")
+ QMessageBox.information(self, "操作提示", "已停止上料操作")
+ else:
+ QMessageBox.warning(self, "错误", "停止上料操作失败")
except Exception as e:
logging.error(f"停止操作失败: {str(e)}")
QMessageBox.critical(self, "错误", f"停止操作失败: {str(e)}")
finally:
modbus.close_client(client)
- # 停止Modbus监控
+ # 停止Modbus监控
if hasattr(self, 'modbus_monitor'):
logging.info("停止Modbus监控")
self.modbus_monitor.stop()
# 停止串口监听
self.serial_manager.stop_keyboard_listener()
self.serial_manager.close_all_ports()
-
+
+ def clear_operation_status(self, operation_type):
+ """清除右上角的操作状态显示。"""
+ status_label_name = f"{operation_type}_status_label"
+ if hasattr(self, status_label_name):
+ try:
+ getattr(self, status_label_name).deleteLater()
+ delattr(self, status_label_name)
+ logging.info(f"已清除 '{operation_type}' 状态标签。")
+ except AttributeError:
+ pass # Failsafe
+
def handle_camera_status(self, is_connected, message):
"""处理相机状态变化"""
if is_connected:
@@ -1893,47 +1921,114 @@ class MainWindow(MainWindowUI):
@Slot(int, str)
def handle_loading_feedback(self, status, desc):
"""处理上料信息反馈"""
- logging.info(f"[处理] 上料信息: {desc}")
-
- # 如果上料完成(status=1),显示状态信息,把上料寄存器置为 0
+ message = desc # Default message
if status == 1:
modbus = ModbusUtils()
client = modbus.get_client()
modbus.write_register_until_success(client, 2, 0)
modbus.close_client(client)
- # 更新当前层数
if self._current_stow_num > 0:
+ completed_layer_num = self._current_stow_num
self._current_stow_num -= 1
if self._current_stow_num == 0:
- # 如果所有层都完成,清空上料信息
self._loading_info = None
logging.info("所有层拆垛完成,清空上料信息")
+ message = f"第 {completed_layer_num} 层(最后一层)拆垛完成!"
else:
logging.info(f"当前层拆垛完成,剩余层数: {self._current_stow_num}")
-
- # 通过信号触发UI更新
- self.loading_feedback_signal.emit("input", desc)
+ message = f"第 {completed_layer_num} 层拆垛完成。"
+
+ self.loading_feedback_signal.emit("input", message)
def _handle_loading_feedback_ui(self, status_type, desc):
- """在主线程中处理UI更新"""
+ """在主线程中处理上料UI更新"""
try:
- self.show_operation_status("上料完成", status_type, desc)
+ # 如果上料任务仍在进行,更新层数显示
+ if self._loading_info and self._current_stow_num > 0:
+ self.show_operation_status("拆垛层数", "input", str(self._current_stow_num))
+ else:
+ # 上料任务完成,清除状态显示
+ self.clear_operation_status("input")
+
+ QMessageBox.information(self, "上料操作", desc)
except Exception as e:
- logging.error(f"处理UI更新失败: {str(e)}")
-
+ logging.error(f"处理上料UI更新失败: {str(e)}")
+
@Slot(int, str)
def handle_unloading_feedback(self, status, desc):
"""处理下料信息反馈"""
- logging.info(f"[处理] 下料信息: {desc}")
- # 如果下料完成(status=1),显示状态信息,把下料寄存器置为 0
+ logging.info(f"[处理] 下料信息: {status}, {desc}")
+ # 如果下料完成(status=1),显示状态信息,处理下料流程
if status == 1:
modbus = ModbusUtils()
client = modbus.get_client()
- modbus.write_register_until_success(client, 3, 0)
- modbus.close_client(client)
- self.show_operation_status("下料", "output", desc)
- QMessageBox.information(self, "下料操作", f"下料操作已完成: {desc}")
+
+ try:
+ # 临时重置寄存器3(下料启动)为0,等待用户下一次启动
+ modbus.write_register_until_success(client, 3, 0)
+
+ # 如果当前下料层数小于总层数,则将层数加1并写入寄存器4
+ if self._current_unload_num < self._total_unload_num:
+ # 当前层已完成,准备下一层
+ self._current_unload_num += 1
+ logging.info(f"当前层下料完成,更新层数:当前={self._current_unload_num}, 总数={self._total_unload_num}")
+
+ # 将新的层数写入寄存器4
+ modbus.write_register_until_success(client, 4, self._current_unload_num)
+ logging.info(f"已将新层数{self._current_unload_num}写入寄存器4")
+
+ # 不直接更新UI,而是通过信号将数据传递给主线程处理
+ # 通过信号触发UI更新 - 显示前一层完成的消息
+ message = f"第{self._current_unload_num-1}层下料完成,请启动第{self._current_unload_num}层下料"
+ self.unloading_feedback_signal.emit("output", message)
+ else:
+ # 所有层都下料完成,重置寄存器和计数器
+ modbus.write_register_until_success(client, 3, 0) # 确保下料启动寄存器为0
+ modbus.write_register_until_success(client, 4, 0) # 重置下料层数寄存器为0
+
+ # 记录完成的信息用于消息显示
+ final_tier = self._current_unload_num
+ total_tier = self._total_unload_num
+ tray_code = self._current_unload_info.get('tray_code', '') if self._current_unload_info else ''
+
+ # 重置计数器和信息
+ self._current_unload_num = 0
+ # 不重置总层数,以便可以继续使用相同的总层数
+ # self._total_unload_num = 0
+ self._current_unload_info = None
+
+ logging.info(f"托盘 {tray_code} 的所有 {total_tier} 层下料完成,重置当前层数")
+
+ # 通过信号触发UI更新,而不是直接操作UI
+ message = f"托盘 {tray_code} 的所有 {total_tier} 层下料已全部完成"
+ self.unloading_feedback_signal.emit("output", message)
+ except Exception as e:
+ logging.error(f"处理下料反馈时发生错误: {str(e)}")
+ # 不在这里显示对话框,而是通过信号传递错误信息
+ self.unloading_feedback_signal.emit("error", f"处理下料反馈失败: {str(e)}")
+ finally:
+ modbus.close_client(client)
+
+ def _handle_unloading_feedback_ui(self, status_type, desc):
+ """在主线程中处理下料完成的事件通知"""
+ try:
+ if status_type == "error":
+ QMessageBox.critical(self, "错误", desc)
+ return
+
+ # 显示事件消息
+ if "全部完成" in desc:
+ QMessageBox.information(self, "下料完成", desc)
+ # 任务完成,清除状态显示
+ self.clear_operation_status("output")
+ self.unloading_level_label.setText("下料层数:--")
+ self.unloading_position_label.setText("下料位置:--")
+ elif "请启动" in desc:
+ QMessageBox.information(self, "下料层完成", desc)
+
+ except Exception as e:
+ logging.error(f"处理下料UI更新失败: {str(e)}")
def _update_error_status(self):
"""更新故障状态显示"""
@@ -2025,14 +2120,53 @@ class MainWindow(MainWindowUI):
modbus.close_client(client)
@Slot(int)
def handle_unloading_level(self, level):
- """处理下料层数信息"""
- self.unloading_level_label.setText(f"下料层数:{level}")
+ """处理下料层数信息(来自Modbus)"""
+ # 只更新内存中的当前层数,UI更新通过信号槽完成
+ if self._current_unload_num != level:
+ logging.info(f"下料层数变化:{self._current_unload_num} -> {level}")
+
+ self._current_unload_num = level
+
+ # 更新保存的下料信息中的当前层数值
+ if self._current_unload_info:
+ self._current_unload_info['tier'] = str(level)
+
+ # 通过信号在主线程中更新UI
+ self.unloading_level_ui_signal.emit(level)
+
+ @Slot(int)
+ def handle_unloading_level_ui(self, level):
+ """在主线程中更新下料层数UI"""
+ try:
+ # 更新显示
+ self.unloading_level_label.setText(f"下料层数:{level}")
+
+ # 如果有下料信息且层数大于0,更新右上角显示
+ if level > 0 and self._current_unload_info:
+ tray_code = self._current_unload_info.get('tray_code', '')
+
+ # 确保使用固定的总层数
+ total_tier = self._total_unload_num
+
+ self.show_operation_status("下料层数", "output", f"{level}/{total_tier}")
+ logging.info(f"更新右上角下料层数显示:{level}/{total_tier}")
+ except Exception as e:
+ logging.error(f"更新下料层数UI失败: {str(e)}")
@Slot(int)
def handle_unloading_position(self, position):
"""处理下料位置信息"""
- self.unloading_position_label.setText(f"下料位置:{position}")
-
+ # 通过信号在主线程中更新UI
+ self.unloading_position_ui_signal.emit(position)
+
+ @Slot(int)
+ def handle_unloading_position_ui(self, position):
+ """在主线程中更新下料位置UI"""
+ try:
+ self.unloading_position_label.setText(f"下料位置:{position}")
+ except Exception as e:
+ logging.error(f"更新下料位置UI失败: {str(e)}")
+
@Slot(int)
def handle_ng(self, ng):
"""处理NG信号, 将当前处理的数据添加到包装记录中,毛重和净重设为0"""
diff --git a/widgets/unloading_dialog_widget.py b/widgets/unloading_dialog_widget.py
index dad5a4d..8b45589 100644
--- a/widgets/unloading_dialog_widget.py
+++ b/widgets/unloading_dialog_widget.py
@@ -5,6 +5,7 @@ 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):
# 定义一个信号,用于向主窗口传递托盘号
@@ -114,9 +115,9 @@ class UnloadingDialog(UnloadingDialogUI):
else:
# API查询失败,保存基本信息到数据库
logging.info(f"API查询失败,保存基本信息到数据库")
- if not pallet_type or not tier:
- QMessageBox.warning(self, "提示", "请选择托盘类型和层数")
- return
+ # if not pallet_type or not tier:
+ # QMessageBox.warning(self, "提示", "请选择托盘类型和层数")
+ # return
pallet_info = {
"cc": pallet_type,
"cs": tier # 使用用户输入的层数
@@ -128,9 +129,9 @@ class UnloadingDialog(UnloadingDialogUI):
if not pallet_info:
# 数据库中没有记录,保存基本信息
logging.info(f"数据库中未找到记录,保存基本信息")
- if not pallet_type or not tier:
- QMessageBox.warning(self, "提示", "请选择托盘类型和层数")
- return
+ # if not pallet_type or not tier:
+ # QMessageBox.warning(self, "提示", "请选择托盘类型和层数")
+ # return
pallet_info = {
"cc": pallet_type,
"cs": tier # 使用用户输入的层数
@@ -213,4 +214,93 @@ class UnloadingDialog(UnloadingDialogUI):
return
# 其他键位事件交给父类处理
- super().keyPressEvent(event)
\ No newline at end of file
+ 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)}")
\ No newline at end of file