|
|
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
HART设备配置界面模块
|
|
|
|
|
|
实现HART设备参数配置功能,包括查询和修改仪表基本信息、标签描述及出厂日期、装配号等
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
|
import time
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGroupBox,
|
|
|
|
|
|
QLabel, QLineEdit, QPushButton, QGridLayout,
|
|
|
|
|
|
QTabWidget, QMessageBox, QDateEdit, QSpinBox)
|
|
|
|
|
|
from PyQt5.QtCore import Qt, pyqtSignal, QDate
|
|
|
|
|
|
from PyQt5.QtGui import QFont
|
|
|
|
|
|
from protocol.HART import tools
|
|
|
|
|
|
|
|
|
|
|
|
class HartDeviceConfigWidget(QWidget):
|
|
|
|
|
|
"""
|
|
|
|
|
|
HART设备配置界面类
|
|
|
|
|
|
实现HART设备参数配置功能,包括查询和修改仪表基本信息、标签描述及出厂日期、装配号等
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
初始化设备配置界面
|
|
|
|
|
|
"""
|
|
|
|
|
|
super().__init__()
|
|
|
|
|
|
|
|
|
|
|
|
# 初始化HART通信对象
|
|
|
|
|
|
self.hartComm = None
|
|
|
|
|
|
self.connectionWidget = None
|
|
|
|
|
|
|
|
|
|
|
|
# 初始化界面
|
|
|
|
|
|
self.initUI()
|
|
|
|
|
|
|
|
|
|
|
|
def initUI(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
初始化用户界面
|
|
|
|
|
|
"""
|
|
|
|
|
|
# 创建主布局
|
|
|
|
|
|
self.mainLayout = QVBoxLayout(self)
|
|
|
|
|
|
self.mainLayout.setContentsMargins(10, 10, 10, 10)
|
|
|
|
|
|
|
|
|
|
|
|
# --- 1. 仪表基本信息区域 ---
|
|
|
|
|
|
infoGroup = QGroupBox("仪表基本信息")
|
|
|
|
|
|
infoLayout = QGridLayout(infoGroup)
|
|
|
|
|
|
|
|
|
|
|
|
self.messageLabel = QLabel("设备消息:")
|
|
|
|
|
|
self.messageEdit = QLineEdit()
|
|
|
|
|
|
self.messageEdit.setMaxLength(32)
|
|
|
|
|
|
infoLayout.addWidget(self.messageLabel, 0, 0)
|
|
|
|
|
|
infoLayout.addWidget(self.messageEdit, 0, 1)
|
|
|
|
|
|
|
|
|
|
|
|
self.queryBasicInfoBtn = QPushButton("查询信息")
|
|
|
|
|
|
self.updateBasicInfoBtn = QPushButton("更新信息")
|
|
|
|
|
|
infoButtonLayout = QHBoxLayout()
|
|
|
|
|
|
infoButtonLayout.addWidget(self.queryBasicInfoBtn)
|
|
|
|
|
|
infoButtonLayout.addWidget(self.updateBasicInfoBtn)
|
|
|
|
|
|
|
|
|
|
|
|
self.mainLayout.addWidget(infoGroup)
|
|
|
|
|
|
self.mainLayout.addLayout(infoButtonLayout)
|
|
|
|
|
|
|
|
|
|
|
|
# --- 2. 仪表标签与描述区域 ---
|
|
|
|
|
|
tagGroup = QGroupBox("仪表标签与描述")
|
|
|
|
|
|
tagLayout = QGridLayout(tagGroup)
|
|
|
|
|
|
|
|
|
|
|
|
self.tagLabel = QLabel("设备标签:")
|
|
|
|
|
|
self.tagEdit = QLineEdit()
|
|
|
|
|
|
self.tagEdit.setMaxLength(8)
|
|
|
|
|
|
tagLayout.addWidget(self.tagLabel, 0, 0)
|
|
|
|
|
|
tagLayout.addWidget(self.tagEdit, 0, 1)
|
|
|
|
|
|
|
|
|
|
|
|
self.descLabel = QLabel("设备描述:")
|
|
|
|
|
|
self.descEdit = QLineEdit()
|
|
|
|
|
|
self.descEdit.setMaxLength(16)
|
|
|
|
|
|
tagLayout.addWidget(self.descLabel, 1, 0)
|
|
|
|
|
|
tagLayout.addWidget(self.descEdit, 1, 1)
|
|
|
|
|
|
|
|
|
|
|
|
self.dateLabel = QLabel("出厂日期:")
|
|
|
|
|
|
self.dateEdit = QDateEdit()
|
|
|
|
|
|
self.dateEdit.setDisplayFormat("dd/MM/yyyy")
|
|
|
|
|
|
self.dateEdit.setCalendarPopup(True)
|
|
|
|
|
|
self.dateEdit.setDate(QDate.currentDate())
|
|
|
|
|
|
tagLayout.addWidget(self.dateLabel, 2, 0)
|
|
|
|
|
|
tagLayout.addWidget(self.dateEdit, 2, 1)
|
|
|
|
|
|
|
|
|
|
|
|
self.queryTagDescBtn = QPushButton("查询信息")
|
|
|
|
|
|
self.updateTagDescBtn = QPushButton("更新信息")
|
|
|
|
|
|
tagButtonLayout = QHBoxLayout()
|
|
|
|
|
|
tagButtonLayout.addWidget(self.queryTagDescBtn)
|
|
|
|
|
|
tagButtonLayout.addWidget(self.updateTagDescBtn)
|
|
|
|
|
|
|
|
|
|
|
|
self.mainLayout.addWidget(tagGroup)
|
|
|
|
|
|
self.mainLayout.addLayout(tagButtonLayout)
|
|
|
|
|
|
|
|
|
|
|
|
# --- 3. 仪表装配号区域 ---
|
|
|
|
|
|
assemblyGroup = QGroupBox("仪表装配号")
|
|
|
|
|
|
assemblyLayout = QGridLayout(assemblyGroup)
|
|
|
|
|
|
|
|
|
|
|
|
self.assemblyLabel = QLabel("装配号:")
|
|
|
|
|
|
self.assemblyEdit = QSpinBox()
|
|
|
|
|
|
self.assemblyEdit.setRange(0, 16777215)
|
|
|
|
|
|
self.assemblyEdit.setButtonSymbols(QSpinBox.NoButtons)
|
|
|
|
|
|
assemblyLayout.addWidget(self.assemblyLabel, 0, 0)
|
|
|
|
|
|
assemblyLayout.addWidget(self.assemblyEdit, 0, 1)
|
|
|
|
|
|
|
|
|
|
|
|
self.queryAssemblyBtn = QPushButton("查询装配号")
|
|
|
|
|
|
self.updateAssemblyBtn = QPushButton("更新装配号")
|
|
|
|
|
|
assemblyButtonLayout = QHBoxLayout()
|
|
|
|
|
|
assemblyButtonLayout.addWidget(self.queryAssemblyBtn)
|
|
|
|
|
|
assemblyButtonLayout.addWidget(self.updateAssemblyBtn)
|
|
|
|
|
|
|
|
|
|
|
|
self.mainLayout.addWidget(assemblyGroup)
|
|
|
|
|
|
self.mainLayout.addLayout(assemblyButtonLayout)
|
|
|
|
|
|
|
|
|
|
|
|
# --- 4. 轮询地址修改区域 ---
|
|
|
|
|
|
pollingGroup = QGroupBox("轮询地址修改 (仅短帧)")
|
|
|
|
|
|
pollingLayout = QGridLayout(pollingGroup)
|
|
|
|
|
|
|
|
|
|
|
|
self.pollingAddressLabel = QLabel("新轮询地址:")
|
|
|
|
|
|
self.pollingAddressSpinBox = QSpinBox()
|
|
|
|
|
|
self.pollingAddressSpinBox.setRange(0, 63)
|
|
|
|
|
|
pollingLayout.addWidget(self.pollingAddressLabel, 0, 0)
|
|
|
|
|
|
pollingLayout.addWidget(self.pollingAddressSpinBox, 0, 1)
|
|
|
|
|
|
|
|
|
|
|
|
self.updatePollingAddressBtn = QPushButton("更新轮询地址")
|
|
|
|
|
|
pollingButtonLayout = QHBoxLayout()
|
|
|
|
|
|
pollingButtonLayout.addWidget(self.updatePollingAddressBtn)
|
|
|
|
|
|
|
|
|
|
|
|
self.mainLayout.addWidget(pollingGroup)
|
|
|
|
|
|
self.mainLayout.addLayout(pollingButtonLayout)
|
|
|
|
|
|
|
|
|
|
|
|
self.mainLayout.addStretch(1)
|
|
|
|
|
|
|
|
|
|
|
|
# --- 连接所有信号和槽 ---
|
|
|
|
|
|
self.queryBasicInfoBtn.clicked.connect(self.queryBasicInfo)
|
|
|
|
|
|
self.updateBasicInfoBtn.clicked.connect(self.updateBasicInfo)
|
|
|
|
|
|
self.queryTagDescBtn.clicked.connect(self.queryTagDesc)
|
|
|
|
|
|
self.updateTagDescBtn.clicked.connect(self.updateTagDesc)
|
|
|
|
|
|
self.queryAssemblyBtn.clicked.connect(self.queryAssembly)
|
|
|
|
|
|
self.updateAssemblyBtn.clicked.connect(self.updateAssembly)
|
|
|
|
|
|
self.updatePollingAddressBtn.clicked.connect(self.updatePollingAddress)
|
|
|
|
|
|
|
|
|
|
|
|
def setHartComm(self, hartComm):
|
|
|
|
|
|
"""
|
|
|
|
|
|
设置HART通信对象
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
hartComm: HART通信对象
|
|
|
|
|
|
"""
|
|
|
|
|
|
self.hartComm = hartComm
|
|
|
|
|
|
|
|
|
|
|
|
def setConnectionWidget(self, widget):
|
|
|
|
|
|
"""设置连接窗口的引用"""
|
|
|
|
|
|
self.connectionWidget = widget
|
|
|
|
|
|
|
|
|
|
|
|
def queryBasicInfo(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
查询仪表基本信息 - command 12
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.hartComm or not self.hartComm.isConnected():
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "设备未连接,请先连接设备")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 发送查询命令
|
|
|
|
|
|
result = self.hartComm.readMessage()
|
|
|
|
|
|
# print(result)
|
|
|
|
|
|
# 处理响应数据
|
|
|
|
|
|
if result:
|
|
|
|
|
|
# 兼容处理:如果result是列表,则取第一个元素
|
|
|
|
|
|
msg = result[0] if isinstance(result, list) and len(result) > 0 else result
|
|
|
|
|
|
|
|
|
|
|
|
if isinstance(msg, dict):
|
|
|
|
|
|
message_data = msg.get('message')
|
|
|
|
|
|
if isinstance(message_data, bytes):
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 使用新的 unpack_packed_ascii 函数
|
|
|
|
|
|
message_str = tools.unpack_packed_ascii(message_data, 32)
|
|
|
|
|
|
self.messageEdit.setText(message_str.strip())
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
# 如果解码失败,显示原始数据的十六进制表示和错误
|
|
|
|
|
|
message_hex = message_data.hex()
|
|
|
|
|
|
self.messageEdit.setText(f"HEX: {message_hex}")
|
|
|
|
|
|
QMessageBox.critical(self, "解码错误", f"解码消息失败: {e}")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "未能获取设备基本信息")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
QMessageBox.critical(self, "错误", f"查询设备基本信息失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
def updateBasicInfo(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
修改仪表基本信息 - command 17
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.hartComm or not self.hartComm.isConnected():
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "设备未连接,请先连接设备")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 获取消息内容
|
|
|
|
|
|
message_text = self.messageEdit.text()
|
|
|
|
|
|
|
|
|
|
|
|
# 直接将字符串传递给通信函数,由底层负责打包
|
|
|
|
|
|
result = self.hartComm.writeMessage(message_text)
|
|
|
|
|
|
|
|
|
|
|
|
# 处理响应数据
|
|
|
|
|
|
if result and len(result) > 0:
|
|
|
|
|
|
QMessageBox.information(self, "成功", "成功更新设备基本信息")
|
|
|
|
|
|
else:
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "未能更新设备基本信息")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
QMessageBox.critical(self, "错误", f"更新设备基本信息失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
def queryTagDesc(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
查询仪表标签、描述及出厂日期 - command 13
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.hartComm or not self.hartComm.isConnected():
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "设备未连接,请先连接设备")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 发送查询命令
|
|
|
|
|
|
result = self.hartComm.readTagDescriptorDate()
|
|
|
|
|
|
|
|
|
|
|
|
# 处理响应数据
|
|
|
|
|
|
if result:
|
|
|
|
|
|
# 兼容处理:如果result是列表,则取第一个元素
|
|
|
|
|
|
msg = result[0] if isinstance(result, list) and len(result) > 0 else result
|
|
|
|
|
|
|
|
|
|
|
|
if isinstance(msg, dict) and msg.get("status") == "success":
|
|
|
|
|
|
tag_str = msg.get("device_tag_name", "")
|
|
|
|
|
|
desc_str = msg.get("device_descriptor", "")
|
|
|
|
|
|
date_dict = msg.get("date", {})
|
|
|
|
|
|
|
|
|
|
|
|
self.tagEdit.setText(tag_str.strip())
|
|
|
|
|
|
self.descEdit.setText(desc_str.strip())
|
|
|
|
|
|
|
|
|
|
|
|
if isinstance(date_dict, dict) and all(k in date_dict for k in ['day', 'month', 'year']):
|
|
|
|
|
|
day = date_dict.get('day', 1)
|
|
|
|
|
|
month = date_dict.get('month', 1)
|
|
|
|
|
|
year = date_dict.get('year', 1900)
|
|
|
|
|
|
self.dateEdit.setDate(QDate(year, month, day))
|
|
|
|
|
|
|
|
|
|
|
|
QMessageBox.information(self, "成功", "成功读取设备标签、描述及日期信息")
|
|
|
|
|
|
return
|
|
|
|
|
|
elif isinstance(msg, dict) and 'error' in msg:
|
|
|
|
|
|
QMessageBox.warning(self, "查询失败", f"未能获取设备标签、描述及日期信息: {msg.get('error')}")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "未能获取设备标签、描述及日期信息")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
QMessageBox.critical(self, "错误", f"查询设备标签、描述及日期信息失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
def updateTagDesc(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
修改仪表标签、描述及出厂日期 - command 18
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.hartComm or not self.hartComm.isConnected():
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "设备未连接,请先连接设备")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 获取标签和描述
|
|
|
|
|
|
tag_text = self.tagEdit.text()
|
|
|
|
|
|
descriptor_text = self.descEdit.text()
|
|
|
|
|
|
|
|
|
|
|
|
date = self.dateEdit.date()
|
|
|
|
|
|
# According to the spec, year should be (actual_year - 1900)
|
|
|
|
|
|
year_for_protocol = date.year() - 1900
|
|
|
|
|
|
if not (0 <= year_for_protocol <= 255):
|
|
|
|
|
|
QMessageBox.warning(self, "年份错误", "年份必须在1900年至2155年之间")
|
|
|
|
|
|
return
|
|
|
|
|
|
date_tuple = (date.day(), date.month(), year_for_protocol)
|
|
|
|
|
|
|
|
|
|
|
|
# 直接将字符串传递给通信函数,由底层负责打包
|
|
|
|
|
|
result = self.hartComm.writeTagDescriptorDate(tag_text, descriptor_text, date_tuple)
|
|
|
|
|
|
|
|
|
|
|
|
# 处理响应数据
|
|
|
|
|
|
if result and len(result) > 0:
|
|
|
|
|
|
QMessageBox.information(self, "成功", "成功更新设备标签、描述及日期信息")
|
|
|
|
|
|
else:
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "未能更新设备标签、描述及日期信息")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
QMessageBox.critical(self, "错误", f"更新设备标签、描述及日期信息失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
def queryAssembly(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
查询仪表装配号 - command 16
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.hartComm or not self.hartComm.isConnected():
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "设备未连接,请先连接设备")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 发送查询命令
|
|
|
|
|
|
result = self.hartComm.readFinalAssemblyNumber()
|
|
|
|
|
|
|
|
|
|
|
|
# 处理响应数据
|
|
|
|
|
|
if result:
|
|
|
|
|
|
# 兼容处理:如果result是列表,则取第一个元素
|
|
|
|
|
|
msg = result[0] if isinstance(result, list) and len(result) > 0 else result
|
|
|
|
|
|
|
|
|
|
|
|
if isinstance(msg, dict) and msg.get("status") == "success":
|
|
|
|
|
|
assembly_no = msg.get("final_assembly_no", 0)
|
|
|
|
|
|
self.assemblyEdit.setValue(assembly_no)
|
|
|
|
|
|
QMessageBox.information(self, "成功", f"成功读取设备装配号: {assembly_no}")
|
|
|
|
|
|
return
|
|
|
|
|
|
elif isinstance(msg, dict) and 'error' in msg:
|
|
|
|
|
|
QMessageBox.warning(self, "查询失败", f"未能获取设备装配号: {msg.get('error')}")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "未能获取设备装配号")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
QMessageBox.critical(self, "错误", f"查询设备装配号失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
def updateAssembly(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
修改仪表装配号 - command 19
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.hartComm or not self.hartComm.isConnected():
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "设备未连接,请先连接设备")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 获取装配号
|
|
|
|
|
|
assembly_number = self.assemblyEdit.value()
|
|
|
|
|
|
|
|
|
|
|
|
# 发送更新命令
|
|
|
|
|
|
result = self.hartComm.writeFinalAssemblyNumber(assembly_number)
|
|
|
|
|
|
|
|
|
|
|
|
# 处理响应数据
|
|
|
|
|
|
if result and len(result) > 0:
|
|
|
|
|
|
QMessageBox.information(self, "成功", "成功更新设备装配号")
|
|
|
|
|
|
else:
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "未能更新设备装配号")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
QMessageBox.critical(self, "错误", f"更新设备装配号失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
def updatePollingAddress(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
修改设备轮询地址 - command 6
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.hartComm or not self.hartComm.isConnected():
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "设备未连接,请先连接设备")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
new_address = self.pollingAddressSpinBox.value()
|
|
|
|
|
|
current_address_bytes = self.hartComm.getCurrentAddress()
|
|
|
|
|
|
if current_address_bytes and len(current_address_bytes) == 1:
|
|
|
|
|
|
current_address = current_address_bytes[0] & 0x3F
|
|
|
|
|
|
if new_address == current_address:
|
|
|
|
|
|
QMessageBox.information(self, "提示", "新地址与当前地址相同,无需修改。")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
reply = QMessageBox.question(self, '确认修改',
|
|
|
|
|
|
f"确定要将设备的轮询地址修改为 {new_address} 吗?\n"
|
|
|
|
|
|
"修改成功后将使用新地址自动重新连接。",
|
|
|
|
|
|
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
|
|
|
|
|
|
|
|
|
|
|
if reply == QMessageBox.Yes:
|
|
|
|
|
|
result = self.hartComm.write_polling_address(new_address)
|
|
|
|
|
|
if result:
|
|
|
|
|
|
QMessageBox.information(self, "成功", f"成功将轮询地址修改为 {new_address}。\n现在将使用新地址重新连接。")
|
|
|
|
|
|
if self.connectionWidget:
|
|
|
|
|
|
self.connectionWidget.disconnectDevice(silent=True)
|
|
|
|
|
|
self.connectionWidget.pollingAddressSpinBox.setValue(new_address)
|
|
|
|
|
|
self.connectionWidget.connectDevice()
|
|
|
|
|
|
else:
|
|
|
|
|
|
QMessageBox.warning(self, "警告", "未能更新轮询地址。")
|
|
|
|
|
|
|
|
|
|
|
|
except ValueError as ve:
|
|
|
|
|
|
QMessageBox.critical(self, "地址错误", f"轮询地址设置错误: {str(ve)}")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
QMessageBox.critical(self, "错误", f"更新轮询地址失败: {str(e)}")
|