You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
11 KiB
Python

10 months ago
import qtawesome
from PyQt5 import QtGui
from PyQt5.QtCore import Qt, QVariant, QSize
from PyQt5.QtWidgets import QHBoxLayout, QWidget, QMessageBox, QComboBox
from model.ProjectModel.VarManage import *
from UI.VarManages.ModbusModel import *
from UI.VarManages.BaseButtonDelegate import BaseButtonDelegate
10 months ago
from utils import Globals
import re
class HartSimulateModel(VarTableModel):
def __init__(self, header, data: list, table = None):
'''
header : 表头变量
data : 表格内容
table : 缺省参数
'''
VarTableModel.__init__(self, header, data, table = table)
def initTable(self):
self.datas = []
7 months ago
10 months ago
varDatas = HartSimulateVarManage.getAllVar()
if not varDatas:
# self.layoutChanged.emit()
self.table.proxy.invalidate()
return
for x in varDatas:
7 months ago
for i in range(3, 9):
10 months ago
x.insert(i, '')
7 months ago
x.append('')
10 months ago
self.datas.append(x)
self.checkList = ['Unchecked'] * len(self.datas)
# self.layoutChanged.emit()
self.table.proxy.invalidate()
def data(self, QModelIndex, role=None):
# print(Qt.__dict__.items())
if role == Qt.TextAlignmentRole:
return Qt.AlignCenter
if not QModelIndex.isValid():
print("行或者列有问题")
return QVariant()
if role == Qt.BackgroundRole:
10 months ago
if QModelIndex.row() % 2 == 0 and self.datas[QModelIndex.row()][1] not in Globals.getValue('forceVars'):
return QtGui.QColor('#EFEFEF')
if self.datas[QModelIndex.row()][1] in Globals.getValue('forceVars'):
return QtGui.QColor('#00FF7F')
if role == Qt.TextColorRole:
return QtGui.QColor('#1A1A1A')
if role == Qt.CheckStateRole:
if QModelIndex.column() == 0:
return Qt.Checked if self.checkList[QModelIndex.row()] == 'Checked' else Qt.Unchecked
else:
return None
if role == Qt.ToolTipRole:
if QModelIndex.column() == 0:
return self.checkList[QModelIndex.row()]
if role == Qt.DisplayRole or role == Qt.EditRole:
if QModelIndex.row() in self.editableList:
return self.datas[QModelIndex.row()][QModelIndex.column()]
if role != Qt.DisplayRole:
return QVariant()
return QVariant(self.datas[QModelIndex.row()][QModelIndex.column()])
def flags(self, index):
if index.column() == 0:
return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable
if index.row() in self.editableList and index.column():
return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEditable
if index.column() in range(3, 9):
return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEditable
return Qt.ItemIsEnabled
class HartSimulateButtonDelegate(BaseButtonDelegate):
10 months ago
"""该类用于向单元格中添加按钮 任务表格"""
def __init__(self, parent=None):
super(HartSimulateButtonDelegate, self).__init__(parent)
def paint(self, painter, option, index):
# 首先绘制背景颜色,与其他委托保持一致
if index.data(Qt.BackgroundRole):
height = option.rect.height()
top = option.rect.top()
# 减少高度调整,保持更多的绘制区域
paint_rect = option.rect
paint_rect.setHeight(max(46, height - 4)) # 最小保持46px高度
paint_rect.moveTop(top + 2)
painter.fillRect(paint_rect, index.data(Qt.BackgroundRole))
# 然后创建按钮部件
10 months ago
if not self.parent().indexWidget(index):
button1 = QPushButton(
qtawesome.icon('fa.play', color='#1fbb6f'),
"",
self.parent(),
clicked=self.start_action
)
button1.setIconSize(QSize(15, 15))
button1.setToolTip("启动仿真")
10 months ago
button2 = QPushButton(
qtawesome.icon('fa.pencil', color='#4c8cf2'),
"",
self.parent(),
clicked=self.edit_action
)
button2.setToolTip("编辑变量")
10 months ago
button1.clicked.connect(self.start_action)
button2.clicked.connect(self.edit_action)
button2.oldName = False
button2.isEdit = True
button1.index = [index.row(), index.column()]
button2.index = [index.row(), index.column()]
data = self.parent().model.datas[index.row()]
for x in data[:-1]:
if x != '':
break
else:
button2.isEdit = False
button2.setIcon(qtawesome.icon('fa.save', color='#1fbb6f'))
button2.setToolTip("保存变量")
10 months ago
self.parent().model.editableList.append(button2.index[0])
10 months ago
h_box_layout = QHBoxLayout()
h_box_layout.addWidget(button1)
h_box_layout.addWidget(button2)
h_box_layout.setContentsMargins(2, 2, 2, 2)
10 months ago
h_box_layout.setAlignment(Qt.AlignCenter)
h_box_layout.setSpacing(3)
10 months ago
widget = QWidget()
widget.setLayout(h_box_layout)
# 设置widget的背景为透明让底层的背景颜色显示出来
widget.setStyleSheet("""
QWidget {
background-color: transparent;
}
QPushButton {
background-color: rgba(255, 255, 255, 180);
border: 1px solid #E5E7EB;
border-radius: 3px;
padding: 3px;
margin: 1px;
min-height: 20px;
max-height: 24px;
min-width: 24px;
max-width: 28px;
}
QPushButton:hover {
background-color: rgba(255, 255, 255, 255);
border-color: #2277EF;
}
""")
10 months ago
self.parent().setIndexWidget(
index,
widget
)
def edit_action(self):
sender = self.sender()
model = self.parent().model
# 使用基类的验证方法获取行索引
view_row, source_row = self._validate_button_indices(sender)
if view_row is None:
return
10 months ago
if sender.isEdit:
sender.setIcon(qtawesome.icon('fa.save', color='#1fbb6f'))
sender.isEdit = False
sender.oldName = model.datas[source_row][1]
model.editableList.append(source_row)
10 months ago
else:
varMes = model.datas[source_row]
10 months ago
name, des = str(varMes[1]), str(varMes[2])
# print(name, des)
if not name :
reply = QMessageBox.question(self.parent(),
'警告',
"有字段为空",
QMessageBox.Yes)
return
sender.isEdit = True
model.editableList.remove(source_row)
10 months ago
if sender.oldName:
HartSimulateVarManage.editVar(name = sender.oldName, Nname = name, des = des)
else:
HartSimulateVarManage.createVar(varName = name, des = des)
sender.setIcon(qtawesome.icon('fa.pencil', color='#4c8cf2'))
varMes = HartSimulateVarManage.getByName(name)
model.insert_data(varMes, source_row)
model.remove_row(source_row + 1)
10 months ago
def start_action(self):
sender = self.sender()
model = self.parent().model
# 使用基类的验证方法获取行索引
view_row, source_row = self._validate_button_indices(sender)
if view_row is None:
return
# 获取强制值(从视图)和其他数据(从源模型)
value1 = self._get_view_data(view_row, 3) # 强制值列
minSpan = model.datas[source_row][7]
maxSpan = model.datas[source_row][8]
writeList = [str(x) for x in model.datas[source_row][3:9]]
# print(writeList)
10 months ago
pattern = re.compile(r'[^0-9\.-]+')
if minSpan and maxSpan and value1 and not re.findall(pattern, str(value1) + str(minSpan) + str(maxSpan)):
if float(value1) < float(minSpan) or float(value1) > float(maxSpan):
reply = QMessageBox.question(self.parent(),
'警告',
"主变量超出量程",
QMessageBox.Yes)
return
for index, value in enumerate(writeList):
if re.findall(pattern, value):
print(value)
10 months ago
reply = QMessageBox.question(self.parent(),
'警告',
"请输入强制值或数字",
QMessageBox.Yes)
return
10 months ago
try:
# 使用HART RTU从站功能写入变量值
protocolManage = Globals.getValue('protocolManage')
print(protocolManage,protocolManage.hartRtuSlaveManager)
if not protocolManage or not protocolManage.hartRtuSlaveManager:
return
# 检查value是否为空或无效
if not value or str(value).strip() == '':
# print(f"HART变量{index}的值为空,跳过写入")
continue
try:
floatValue = float(value)
except (ValueError, TypeError):
print(f"HART变量{index}的值'{value}'无法转换为浮点数")
return
# 根据索引写入对应的变量
if index == 0: # 主变量
protocolManage.writeHartVariable('primaryVariable', floatValue)
# print(floatValue, 111)
elif index == 1: # 动态变量1
protocolManage.writeHartVariable('dynamicVariable1', floatValue)
elif index == 2: # 动态变量2
protocolManage.writeHartVariable('dynamicVariable2', floatValue)
elif index == 3: # 动态变量3
protocolManage.writeHartVariable('dynamicVariable3', floatValue)
# print('1111', floatValue)
except Exception as e:
print(f"写入HART变量失败: {e}")
10 months ago
forceVars = Globals.getValue('forceVars')
forceVars.add(model.datas[source_row][1])
10 months ago
Globals.setValue('forceVars', forceVars)