From 3dcca3632c993f43d1eb5b37f6b1b19eb9797472 Mon Sep 17 00:00:00 2001 From: "ZHANGXUXU\\95193" <951937200@qq.com> Date: Sun, 10 Aug 2025 17:57:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=89=B9=E9=87=8F=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=80=BC=E7=B1=BB=E5=9E=8B=E6=8C=89=E9=92=AE=E5=8F=8A?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UI/VarManages/ModbusModel.py | 48 +++++++------ UI/VarManages/VarWidget.py | 126 +++++++++++++++++++++++++++++++++-- 2 files changed, 148 insertions(+), 26 deletions(-) diff --git a/UI/VarManages/ModbusModel.py b/UI/VarManages/ModbusModel.py index 012e369..3d16852 100644 --- a/UI/VarManages/ModbusModel.py +++ b/UI/VarManages/ModbusModel.py @@ -63,7 +63,8 @@ class VarTableModel(QAbstractTableModel): self.checkList = ['Unchecked'] * len(self.datas) # self.layoutChanged.emit() self.table.proxy.invalidate() - # self.refreshComboBox() + # self.refreshComboBox(10) + def append_data(self, x): @@ -177,34 +178,38 @@ class VarTableModel(QAbstractTableModel): self.datas[sourceRow], self.datas[destinationChild] = self.datas[destinationChild], self.datas[sourceRow] self.table.proxy.invalidate() - def refreshComboBox(self): + def refreshComboBox(self, comboBoxColumn): #功能类型的index是5,通讯类型index是10 for i in range(len(self.datas)): - cbRow = str('cb' + str(i) + str(5)) - index = self.index(i, int(5)) + cbRow = str('cb' + str(i) + str(comboBoxColumn)) + index = self.index(i, int(comboBoxColumn)) delegate = self.table.itemDelegate(index) - # 不需要调用paint方法,因为委托会在需要时自动创建控件 - # 直接尝试获取已存在的comboBox - try: - comboBox = getattr(delegate, cbRow, None) + # 方法1:尝试通过indexWidget获取已存在的comboBox + widget = self.table.indexWidget(index) + if widget is not None: + # 从容器widget中获取comboBox + comboBox = widget.findChild(QComboBox) + else: + # 方法2:尝试通过getattr获取委托中的comboBox + try: + comboBox = getattr(delegate, cbRow, None) + except AttributeError: + # 如果属性不存在,跳过这一行 + continue + if comboBox is None: # 如果comboBox不存在,跳过这一行 continue - # 检查comboBox对象是否仍然有效,避免RuntimeError - if not comboBox or comboBox.isHidden(): - continue - # print(comboBox, i, num, cbRow) - except Exception as e: + + # 检查comboBox对象是否仍然有效,避免RuntimeError + if not comboBox or comboBox.isHidden(): continue - - if self.datas[i][5] in [0, 1]: - comboBox.setCurrentIndex(self.datas[i][5]) - elif self.datas[i][5] in [3, 4]: - comboBox.setCurrentIndex(self.datas[i][5] - 1) - else: - comboBox.setCurrentIndex(-1) + + + # 根据数据类型设置comboBox的值 + comboBox.setCurrentText(str(self.datas[i][comboBoxColumn])) @@ -601,8 +606,7 @@ class ModbusVarModelBox(QItemDelegate): comBox = str('cb' + str(index.row()) + str(index.column())) setattr(self, comBox, QComboBox()) comboBox = getattr(self, comBox) - comboBox = QComboBox(self.parent()) - items = ['本地值', '模拟值'] + items = ['本地值', '模拟值', '远程值'] comboBox.addItems(items) comboBox.setCurrentText(str(self.parent().model.datas[index.row()][index.column()])) diff --git a/UI/VarManages/VarWidget.py b/UI/VarManages/VarWidget.py index dad8ef5..481a18c 100644 --- a/UI/VarManages/VarWidget.py +++ b/UI/VarManages/VarWidget.py @@ -1,14 +1,15 @@ from PyQt5 import QtCore, QtWidgets from PyQt5.QtCore import QSize, Qt, QTimer from PyQt5.QtGui import QIcon -from PyQt5.QtWidgets import QSplitter, QPushButton, QFileDialog, QMessageBox +from PyQt5.QtWidgets import QSplitter, QPushButton, QFileDialog, QMessageBox, QDialog import qtawesome as qta from UI.VarManages.VarTable import VarTableView, HartTableView, TcRtdTableView, AnalogTableView, \ HartSimulateTableView from UI.VarManages.MessageWidget import MessageWidget -from model.ProjectModel.VarManage import ModbusVarManage +from model.ProjectModel.VarManage import ModbusVarManage, TcRtdManage, AnalogManage, HartVarManage, HartSimulateVarManage +from UI.VarManages.SwitchVarModelWidget import SwitchVarModelDialog from utils import Globals # 移除 Celery 相关导入,现在使用 ProtocolManage 和 ModbusManager from protocol.TCP.TemToMv import temToMv @@ -128,6 +129,12 @@ class VarWidgets(QtWidgets.QWidget): self.forceBtn.setIconSize(QSize(18, 18)) self.forceBtn.clicked.connect(self.forceVar) self.setupButtonIcon(self.forceBtn, 'fa5s.play', '#F59E0B') + + self.varModelSwitchBtn = QPushButton('值类型切换') + self.varModelSwitchBtn.setObjectName('forceBtn') + self.varModelSwitchBtn.setIconSize(QSize(18, 18)) + self.varModelSwitchBtn.clicked.connect(self.switchVarModel) + self.setupButtonIcon(self.varModelSwitchBtn, 'fa5s.play', '#F59E0B') # 清除颜色按钮 self.clearBtn = QPushButton('清除颜色') @@ -172,6 +179,7 @@ class VarWidgets(QtWidgets.QWidget): self.gridLayout.addWidget(self.startProtocolBtn, 0, 3, 1, 1) self.gridLayout.addWidget(QSplitter(), 0, 4, 1, 20) self.gridLayout.addWidget(self.clearBtn, 0, 4, 1, 1) + self.gridLayout.addWidget(self.varModelSwitchBtn, 0, 5, 1, 1) # self.gridLayout.addWidget(self.importBtn, 0, 24, 1, 1) # self.gridLayout.addWidget(self.exportBtn, 0, 25, 1, 1) @@ -183,8 +191,104 @@ class VarWidgets(QtWidgets.QWidget): # self.comboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged) self.horizontalHeader = self.varView.horizontalHeader() self.horizontalHeader.sectionClicked.connect(self.on_view_horizontalHeader_sectionClicked) - + + def switchVarModel(self): + # 切换变量值类型 + check = [i for i, x in enumerate(self.varView.model.checkList) if x == 'Checked'] + if not check: + QMessageBox.information(self.parent(), '提示', '请先勾选要切换的变量', QMessageBox.Yes) + return False + + dialog = SwitchVarModelDialog() + if dialog.exec_() == QDialog.Accepted: + selectedType = dialog.getSelectedType() + else: + return False + successCount = 0 + failedVars = [] + + for i in check: + varName = self.varView.model.datas[i][3] # 变量名在第3列 + try: + # 根据不同的变量类型调用相应的数据库更新方法 + if hasattr(self.varView.model, 'modbusType') and self.varView.model.modbusType: + # Modbus 变量 + ModbusVarManage.editVarModel(varName, selectedType, self.varView.model.modbusType) + else: + # 根据表格类型判断变量类型 + if isinstance(self.varView.model, __import__('UI.VarManages.TCRTDModel', fromlist=['TcRtdModel']).TcRtdModel): + TcRtdManage.editVarModel(varName, selectedType) + elif isinstance(self.varView.model, __import__('UI.VarManages.AnalogModel', fromlist=['AnalogModel']).AnalogModel): + AnalogManage.editVarModel(varName, selectedType) + elif isinstance(self.varView.model, __import__('UI.VarManages.HartModel', fromlist=['HartModel']).HartModel): + HartVarManage.editVarModel(varName, selectedType) + elif isinstance(self.varView.model, __import__('UI.VarManages.HartSimulateModel', fromlist=['HartSimulateModel']).HartSimulateModel): + HartSimulateVarManage.editVarModel(varName, selectedType) + else: + # 默认使用 Modbus 变量管理 + ModbusVarManage.editVarModel(varName, selectedType, 'ModbusTcpMaster') + + # 更新表格数据 - 根据变量类型确定正确的列索引 + if hasattr(self.varView.model, 'modbusType') and self.varView.model.modbusType: + # Modbus 变量 - 第10列 + self.varView.model.datas[i][10] = selectedType + elif isinstance(self.varView.model, __import__('UI.VarManages.TCRTDModel', fromlist=['TcRtdModel']).TcRtdModel): + # TcRtd 变量 - 第11列 + self.varView.model.datas[i][11] = selectedType + elif isinstance(self.varView.model, __import__('UI.VarManages.AnalogModel', fromlist=['AnalogModel']).AnalogModel): + # Analog 变量 - 第10列 + self.varView.model.datas[i][10] = selectedType + elif isinstance(self.varView.model, __import__('UI.VarManages.HartModel', fromlist=['HartModel']).HartModel): + # Hart 变量 - 第8列 + self.varView.model.datas[i][8] = selectedType + elif isinstance(self.varView.model, __import__('UI.VarManages.HartSimulateModel', fromlist=['HartSimulateModel']).HartSimulateModel): + # HartSimulate 变量 - 第9列 + self.varView.model.datas[i][9] = selectedType + else: + # 默认使用第10列 + self.varView.model.datas[i][10] = selectedType + successCount += 1 + + + + except Exception as e: + failedVars.append(varName) + print(f"更新变量 {varName} 失败: {str(e)}") + # 立即更新界面显示 + + + # 刷新comboBox显示 - 根据变量类型确定正确的列索引 + if hasattr(self.varView.model, 'modbusType') and self.varView.model.modbusType: + # Modbus 变量 - 第10列 + self.varView.model.refreshComboBox(10) + elif isinstance(self.varView.model, __import__('UI.VarManages.TCRTDModel', fromlist=['TcRtdModel']).TcRtdModel): + # TcRtd 变量 - 第11列 + self.varView.model.refreshComboBox(11) + elif isinstance(self.varView.model, __import__('UI.VarManages.AnalogModel', fromlist=['AnalogModel']).AnalogModel): + # Analog 变量 - 第10列 + self.varView.model.refreshComboBox(10) + elif isinstance(self.varView.model, __import__('UI.VarManages.HartModel', fromlist=['HartModel']).HartModel): + # Hart 变量 - 第8列 + self.varView.model.refreshComboBox(8) + elif isinstance(self.varView.model, __import__('UI.VarManages.HartSimulateModel', fromlist=['HartSimulateModel']).HartSimulateModel): + # HartSimulate 变量 - 第9列 + self.varView.model.refreshComboBox(9) + else: + # 默认使用第10列 + self.varView.model.refreshComboBox(10) + + + # 显示结果 + if failedVars: + QMessageBox.warning(self.parent(), '警告', + f'成功更新 {successCount} 个变量,失败 {len(failedVars)} 个变量:\n{", ".join(failedVars)}', + QMessageBox.Yes) + else: + QMessageBox.information(self.parent(), '提示', f'已成功将 {successCount} 个变量切换为:{selectedType}', QMessageBox.Yes) + + + def clearColour(self): Globals.clearValue('forceVars') @@ -503,6 +607,12 @@ class TcRtdWidgets(VarWidgets): self.clearBtn.clicked.connect(self.clearColour) self.setupButtonIcon(self.clearBtn, 'fa5s.eraser', '#DC2626') + self.varModelSwitchBtn = QPushButton('值类型切换') + self.varModelSwitchBtn.setObjectName('forceBtn') + self.varModelSwitchBtn.setIconSize(QSize(18, 18)) + self.varModelSwitchBtn.clicked.connect(self.switchVarModel) + self.setupButtonIcon(self.varModelSwitchBtn, 'fa5s.play', '#F59E0B') + self.varView = TcRtdTableView() self.varView.setObjectName('varView') self.proxy = QtCore.QSortFilterProxyModel(self) @@ -523,7 +633,7 @@ class TcRtdWidgets(VarWidgets): self.gridLayout.addWidget(self.forceBtn, 0, 0, 1, 1) # self.gridLayout.addWidget(self.startProtocolBtn, 0, 1, 1, 1) self.gridLayout.addWidget(self.clearBtn, 0, 1, 1, 1) - + self.gridLayout.addWidget(self.varModelSwitchBtn, 0, 2, 1, 1) self.gridLayout.addWidget(self.varView, 1, 0, 10, 26) self.gridLayout.setSpacing(20) self.gridLayout.setContentsMargins(20, 30, 20, 20) @@ -534,6 +644,7 @@ class TcRtdWidgets(VarWidgets): self.horizontalHeader = self.varView.horizontalHeader() self.horizontalHeader.sectionClicked.connect(self.on_view_horizontalHeader_sectionClicked) + def createVar(self): self.varView.model.append_data(['', '', '', '', '', '', '', '', '','']) @@ -596,6 +707,12 @@ class AnalogWidgets(VarWidgets): self.clearBtn.clicked.connect(self.clearColour) self.setupButtonIcon(self.clearBtn, 'fa5s.eraser', '#DC2626') + self.varModelSwitchBtn = QPushButton('值类型切换') + self.varModelSwitchBtn.setObjectName('forceBtn') + self.varModelSwitchBtn.setIconSize(QSize(18, 18)) + self.varModelSwitchBtn.clicked.connect(self.switchVarModel) + self.setupButtonIcon(self.varModelSwitchBtn, 'fa5s.play', '#F59E0B') + self.varView = AnalogTableView() self.varView.setObjectName('varView') self.proxy = QtCore.QSortFilterProxyModel(self) @@ -616,6 +733,7 @@ class AnalogWidgets(VarWidgets): self.gridLayout.addWidget(self.forceBtn, 0, 0, 1, 1) # self.gridLayout.addWidget(self.startProtocolBtn, 0, 1, 1, 1) self.gridLayout.addWidget(self.clearBtn, 0, 1, 1, 1) + self.gridLayout.addWidget(self.varModelSwitchBtn, 0, 2, 1, 1) self.gridLayout.addWidget(self.varView, 1, 0, 10, 26) self.gridLayout.setSpacing(20)