diff --git a/db/jtDB.db b/db/jtDB.db
index 4433962..388d6a8 100644
Binary files a/db/jtDB.db and b/db/jtDB.db differ
diff --git a/from pymodbus.py b/from pymodbus.py
index 73bf610..ddfea1b 100644
--- a/from pymodbus.py
+++ b/from pymodbus.py
@@ -2,7 +2,7 @@ from pymodbus.client import ModbusTcpClient
import time
client = ModbusTcpClient('localhost', port=5020)
client.connect()
-client.write_registers(address=11, values=[21962])
+client.write_registers(address=11, values=[9562])
# client.write_registers(address=3, values=[0])
# time.sleep(2)
# client.write_registers(address=0, values=[0])
diff --git a/widgets/main_window.py b/widgets/main_window.py
index f97a925..e05d8ad 100644
--- a/widgets/main_window.py
+++ b/widgets/main_window.py
@@ -59,6 +59,12 @@ class MainWindow(MainWindowUI):
emergency_stop_signal = Signal(int, str) # 用于在主线程中处理急停信号
diameter_warning_signal = Signal(float, str, str) # 参数:final_value, bccd, tccd
+ # 新增的线径警告弹框信号 - 参数:值, 最小值, 最大值
+ diameter_alert_signal = Signal(float, float, float)
+
+ # 新增的重量警告弹框信号 - 参数:值, 最小值, 最大值
+ weight_alert_signal = Signal(float, float, float)
+
def __init__(self, user_id=None, user_name=None, corp_name=None, corp_id=None):
"""初始化主窗口"""
super().__init__(user_id)
@@ -335,6 +341,12 @@ class MainWindow(MainWindowUI):
if hasattr(self, 'luno_query_button'):
self.luno_query_button.clicked.connect(self.handle_luno_query)
+ # 连接新的线径警告弹框信号
+ self.diameter_alert_signal.connect(self.show_diameter_alert)
+
+ # 连接重量警告弹框信号
+ self.weight_alert_signal.connect(self.show_weight_alert)
+
def update_inspection_columns(self):
"""更新检验列配置 - 使用检验配置管理器获取启用的列数和标题"""
try:
@@ -866,17 +878,7 @@ class MainWindow(MainWindowUI):
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):
"""相机状态处理的空方法,保留是为了兼容性"""
pass
@@ -2437,48 +2439,23 @@ class MainWindow(MainWindowUI):
# 检查称重值是否在范围内
if net_weight_kg < min_weight or net_weight_kg > max_weight:
# 写入寄存器D10 给值 2 表示重量超出范围
- modbus = ModbusUtils()
- client = modbus.get_client()
- modbus.write_register_until_success(client, 10, 2)
- modbus.close_client(client)
- # 显示自动关闭的警告提示框
- self.warning_msg = QMessageBox(self)
- self.warning_msg.setIcon(QMessageBox.Warning)
- self.warning_msg.setWindowTitle('重量超出范围')
- self.warning_msg.setText(f"称重值 {net_weight_kg:.2f}kg 不在轴重要求范围内 ({min_weight:.1f} - {max_weight:.1f}kg)")
- self.warning_msg.setStandardButtons(QMessageBox.Ok) # 添加确定按钮
- self.warning_msg.setModal(False) # 确保非模态
- self.warning_msg.setWindowFlags(self.warning_msg.windowFlags() | Qt.WindowStaysOnTopHint) # 置顶显示
+ try:
+ modbus = ModbusUtils()
+ client = modbus.get_client()
+ modbus.write_register_until_success(client, 10, 2)
+ modbus.close_client(client)
+ except Exception as e:
+ logging.error(f"写入Modbus寄存器失败: {str(e)}")
- # 连接按钮点击信号
- self.warning_msg.buttonClicked.connect(lambda btn: self.warning_msg.close())
-
- # 使用 show 而非 exec_ 保持非阻塞
- self.warning_msg.show()
-
- # 强制关闭方法1:使用多种定时器策略
- def force_close_weight_warning():
- try:
- if hasattr(self, 'warning_msg') and self.warning_msg:
- if self.warning_msg.isVisible():
- self.warning_msg.close()
- self.warning_msg.deleteLater()
- logging.debug("重量警告弹框已强制关闭")
- else:
- logging.debug("重量警告弹框已不可见,跳过关闭")
- except Exception as e:
- logging.warning(f"强制关闭重量警告弹框时出错: {str(e)}")
- finally:
- # 清理引用
- if hasattr(self, 'warning_msg'):
- delattr(self, 'warning_msg')
-
- # 使用多个定时器确保关闭
- QTimer.singleShot(5000, force_close_weight_warning) # 5秒后关闭
- QTimer.singleShot(6000, force_close_weight_warning) # 6秒后再次尝试
+ # 使用信号触发弹框显示 - 避免主线程阻塞
+ logging.warning(f"称重值 {net_weight_kg:.2f}kg 超出轴重要求范围 ({min_weight:.1f} - {max_weight:.1f}kg),发送信号显示警告")
+ try:
+ self.weight_alert_signal.emit(net_weight_kg, min_weight, max_weight)
+ except Exception as e:
+ logging.error(f"发送重量警告信号失败: {str(e)}", exc_info=True)
# 阻止继续执行,等待用户处理
- logging.warning(f"称重值 {weight_kg:.3f}kg 超出轴重要求范围,已阻止保存,等待用户处理")
+ logging.warning(f"称重值 {weight_kg:.3f}kg 超出轴重要求范围,已阻止保存")
return
else:
logging.info(f"称重值 {weight_kg:.3f}kg 在轴重要求范围内 ({min_weight:.1f} - {max_weight:.1f}kg)")
@@ -3030,8 +3007,6 @@ class MainWindow(MainWindowUI):
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")
# 上料任务完成,恢复上料按钮样式
self.restore_input_button_style()
logging.info("上料任务完成,恢复上料按钮样式")
@@ -3551,52 +3526,20 @@ class MainWindow(MainWindowUI):
# 检查线径值是否在范围内
if final_value < min_diameter or final_value > max_diameter:
- # 写入寄存器D10 给值 3 表示线径超出范围
- modbus = ModbusUtils()
- modbus_client = modbus.get_client()
- modbus.write_register_until_success(modbus_client, 10, 3)
-
- # 显示自动关闭的警告提示框
- self.diameter_warning_msg = QMessageBox(self)
- self.diameter_warning_msg.setIcon(QMessageBox.Warning)
- self.diameter_warning_msg.setWindowTitle('线径超出范围')
- self.diameter_warning_msg.setText(f"线径值 {final_value:.3f}mm 不在线径公差范围内 ({min_diameter:.3f} - {max_diameter:.3f}mm)")
- self.diameter_warning_msg.setStandardButtons(QMessageBox.Ok) # 添加确定按钮
- self.diameter_warning_msg.setModal(False) # 确保非模态
- self.diameter_warning_msg.setWindowFlags(self.diameter_warning_msg.windowFlags() | Qt.WindowStaysOnTopHint) # 置顶显示
-
- # 连接按钮点击信号
- self.diameter_warning_msg.buttonClicked.connect(lambda btn: self.diameter_warning_msg.close())
- # 使用 show 而非 exec_ 保持非阻塞
- self.diameter_warning_msg.show()
- # 强制关闭方法:使用多种定时器策略
- def force_close_diameter_warning():
- try:
- if hasattr(self, 'diameter_warning_msg') and self.diameter_warning_msg:
- if self.diameter_warning_msg.isVisible():
- self.diameter_warning_msg.close()
- self.diameter_warning_msg.deleteLater()
- logging.debug("线径警告弹框已强制关闭")
- else:
- logging.debug("线径警告弹框已不可见,跳过关闭")
- except Exception as e:
- logging.warning(f"强制关闭线径警告弹框时出错: {str(e)}")
- finally:
- # 清理引用
- if hasattr(self, 'diameter_warning_msg'):
- delattr(self, 'diameter_warning_msg')
-
- # 使用多个定时器确保关闭
- QTimer.singleShot(2000, force_close_diameter_warning) # 2秒后关闭
- QTimer.singleShot(3000, force_close_diameter_warning) # 3秒后再次尝试
+ # 使用信号触发弹框显示 - 避免主线程阻塞
+ logging.warning(f"线径值 {final_value:.3f}mm 超出线径公差范围 ({min_diameter:.3f} - {max_diameter:.3f}mm),发送信号显示警告")
+ try:
+ self.diameter_alert_signal.emit(final_value, min_diameter, max_diameter)
+ except Exception as e:
+ logging.error(f"发送线径警告信号失败: {str(e)}", exc_info=True)
# 重置测量列表,防止重复触发
self._diameter_measurements = []
# 阻止继续执行,等待用户处理
- logging.warning(f"线径值 {final_value:.3f}mm 超出线径公差范围,已阻止保存,等待用户处理")
+ logging.warning(f"线径值 {final_value:.3f}mm 超出线径公差范围,已阻止保存")
return
else:
logging.info(f"线径值 {final_value:.3f}mm 在线径公差范围内 ({min_diameter:.3f} - {max_diameter:.3f}mm)")
@@ -3678,56 +3621,11 @@ class MainWindow(MainWindowUI):
@Slot(float, str, str)
def show_diameter_warning(self, final_value, bccd, tccd):
- """显示线径超出范围警告(在主线程中执行)"""
- try:
- # 显示自动关闭的警告提示框
- self.diameter_warning_msg = QMessageBox(self)
- self.diameter_warning_msg.setIcon(QMessageBox.Warning)
- self.diameter_warning_msg.setWindowTitle('线径超出范围')
- self.diameter_warning_msg.setText(f"线径 {final_value:.3f} 不在公差范围内 ({bccd} - {tccd})")
- self.diameter_warning_msg.setStandardButtons(QMessageBox.Ok) # 添加确定按钮
- self.diameter_warning_msg.setModal(False) # 确保非模态
- self.diameter_warning_msg.setWindowFlags(self.diameter_warning_msg.windowFlags() | Qt.WindowStaysOnTopHint) # 置顶显示
-
- # 连接按钮点击信号
- self.diameter_warning_msg.buttonClicked.connect(lambda btn: self.diameter_warning_msg.close())
-
- # 显示提示框(非模态)
- self.diameter_warning_msg.show()
-
- # Windows平台强制关闭方法
- def force_close_diameter_warning():
- try:
- if hasattr(self, 'diameter_warning_msg') and self.diameter_warning_msg:
- if self.diameter_warning_msg.isVisible():
- # 方法1:正常关闭
- self.diameter_warning_msg.close()
- # 方法2:强制删除
- self.diameter_warning_msg.deleteLater()
- # 方法3:隐藏窗口
- self.diameter_warning_msg.hide()
- # 方法4:设置为不可见
- self.diameter_warning_msg.setVisible(False)
- logging.debug("线径警告弹框已强制关闭")
- else:
- logging.debug("线径警告弹框已不可见,跳过关闭")
- except Exception as e:
- logging.warning(f"强制关闭线径警告弹框时出错: {str(e)}")
- finally:
- # 清理引用
- try:
- if hasattr(self, 'diameter_warning_msg'):
- delattr(self, 'diameter_warning_msg')
- except:
- pass
-
- # 使用多个定时器确保关闭(Windows平台优化)
- QTimer.singleShot(2000, force_close_diameter_warning) # 1秒后关闭
- QTimer.singleShot(3000, force_close_diameter_warning) # 2秒后最后尝试
-
- logging.info(f"线径警告弹框已显示,将在1-3秒后自动关闭")
- except Exception as e:
- logging.error(f"显示线径警告弹框时出错: {str(e)}")
+ """显示线径超出范围警告(在主线程中执行)- 为避免冲突,此方法已弃用,仅保留接口"""
+ # 这个方法已经被新的线径处理逻辑取代,为避免冲突,此处不再显示弹框
+ # 仅记录日志,保持接口兼容性
+ logging.info(f"线径警告信号已接收,但弹框显示已被新逻辑取代: 线径值 {final_value:.3f}mm, 范围 {bccd} - {tccd}")
+ return
def on_scanner_data_received(self, port_name, data):
"""扫码器数据接收回调函数
@@ -5111,6 +5009,154 @@ class MainWindow(MainWindowUI):
logging.warning(f"线径数据处理超时,强制释放锁。处理时间: {processing_time:.2f}秒")
self._processing_diameter_lock = False
+ @Slot(float, float, float)
+ def show_diameter_alert(self, value, min_value, max_value):
+ """显示线径超出范围警告 - 通过信号触发,使用exec_强制显示"""
+ try:
+ # 使用更强制的方式显示警告对话框
+ from PySide6.QtWidgets import QApplication
+
+ # 记录当前时间,用于跟踪弹框显示时间
+ start_time = time.time()
+ logging.info(f"开始创建线径警告弹框,时间: {start_time}")
+
+ # 创建一个模态对话框 - 使用exec_方式显示
+ msg = QMessageBox()
+ msg.setIcon(QMessageBox.Critical) # 使用Critical图标更明显
+ msg.setWindowTitle('警告:线径超出范围!')
+ msg.setText(f"线径值 {value:.3f}mm 超出范围!
允许范围: {min_value:.3f} - {max_value:.3f}mm")
+ msg.setStandardButtons(QMessageBox.Ok)
+
+ # 设置样式,使其更显眼
+ msg.setStyleSheet("""
+ QMessageBox {
+ background-color: #ffeeee;
+ border: 3px solid #ff0000;
+ font-size: 14px;
+ }
+ QLabel {
+ color: #ff0000;
+ font-size: 16px;
+ font-weight: bold;
+ min-width: 250px;
+ min-height: 80px;
+ }
+ QPushButton {
+ background-color: #ff6666;
+ color: white;
+ font-weight: bold;
+ min-width: 80px;
+ min-height: 30px;
+ }
+ """)
+
+ # 确保对话框显示在所有窗口之上
+ msg.setWindowFlags(Qt.WindowStaysOnTopHint)
+
+ # 强制处理事件,确保UI更新
+ QApplication.processEvents()
+
+ # 使用定时器在2秒后自动点击确定按钮
+ def auto_close():
+ try:
+ # 查找确定按钮并点击
+ for button in msg.buttons():
+ if msg.buttonRole(button) == QMessageBox.AcceptRole:
+ button.click()
+ logging.info(f"已自动点击确定按钮,弹框显示时长: {time.time() - start_time:.2f}秒")
+ return
+ # 如果没有找到确定按钮,直接关闭
+ msg.done(QMessageBox.Ok)
+ logging.info(f"已自动关闭弹框,弹框显示时长: {time.time() - start_time:.2f}秒")
+ except Exception as e:
+ logging.error(f"自动关闭弹框失败: {str(e)}")
+
+ # 设置自动关闭定时器
+ QTimer.singleShot(2000, auto_close)
+
+ # 显示弹框并阻塞直到用户关闭或自动关闭
+ logging.info(f"即将显示线径警告弹框...")
+ msg.exec_() # 使用exec_而不是show,确保弹框显示
+
+ # 记录日志
+ logging.info(f"线径警告弹框已关闭,总显示时长: {time.time() - start_time:.2f}秒")
+ except Exception as e:
+ logging.error(f"显示线径警告弹框失败: {str(e)}", exc_info=True)
+
+ @Slot(float, float, float)
+ def show_weight_alert(self, value, min_value, max_value):
+ """显示重量超出范围警告 - 通过信号触发,使用exec_强制显示"""
+ try:
+ # 使用更强制的方式显示警告对话框
+ from PySide6.QtWidgets import QApplication
+
+ # 记录当前时间,用于跟踪弹框显示时间
+ start_time = time.time()
+ logging.info(f"开始创建重量警告弹框,时间: {start_time}")
+
+ # 创建一个模态对话框 - 使用exec_方式显示
+ msg = QMessageBox()
+ msg.setIcon(QMessageBox.Critical) # 使用Critical图标更明显
+ msg.setWindowTitle('警告:重量超出范围!')
+ msg.setText(f"称重值 {value:.2f}kg 超出范围!
允许范围: {min_value:.1f} - {max_value:.1f}kg")
+ msg.setStandardButtons(QMessageBox.Ok)
+
+ # 设置样式,使其更显眼
+ msg.setStyleSheet("""
+ QMessageBox {
+ background-color: #ffeeee;
+ border: 3px solid #ff0000;
+ font-size: 14px;
+ }
+ QLabel {
+ color: #ff0000;
+ font-size: 16px;
+ font-weight: bold;
+ min-width: 250px;
+ min-height: 80px;
+ }
+ QPushButton {
+ background-color: #ff6666;
+ color: white;
+ font-weight: bold;
+ min-width: 80px;
+ min-height: 30px;
+ }
+ """)
+
+ # 确保对话框显示在所有窗口之上
+ msg.setWindowFlags(Qt.WindowStaysOnTopHint)
+
+ # 强制处理事件,确保UI更新
+ QApplication.processEvents()
+
+ # 使用定时器在2秒后自动点击确定按钮
+ def auto_close():
+ try:
+ # 查找确定按钮并点击
+ for button in msg.buttons():
+ if msg.buttonRole(button) == QMessageBox.AcceptRole:
+ button.click()
+ logging.info(f"已自动点击确定按钮,弹框显示时长: {time.time() - start_time:.2f}秒")
+ return
+ # 如果没有找到确定按钮,直接关闭
+ msg.done(QMessageBox.Ok)
+ logging.info(f"已自动关闭弹框,弹框显示时长: {time.time() - start_time:.2f}秒")
+ except Exception as e:
+ logging.error(f"自动关闭弹框失败: {str(e)}")
+
+ # 设置自动关闭定时器
+ QTimer.singleShot(2000, auto_close)
+
+ # 显示弹框并阻塞直到用户关闭或自动关闭
+ logging.info(f"即将显示重量警告弹框...")
+ msg.exec_() # 使用exec_而不是show,确保弹框显示
+
+ # 记录日志
+ logging.info(f"重量警告弹框已关闭,总显示时长: {time.time() - start_time:.2f}秒")
+ except Exception as e:
+ logging.error(f"显示重量警告弹框失败: {str(e)}", exc_info=True)
+
def safe_str(val):