from PyQt5.QtCore import (QCoreApplication, Qt) from PyQt5.QtWidgets import (QComboBox, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QListView, QWidget, QMessageBox) from utils.DBModels.ProtocolModel import RTUSetting class CustomBox(QComboBox): def __init__(self): super(CustomBox, self).__init__() self.setCursor(Qt.PointingHandCursor) self.setView(QListView()) def showPopup(self): QComboBox.showPopup(self) pop = self.children()[1] pop.move(pop.x(), pop.y() + 51) class RTUSettingWidget(QWidget): def __init__(self, rtuType): super(RTUSettingWidget, self).__init__() self.rtuType = rtuType self.setObjectName("RTUSettingWidget") self.setupUI() def setupUI(self): # 主布局 - 垂直布局 main_layout = QVBoxLayout(self) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(7) # 第一行:端口号和波特率 row1_layout = QHBoxLayout() row1_layout.setSpacing(15) # 端口号列 port_column = QVBoxLayout() port_column.setSpacing(4) self.label = QLabel('端口号') self.label.setObjectName("setlabel") self.portEdit = QLineEdit() self.portEdit.setObjectName("setEdit") port_column.addWidget(self.label) port_column.addWidget(self.portEdit) # 波特率列 baud_column = QVBoxLayout() baud_column.setSpacing(4) self.label_5 = QLabel('波特率') self.label_5.setObjectName("setlabel") self.baudrateEdit = QLineEdit() self.baudrateEdit.setObjectName("setEdit") baud_column.addWidget(self.label_5) baud_column.addWidget(self.baudrateEdit) row1_layout.addLayout(port_column) row1_layout.addLayout(baud_column) main_layout.addLayout(row1_layout) # 第二行:字节长度和停止位 row2_layout = QHBoxLayout() row2_layout.setSpacing(15) # 字节长度列 byte_column = QVBoxLayout() byte_column.setSpacing(4) self.label_2 = QLabel('字节长度') self.label_2.setObjectName("setlabel") self.byteSizeBox = CustomBox() self.byteSizeBox.addItem("8") self.byteSizeBox.addItem("7") self.byteSizeBox.setObjectName("setBox") byte_column.addWidget(self.label_2) byte_column.addWidget(self.byteSizeBox) # 停止位列 stop_column = QVBoxLayout() stop_column.setSpacing(4) self.label_4 = QLabel('停止位') self.label_4.setObjectName("setlabel") self.stopbitsBox = CustomBox() self.stopbitsBox.addItem("1") self.stopbitsBox.addItem("2") self.stopbitsBox.setObjectName("setBox") stop_column.addWidget(self.label_4) stop_column.addWidget(self.stopbitsBox) row2_layout.addLayout(byte_column) row2_layout.addLayout(stop_column) main_layout.addLayout(row2_layout) # 第三行:奇偶校验(单独一行) parity_layout = QVBoxLayout() parity_layout.setSpacing(4) self.label_3 = QLabel('奇偶校验') self.label_3.setObjectName("setlabel") self.parityBox = CustomBox() self.parityBox.addItem("N 无") self.parityBox.addItem("O 奇") self.parityBox.addItem("E 偶") self.parityBox.setObjectName("setBox") parity_layout.addWidget(self.label_3) parity_layout.addWidget(self.parityBox) main_layout.addLayout(parity_layout) # 第四行:通信频率和起始值 row4_layout = QHBoxLayout() row4_layout.setSpacing(15) # 通信频率列 freq_column = QVBoxLayout() freq_column.setSpacing(4) self.label_6 = QLabel('通信频率') self.label_6.setObjectName("setlabel") self.freEdit = QLineEdit() self.freEdit.setObjectName("setEdit") freq_column.addWidget(self.label_6) freq_column.addWidget(self.freEdit) # 起始值列 offset_column = QVBoxLayout() offset_column.setSpacing(4) self.label_7 = QLabel('起始值') self.label_7.setObjectName('setlabel') self.offsetBox = CustomBox() self.offsetBox.addItem("1") self.offsetBox.addItem("0") self.offsetBox.setObjectName("setBox") offset_column.addWidget(self.label_7) offset_column.addWidget(self.offsetBox) row4_layout.addLayout(freq_column) row4_layout.addLayout(offset_column) main_layout.addLayout(row4_layout) # 保存按钮 self.saveButton = QPushButton('保存') if self.rtuType == 'master': self.saveButton.setObjectName('rtuSaveButton') else: self.saveButton.setObjectName('setButton') self.saveButton.clicked.connect(self.saveSetting) main_layout.addWidget(self.saveButton) # 添加弹性空间 main_layout.addStretch() def loadSettings(self): """加载设置数据""" try: if self.rtuType == 'master': query = RTUSetting.get_by_id(1) else: query = RTUSetting.get_by_id(2) port = str(query.port) byteSize = str(query.byteSize) baudrate = str(query.baudrate) stopbits = str(query.stopbits) parity = str(query.parity) frequency = str(query.frequency) offset = str(query.offset) self.portEdit.setText(port) self.byteSizeBox.setCurrentText(byteSize) self.baudrateEdit.setText(baudrate) self.stopbitsBox.setCurrentText(stopbits) self.freEdit.setText(frequency) self.offsetBox.setCurrentText(offset) self.parityBox.setCurrentText(parity) except Exception as e: print(f"加载RTU设置失败: {e}") # 设置默认值 self.portEdit.setText("COM1") self.byteSizeBox.setCurrentText("8") self.baudrateEdit.setText("9600") self.stopbitsBox.setCurrentText("1") self.freEdit.setText("1") self.offsetBox.setCurrentText("1") self.parityBox.setCurrentText("N 无") def saveSetting(self): """保存设置""" try: port = self.portEdit.text() byteSize = self.byteSizeBox.currentText() baudrate = self.baudrateEdit.text() stopbits = self.stopbitsBox.currentText() parity = self.parityBox.currentText() frequency = self.freEdit.text() offset = self.offsetBox.currentText() if self.rtuType == 'master': RTUSetting.update(port=port, byteSize=byteSize, baudrate=baudrate, stopbits=stopbits, parity=parity, frequency=frequency, offset=offset).where(RTUSetting.tcpType == 'master').execute() else: RTUSetting.update(port=port, byteSize=byteSize, baudrate=baudrate, stopbits=stopbits, parity=parity, frequency=frequency, offset=offset).where(RTUSetting.tcpType == 'slave').execute() # 创建消息框 QMessageBox.information(self, '保存成功', f'RTU{self.rtuType}站配置已保存!') except Exception as e: QMessageBox.critical(self, '保存失败', f'保存RTU设置时发生错误:{str(e)}')