feat: 更新SDK初始化逻辑,添加异常处理以增强稳定性;在设置界面中新增Modbus配置功能,包含主机地址和端口输入框及连接测试按钮;优化Modbus工具类以支持动态主机和端口配置;增强设置窗口信号连接功能以处理设置变更。

This commit is contained in:
zhu-mengmeng 2025-06-26 10:44:15 +08:00
parent 99bca76e08
commit 77c6f9f480
5 changed files with 250 additions and 22 deletions

View File

@ -47,9 +47,13 @@ class MvCamera():
# ch:初始化SDK | en: Initialize SDK
@staticmethod
def MV_CC_Initialize():
MvCamCtrldll.MV_CC_Initialize.restype = c_int
# C原型int __stdcall MV_CC_Initialize();
return MvCamCtrldll.MV_CC_Initialize()
try:
MvCamCtrldll.MV_CC_Initialize.restype = c_int
# C原型int __stdcall MV_CC_Initialize();
return MvCamCtrldll.MV_CC_Initialize()
except Exception as e:
print(f"初始化SDK失败: {e}")
return -1
# ch:反初始化SDK | en: Finalize SDK
@staticmethod

View File

@ -3,7 +3,7 @@ from PySide6.QtWidgets import (
QTabWidget, QFrame, QFormLayout, QGroupBox, QRadioButton, QSpacerItem, QSizePolicy,
QTableWidget, QTableWidgetItem, QHeaderView, QSlider, QCheckBox, QButtonGroup
)
from PySide6.QtGui import QFont, QBrush, QColor
from PySide6.QtGui import QFont, QBrush, QColor, QIntValidator
from PySide6.QtCore import Qt, Signal, QSize
class SettingsUI(QWidget):
@ -354,11 +354,71 @@ class SettingsUI(QWidget):
self.plc_layout = QVBoxLayout(self.plc_tab)
self.plc_layout.setContentsMargins(20, 20, 20, 20)
# 占位标签
self.plc_placeholder = QLabel("PLC设置待实现")
self.plc_placeholder.setFont(self.normal_font)
self.plc_placeholder.setAlignment(Qt.AlignCenter)
self.plc_layout.addWidget(self.plc_placeholder)
# 创建Modbus配置组
self.modbus_group = QGroupBox("Modbus 配置")
self.modbus_group.setFont(self.normal_font)
self.modbus_layout = QFormLayout(self.modbus_group)
self.modbus_layout.setContentsMargins(15, 20, 15, 15)
self.modbus_layout.setSpacing(15)
# 主机地址输入框
self.modbus_host_input = QLineEdit()
self.modbus_host_input.setFont(self.normal_font)
self.modbus_host_input.setPlaceholderText("请输入Modbus主机地址")
self.modbus_layout.addRow(QLabel("主机地址:"), self.modbus_host_input)
# 端口输入框
self.modbus_port_input = QLineEdit()
self.modbus_port_input.setFont(self.normal_font)
self.modbus_port_input.setPlaceholderText("请输入Modbus端口")
self.modbus_port_input.setValidator(QIntValidator(1, 65535))
self.modbus_layout.addRow(QLabel("端口:"), self.modbus_port_input)
# 测试连接按钮
self.modbus_test_button = QPushButton("测试连接")
self.modbus_test_button.setFont(self.normal_font)
self.modbus_test_button.setStyleSheet("""
QPushButton {
background-color: #2196f3;
color: white;
border: none;
border-radius: 3px;
padding: 5px 15px;
}
QPushButton:hover {
background-color: #1e88e5;
}
""")
self.modbus_layout.addRow("", self.modbus_test_button)
# 添加Modbus配置组到布局
self.plc_layout.addWidget(self.modbus_group)
# 添加保存按钮
self.plc_save_button = QPushButton("保存配置")
self.plc_save_button.setFont(self.normal_font)
self.plc_save_button.setFixedSize(120, 40)
self.plc_save_button.setStyleSheet("""
QPushButton {
background-color: #4caf50;
color: white;
border: none;
border-radius: 5px;
}
QPushButton:hover {
background-color: #45a049;
}
QPushButton:pressed {
background-color: #3d8b40;
}
""")
# 添加按钮布局
button_layout = QHBoxLayout()
button_layout.addStretch(1)
button_layout.addWidget(self.plc_save_button)
self.plc_layout.addLayout(button_layout)
self.plc_layout.addStretch(1)
self.tab_widget.addTab(self.plc_tab, "PLC设置")

View File

@ -12,11 +12,11 @@ log.setLevel(logging.WARNING)
class ModbusUtils:
def __init__(self) -> None:
def __init__(self, host=None, port=None) -> None:
# 初始化 modbus 配置
config = ConfigLoader.get_instance()
self.MODBUS_HOST = config.get_value("modbus.host")
self.MODBUS_PORT = config.get_value("modbus.port")
self.MODBUS_HOST = host if host is not None else config.get_value("modbus.host")
self.MODBUS_PORT = port if port is not None else int(config.get_value("modbus.port"))
def get_client(self):
# 创建Modbus TCP客户端实例指定服务器的IP地址和端口号
@ -35,7 +35,6 @@ class ModbusUtils:
return None # Or raise an exception
return client
def close_client(self, client):
# 关闭客户端连接
if client:

View File

@ -0,0 +1,141 @@
import logging
import json
import os
from PySide6.QtWidgets import QWidget, QMessageBox
from PySide6.QtCore import Signal
from utils.config_loader import ConfigLoader
class PLCSettingsWidget(QWidget):
"""PLC设置控制器"""
# 定义信号
settings_changed = Signal() # 设置变更信号
def __init__(self, parent=None):
"""初始化控制器
Args:
parent: 父窗口
"""
super().__init__(parent)
self.parent = parent
self.config = ConfigLoader.get_instance()
# 获取UI控件引用
self.modbus_host_input = parent.modbus_host_input
self.modbus_port_input = parent.modbus_port_input
self.modbus_test_button = parent.modbus_test_button
self.plc_save_button = parent.plc_save_button
# 连接信号和槽
self.connect_signals()
# 加载配置
self.load_config()
def connect_signals(self):
"""连接信号和槽"""
self.modbus_test_button.clicked.connect(self.test_modbus_connection)
self.plc_save_button.clicked.connect(self.save_config)
def load_config(self):
"""加载配置"""
try:
# 加载Modbus配置
host = self.config.get_value("modbus.host")
port = self.config.get_value("modbus.port")
self.modbus_host_input.setText(host if host else "localhost")
self.modbus_port_input.setText(str(port) if port else "502")
logging.info("已加载PLC配置")
except Exception as e:
logging.error(f"加载PLC配置失败: {str(e)}")
QMessageBox.critical(self, "错误", f"加载PLC配置失败: {str(e)}")
def save_config(self):
"""保存配置"""
try:
# 获取输入值
host = self.modbus_host_input.text().strip()
port = self.modbus_port_input.text().strip()
# 验证输入
if not host:
QMessageBox.warning(self, "警告", "请输入Modbus主机地址")
return
if not port:
QMessageBox.warning(self, "警告", "请输入Modbus端口")
return
try:
port_int = int(port)
if port_int < 1 or port_int > 65535:
QMessageBox.warning(self, "警告", "端口号必须在1-65535之间")
return
except ValueError:
QMessageBox.warning(self, "警告", "端口号必须是整数")
return
# 更新配置
self.config.set_value("modbus.host", host)
self.config.set_value("modbus.port", port)
self.config.save_config()
# 发送信号
self.settings_changed.emit()
# 提示成功
QMessageBox.information(self, "成功", "PLC配置已保存")
logging.info(f"已保存PLC配置: host={host}, port={port}")
except Exception as e:
logging.error(f"保存PLC配置失败: {str(e)}")
QMessageBox.critical(self, "错误", f"保存PLC配置失败: {str(e)}")
def test_modbus_connection(self):
"""测试Modbus连接"""
try:
# 获取输入值
host = self.modbus_host_input.text().strip()
port = self.modbus_port_input.text().strip()
# 验证输入
if not host:
QMessageBox.warning(self, "警告", "请输入Modbus主机地址")
return
if not port:
QMessageBox.warning(self, "警告", "请输入Modbus端口")
return
try:
port_int = int(port)
except ValueError:
QMessageBox.warning(self, "警告", "端口号必须是整数")
return
# 导入ModbusUtils
from utils.modbus_utils import ModbusUtils
# 创建Modbus连接
modbus = ModbusUtils(host=host, port=port_int)
client = modbus.get_client()
if client:
QMessageBox.information(self, "成功", f"Modbus连接成功: {host}:{port}")
logging.info(f"Modbus连接测试成功: {host}:{port}")
else:
QMessageBox.warning(self, "警告", f"Modbus连接失败: {host}:{port}")
logging.warning(f"Modbus连接测试失败: {host}:{port}")
# 关闭连接
modbus.close_client(client)
except Exception as e:
logging.error(f"测试Modbus连接失败: {str(e)}")
QMessageBox.critical(self, "错误", f"测试Modbus连接失败: {str(e)}")
def on_settings_changed(self):
"""设置变更处理"""
# 重新加载配置
self.load_config()

View File

@ -1,5 +1,5 @@
from PySide6.QtWidgets import QMessageBox, QVBoxLayout
from PySide6.QtCore import Qt
from PySide6.QtCore import Qt, Signal
import logging
import json
import os
@ -7,19 +7,29 @@ from ui.settings_ui import SettingsUI
from utils.sql_utils import SQLUtils
from widgets.inspection_settings_widget import InspectionSettingsWidget
from widgets.pallet_type_settings_widget import PalletTypeSettingsWidget
from widgets.plc_settings_widget import PLCSettingsWidget
from utils.config_loader import ConfigLoader
from utils.app_mode import AppMode
from widgets.camera_settings_widget import CameraSettingsWidget
from widgets.serial_settings_widget import SerialSettingsWidget
class SettingsWidget(SettingsUI):
# 定义信号
settings_changed = Signal()
def __init__(self, parent=None):
"""初始化设置窗口"""
super().__init__(parent)
self.parent = parent
logging.info("正在初始化SettingsWidget")
# 创建检验设置部件
logging.info("创建InspectionSettingsWidget实例")
self.inspection_settings = InspectionSettingsWidget()
# 创建子设置控制器
self.camera_settings = CameraSettingsWidget(self)
self.serial_settings = SerialSettingsWidget(self)
self.inspection_settings = InspectionSettingsWidget(self)
self.pallet_type_settings = PalletTypeSettingsWidget(self)
self.plc_settings = PLCSettingsWidget(self)
# 移除临时占位符标签并添加检验设置部件
if hasattr(self, 'inspection_placeholder'):
@ -60,7 +70,7 @@ class SettingsWidget(SettingsUI):
# 加载配置文件
self.config_loader = ConfigLoader.get_instance()
# 连接信号和槽
# 连接信号
self.connect_signals()
# 初始化数据库类型UI状态
@ -72,6 +82,14 @@ class SettingsWidget(SettingsUI):
logging.info("SettingsWidget初始化完成")
def connect_signals(self):
"""连接信号和槽"""
# 连接子设置控制器的信号
self.camera_settings.settings_changed.connect(self.on_settings_changed)
self.serial_settings.settings_changed.connect(self.on_settings_changed)
self.inspection_settings.settings_changed.connect(self.on_settings_changed)
self.pallet_type_settings.settings_changed.connect(self.on_settings_changed)
self.plc_settings.settings_changed.connect(self.on_settings_changed)
# 数据库类型选择
self.db_type_combo.currentTextChanged.connect(self.update_db_ui_state)
@ -354,3 +372,9 @@ class SettingsWidget(SettingsUI):
"""返回主页"""
if self.parent and hasattr(self.parent, 'show_main_page'):
self.parent.show_main_page()
def on_settings_changed(self):
"""处理设置变更信号"""
logging.info("设置已变更发送settings_changed信号")
# 发送信号
self.settings_changed.emit()