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.

264 lines
11 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import re
import qtawesome
from PyQt5 import QtGui
from PyQt5.QtCore import Qt, QVariant, QTimer
from PyQt5.QtWidgets import QMessageBox
# from websocket import send
from protocol.TCP.Analog import getRealAO
from model.ProjectModel.VarManage import *
from UI.VarManages.ModbusModel import *
from UI.VarManages.TCRTDModel import *
from utils import Globals
class AnalogModel(VarTableModel):
def __init__(self, header, data: list, table = None):
'''
header : 表头变量
data : 表格内容
table : 缺省参数
'''
VarTableModel.__init__(self, header, data, table = table)
# 修改为驼峰命名
self.valueCache = {}
self.cacheTimer = QTimer()
self.cacheTimer.timeout.connect(self.refreshValueCache)
self.cacheTimer.start(300) # 每秒刷新一次缓存
# 方法名改为驼峰命名
def refreshValueCache(self):
"""刷新所有变量的值缓存"""
for row in self.datas:
varName = row[3]
try:
self.valueCache[varName] = Globals.getValue('protocolManage').readVariableValue(varName)
except:
self.valueCache[varName] = None
def initTable(self):
self.datas = []
proType = Globals.getValue('currentProType')
# if proType in ['6']:
varDatas = AnalogManage.getAllVar()
if not varDatas:
# self.layoutChanged.emit()
self.table.proxy.invalidate()
return
for x in varDatas:
# x.insert(1, '')
x.insert(2, '')
self.datas.append(x)
x.append('')
self.checkList = ['Unchecked'] * len(self.datas)
# self.layoutChanged.emit()
self.table.proxy.invalidate()
# 初始化后立即刷新缓存
self.refreshValueCache()
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:
# if QModelIndex.row() % 2 == 0 and self.datas[QModelIndex.row()][3] not in Globals.getValue('forceVars'):
# return QtGui.QColor('#EFEFEF')
if self.datas[QModelIndex.row()][3] in Globals.getValue('forceVars'):
# print(111111)
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()
# # 获取变量值并插入表格
if QModelIndex.column() == 2:
varName = self.datas[QModelIndex.row()][3]
# 使用修改后的缓存变量名
return self.valueCache.get(varName, None)
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() or index.column() == 1:
if index.column() == 6 or index.column() == 4:
return Qt.ItemIsEnabled
return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEditable
return Qt.ItemIsEnabled
class AnalogButtonDelegate(TcRtdButtonDelegate):
"""该类用于向单元格中添加按钮 任务表格"""
def __init__(self, parent=None):
super(AnalogButtonDelegate, self).__init__(parent)
self.trendWindows = {} # 保存所有打开的趋势窗口
def trend_action(self):
sender = self.sender()
model = self.parent().model
# 使用基类的验证方法获取行索引
view_row, source_row = self._validate_button_indices(sender)
if view_row is None:
return
varName = model.datas[source_row][3]
# 以变量名为key避免重复打开
if varName not in self.trendWindows or self.trendWindows[varName] is None:
self.trendWindows[varName] = ActualTrend(varName=varName)
self.trendWindows[varName].show()
self.trendWindows[varName].raise_()
self.trendWindows[varName].activateWindow()
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
if sender.isEdit:
sender.setIcon(qtawesome.icon('fa.save', color='#1fbb6f'))
sender.isEdit = False
sender.oldName = model.datas[source_row][3]
model.editableList.append(source_row)
else:
varMes = model.datas[source_row]
name,channelNumber, des, varType, min, max, unit = str(varMes[3]), str(varMes[4]), str(varMes[5]),str(varMes[6]), str(varMes[7]), str(varMes[8]), str(varMes[9])
if not name or not varType:
reply = QMessageBox.question(self.parent(),
'警告',
"有字段为空",
QMessageBox.Yes)
return
sender.isEdit = True
model.editableList.remove(source_row)
if sender.oldName:
if sender.oldName == name:
AnalogManage.editVar(name=sender.oldName, Nname=name, channelNumber = channelNumber,
des=des, varType=varType, min=min, max=max, unit=unit)
else:
if GlobalVarManager.isVarNameExist(name):
QMessageBox.information(self.parent(), '提示', '已有同名变量')
return
else:
AnalogManage.editVar(name=sender.oldName, Nname=name, channelNumber = channelNumber,
des=des, varType=varType, min=min, max=max, unit=unit)
else:
if GlobalVarManager.isVarNameExist(name):
QMessageBox.information(self.parent(), '提示', '已有同名变量')
return
else:
AnalogManage.editVar(name=sender.oldName, Nname=name, channelNumber = channelNumber,
des=des, varType=varType, min=min, max=max, unit=unit)
sender.setIcon(qtawesome.icon('fa.pencil', color='#4c8cf2'))
varMes = AnalogManage.getByName(name)
varMes.insert(1, '')
varMes.insert(2, '')
varMes.append('')
model.insert_data(varMes, source_row)
model.remove_row(source_row + 1)
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
# 获取强制值(从视图)和其他数据(从源模型)
value = self._get_view_data(view_row, 1) # 强制值列
varType = model.datas[source_row][6]
min = model.datas[source_row][7]
max = model.datas[source_row][8]
# print(model.datas[source_row][9])
pattern = re.compile(r'[^0-9\.-]+')
if varType in ['AI', 'DI'] and model.datas[source_row][9] != '模拟值':
reply = QMessageBox.question(self.parent(),
'警告',
"AI,DI类型变量不允许强制值",
QMessageBox.Yes)
return
if varType in ['DO'] and int(value) not in [0, 1]:
reply = QMessageBox.question(self.parent(),
'警告',
"DO类型变量强制值只能为0或1",
QMessageBox.Yes)
return
if not value or re.findall(pattern, str(value)):
reply = QMessageBox.question(self.parent(),
'警告',
"请输入强制值或数字",
QMessageBox.Yes)
return
if source_row > 15:
if not value.isdigit:
reply = QMessageBox.question(self.parent(),
'警告',
"请输入0或1",
QMessageBox.Yes)
return
if min and max and source_row < 16:
if float(value) < float(min) or float(value) > float(max):
reply = QMessageBox.question(self.parent(),
'警告',
"超出量程范围",
QMessageBox.Yes)
return
else:
min = None
max = None
# print(value, source_row)
if (float(value) > 20 or float(value)) < 4 and source_row < 8:
reply = QMessageBox.question(self.parent(),
'警告',
"超出量程范围1",
QMessageBox.Yes)
return
if float(value) > 10000 or float(value) < 0.1 and 8 < source_row < 16:
reply = QMessageBox.question(self.parent(),
'警告',
"超出量程范围2",
QMessageBox.Yes)
return
# if source_row < 8:
# model.table.realList[source_row] = getRealAO(float(value), max, min)
# model.table.valueList[source_row] = float(value)
# else:
# model.table.realList[source_row] = float(value)
# model.table.valueList[source_row] = float(value)
# print(model.datas[source_row][3])
res = Globals.getValue('protocolManage').writeVariableValue(model.datas[source_row][3], float(value))
if res:
forceVars = Globals.getValue('forceVars')
forceVars.add(model.datas[source_row][3])
Globals.setValue('forceVars', forceVars)
else:
QMessageBox.information(self.parent(), '提示', '写入失败', QMessageBox.Yes)