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.
		
		
		
		
		
			
		
			
	
	
		
			307 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
		
		
			
		
	
	
			307 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
| 
											6 months ago
										 | 
 | ||
|  | import time | ||
|  | import typing | ||
|  | import re | ||
|  | # from matplotlib.pyplot import box | ||
|  | import qtawesome | ||
|  | from PyQt5 import QtGui,QtCore,QtWidgets | ||
|  | from PyQt5.QtCore import QAbstractTableModel, QModelIndex, Qt, QVariant, QSize, QTimer | ||
|  | from PyQt5.QtWidgets import QItemDelegate, QHBoxLayout, QWidget, QPushButton, QMessageBox, QLineEdit,  \ | ||
|  | QComboBox, QStyledItemDelegate, QVBoxLayout, QSplitter | ||
|  | 
 | ||
|  | from UI.ProfibusWidgets.LoadingDataWidget import LoadingDataWidget | ||
|  | from UI.ProfibusWidgets.ObjectTypeEditlayout import ObjectTypeEditlayout | ||
|  | 
 | ||
|  | from utils import Globals | ||
|  | 
 | ||
|  | from utils.DBModels.DeviceParModels import * | ||
|  | 
 | ||
|  | class VarTableModel(QAbstractTableModel): | ||
|  |     ''' 变量表模型类''' | ||
|  |     def __init__(self, header, data: list, table = None): | ||
|  |         '''
 | ||
|  |         header : 表头变量 | ||
|  |         data : 表格内容 | ||
|  |         table : 缺省参数 | ||
|  |         '''
 | ||
|  |         QAbstractTableModel.__init__(self, parent=None) | ||
|  |         self.header = header | ||
|  |         self.datas = data | ||
|  |         self.checkList = ['Unchecked'] * len(self.datas) | ||
|  |         self.supportedDragActions() | ||
|  |         self.table = table | ||
|  |         self.editableList = [] # 表格中可编辑项 | ||
|  | 
 | ||
|  | 
 | ||
|  |     | ||
|  |     def append_data(self, x): | ||
|  |         self.datas.append(x) | ||
|  |         self.checkList = ['Unchecked'] * len(self.datas) | ||
|  |         self.table.proxy.invalidate() | ||
|  |         # self.layoutChanged.emit() | ||
|  | 
 | ||
|  |     def insert_data(self, x, index): | ||
|  |         self.datas.insert(index, x) | ||
|  |         self.checkList = ['Unchecked'] * len(self.datas) | ||
|  |         self.table.proxy.invalidate() | ||
|  | 
 | ||
|  |     def updateColumn(self, row, value): | ||
|  |         if row < 0 or row >= self.rowCount(): | ||
|  |             print("列索引超出范围") | ||
|  |             return | ||
|  |         # for row in range(self.rowCount()): | ||
|  | 
 | ||
|  |         if 'unit'  in self.datas[row][2].lower() or 'unt' in self.datas[row][2].lower(): | ||
|  |             unit = UnitTable.getUnitSymbolByUnitValue(value) | ||
|  |             value = unit if unit else value | ||
|  |         self.datas[row][6] = value | ||
|  |         self.table.proxy.invalidate() | ||
|  |         # self.layoutChanged.emit()  # 通知视图数据已更改 | ||
|  |         # self.dataChanged.emit() | ||
|  | 
 | ||
|  |     def remove_row(self, row): | ||
|  |         self.datas.pop(row) | ||
|  |         self.checkList = ['UnChecked'] * len(self.datas) | ||
|  |         self.table.proxy.invalidate() | ||
|  | 
 | ||
|  |     def rowCount(self, parent: QModelIndex = ...) -> int: | ||
|  |         if len(self.datas) > 0: | ||
|  |             return len(self.datas) | ||
|  |         return 0 | ||
|  | 
 | ||
|  |     def columnCount(self, parent: QModelIndex = ...) -> int: | ||
|  |         return len(self.header) | ||
|  | 
 | ||
|  |     def data(self, QModelIndex, role=None): | ||
|  |         # print(Qt.__dict__.items()) | ||
|  |         if role == Qt.TextAlignmentRole: | ||
|  |             return Qt.AlignCenter | ||
|  |         if not QModelIndex.isValid(): | ||
|  |             | ||
|  |             return QVariant() | ||
|  | 
 | ||
|  |         if role == Qt.TextColorRole: | ||
|  |             return QtGui.QColor('#1A1A1A') | ||
|  | 
 | ||
|  |         if role == Qt.DisplayRole or role == Qt.EditRole: | ||
|  |             if QModelIndex.row() in self.editableList or 'w' in self.datas[QModelIndex.row()][5]: | ||
|  |                 return self.datas[QModelIndex.row()][QModelIndex.column()] | ||
|  |         if role != Qt.DisplayRole: | ||
|  |             return QVariant() | ||
|  | 
 | ||
|  | 
 | ||
|  |         return self.datas[QModelIndex.row()][QModelIndex.column()] | ||
|  | 
 | ||
|  |     def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any: # 表头 | ||
|  |         if role != Qt.DisplayRole: | ||
|  |             return None | ||
|  | 
 | ||
|  |         if role == Qt.SizeHintRole: | ||
|  |             # print(self.datas[QModelIndex.row()][QModelIndex.column()].find('\r\n')) | ||
|  |             return QSize(500, 500) | ||
|  | 
 | ||
|  |         if orientation == Qt.Horizontal: | ||
|  |             return self.header[section] | ||
|  | 
 | ||
|  |         # if orientation == Qt.Vertical: | ||
|  |         #     return str(section + 1) | ||
|  | 
 | ||
|  |     def setData(self, index, value, role): | ||
|  |         row = index.row() | ||
|  |         col = index.column() | ||
|  |         if role == Qt.EditRole: | ||
|  |             self.datas[row][col] = value | ||
|  |             return True | ||
|  |         return True | ||
|  | 
 | ||
|  |     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() == 7: | ||
|  |             return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEditable | ||
|  |        | ||
|  | 
 | ||
|  |         if 'w' in self.datas[index.row()][5] and index.column() == 6: | ||
|  |             return Qt.ItemIsEnabled | Qt.ItemIsEditable | ||
|  |       | ||
|  |         return Qt.ItemIsEnabled | ||
|  | 
 | ||
|  |     def dragMoveEvent(self, event): | ||
|  |         event.setDropAction(QtCore.Qt.MoveAction) | ||
|  |         event.accept() | ||
|  | 
 | ||
|  |     def moveRow(self, sourceParent: QModelIndex, sourceRow: int, destinationParent: QModelIndex, | ||
|  |                 destinationChild: int) -> bool: | ||
|  |         if self.datas[destinationChild] == self.datas[sourceRow]: | ||
|  |             return | ||
|  |         self.datas[sourceRow], self.datas[destinationChild] = self.datas[destinationChild], self.datas[sourceRow] | ||
|  |         self.table.proxy.invalidate() | ||
|  | 
 | ||
|  |     def updateValue(self, valueList): | ||
|  |         for index, value in enumerate(valueList): | ||
|  |             if 'unit' in self.datas[index][2].lower() or 'unt'  in self.datas[index][2].lower(): | ||
|  |                 unit = UnitTable.getUnitSymbolByUnitValue(value) | ||
|  |                 value = unit if unit else value | ||
|  |             self.datas[index][6] = value | ||
|  |         self.table.proxy.invalidate() | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | class VarButtonDelegate(QItemDelegate): | ||
|  |     """该类用于向单元格中添加按钮  任务表格""" | ||
|  |     def __init__(self, parent=None): | ||
|  |         super(VarButtonDelegate, self).__init__(parent) | ||
|  | 
 | ||
|  |     def paint(self, painter, option, index): | ||
|  |         if not self.parent().indexWidget(index): | ||
|  |             startActionBtn = QPushButton( | ||
|  |                 qtawesome.icon('fa.play', color='#1fbb6f'), | ||
|  |                 "", | ||
|  |                 self.parent() | ||
|  |             ) | ||
|  |              | ||
|  |             boxLayout = QHBoxLayout() | ||
|  |              | ||
|  |             refreshButton = QPushButton( | ||
|  |                 qtawesome.icon('fa.refresh', color='#1fbb6f'), | ||
|  |                 "", | ||
|  |                 self.parent() | ||
|  |             ) | ||
|  | 
 | ||
|  |             refreshButton.setToolTip('刷新') | ||
|  |             refreshButton.setObjectName("refreshButton") | ||
|  |             refreshButton.clicked.connect(self.refreshData) | ||
|  |             refreshButton.index = [index.row(), index.column()] | ||
|  |             refreshButton.setIconSize(QSize(50,50)) | ||
|  | 
 | ||
|  |             readORwirte = self.parent().model.datas[index.row()][5] | ||
|  |             if 'w' not in readORwirte: | ||
|  |                 boxLayout.addWidget(QSplitter()) | ||
|  |                 boxLayout.addWidget(refreshButton) | ||
|  |                 boxLayout.addWidget(QSplitter()) | ||
|  |             else: | ||
|  |                 dataType = self.parent().model.datas[index.row()][4] | ||
|  |                 objectType =  self.parent().model.datas[index.row()][2] | ||
|  | 
 | ||
|  |                 editlineLayout = ObjectTypeEditlayout(objectType, dataType) | ||
|  | 
 | ||
|  |                 startActionBtn.index = [index.row(), index.column()] | ||
|  |                 startActionBtn.setToolTip('强制') | ||
|  | 
 | ||
|  |                  | ||
|  | 
 | ||
|  |                      | ||
|  |                 if objectType == 'TARGET_MODE': | ||
|  |                     combox = QComboBox() | ||
|  |                     combox.setObjectName('modeCombox') | ||
|  |                     combox.addItems(["非服务", "手动初始化", "本地超驰", '手动', '自动', '级联', '远程级联', '远程输出']) | ||
|  |                     combox.setCurrentIndex(-1) | ||
|  |                     combox.currentIndexChanged.connect(lambda index: self.startAction(modelIndex = index)) | ||
|  |                     boxLayout.addWidget(combox, 10) | ||
|  |                     boxLayout.addWidget(refreshButton,1) | ||
|  |                     combox.index = [index.row(), index.column()] | ||
|  | 
 | ||
|  |                 elif 'unit'  in objectType.lower() or 'unt' in objectType.lower(): | ||
|  |                     comboxUnit = QComboBox() | ||
|  |                     comboxUnit.setObjectName('modeCombox') | ||
|  |                     comboxUnit.addItem('下拉选择') | ||
|  |                     comboxUnit.addItems([x[1] for x in self.parent().allUnitList]) | ||
|  | 
 | ||
|  |                      | ||
|  |                     comboxUnit.currentIndexChanged.connect(lambda index, comboxUnit = comboxUnit : self.startAction(modelIndex = index, comboxUnit = comboxUnit)) | ||
|  |                     boxLayout.addWidget(comboxUnit, 10) | ||
|  |                     boxLayout.addWidget(refreshButton,1) | ||
|  |                     comboxUnit.index = [index.row(), index.column()] | ||
|  | 
 | ||
|  |                 else: | ||
|  |                     boxLayout.addLayout(editlineLayout)      | ||
|  |                     startActionBtn.clicked.connect(lambda: self.startAction(objectTypeEditlayout = editlineLayout)) | ||
|  |                     boxLayout.addWidget(startActionBtn) | ||
|  |                     boxLayout.addWidget(refreshButton) | ||
|  | 
 | ||
|  | 
 | ||
|  |                  | ||
|  |                 startActionBtn.setObjectName('startActionBtn') | ||
|  |                 startActionBtn.setIconSize(QSize(50,50)) | ||
|  | 
 | ||
|  | 
 | ||
|  |             boxLayout.setContentsMargins(0, 0, 0, 0) | ||
|  |             widget = QWidget() | ||
|  |             # widget.setMinimumHeight(200) | ||
|  |             widget.setLayout(boxLayout) | ||
|  |             self.parent().setIndexWidget( | ||
|  |                 index, | ||
|  |                 widget | ||
|  |             ) | ||
|  |               | ||
|  |          | ||
|  |     def startAction(self, objectTypeEditlayout = None, modelIndex = None, comboxUnit = None): | ||
|  |         sender = self.sender() | ||
|  |         blockView = self.parent() | ||
|  |         model = blockView.model | ||
|  |         blockType = blockView.blockType | ||
|  |         blockIndex = blockView.blcokIndex | ||
|  |         parmIndex = model.datas[sender.index[0]][1] | ||
|  |         blockManage = Globals.getValue('blockManage') | ||
|  |         values = [] | ||
|  |         #修改单位 | ||
|  |         if comboxUnit: | ||
|  |             if modelIndex == 0: | ||
|  |                 return | ||
|  |             else: | ||
|  |                 values = [self.parent().allUnitList[modelIndex - 1][0]] | ||
|  |             # print(values) | ||
|  |         #修改操作模式 | ||
|  |         else:  | ||
|  |             if modelIndex or str(modelIndex) == '0' : | ||
|  |                | ||
|  |                 values.append(str(modelIndex)) | ||
|  |             #正常修改其他值 | ||
|  |             else: | ||
|  |                  | ||
|  |                 values = objectTypeEditlayout.getEditlineValue() | ||
|  |                  | ||
|  |                 dataType = model.datas[sender.index[0]][4] | ||
|  |                 if not values: | ||
|  |                         reply = QMessageBox.question(self.parent(), | ||
|  |                                                         '警告', | ||
|  |                                                         "请输入强制值", | ||
|  |                                                         QMessageBox.Yes) | ||
|  |                         return | ||
|  |                 if dataType in ['Float', 'DS-36', 'Unsigned16', 'Unsigned8']: | ||
|  |                         pattern = re.compile(r'^[+-]?(\d+(\.\d*)?|\.\d+)$') | ||
|  |                         for value in values: | ||
|  |                             if not value or not re.findall(pattern, str(value)): | ||
|  |                                 reply = QMessageBox.question(self.parent(), | ||
|  |                                                             '警告', | ||
|  |                                                             "请输入强制值或数字", | ||
|  |                                                             QMessageBox.Yes) | ||
|  |                                 return | ||
|  |         # print(values,555) | ||
|  |         res = blockManage.writeParmValue(blockType, blockIndex, parmIndex, values) | ||
|  |         time.sleep(0.4) | ||
|  |         self.refreshData() | ||
|  |      | ||
|  |     def refreshData(self): | ||
|  |         sender = self.sender() | ||
|  |         blockView = self.parent() | ||
|  |         model = blockView.model | ||
|  |         parmIndex = model.datas[sender.index[0]][1] | ||
|  |         blockType = blockView.blockType | ||
|  |         blockIndex = blockView.blcokIndex | ||
|  |         # print(blockName, blcokIndex, index) | ||
|  |         blockManage = Globals.getValue('blockManage') | ||
|  |         value = blockManage.getBlockParmValue(blockType, blockIndex, parmIndex) | ||
|  |         # self.loadingDataWidget = LoadingDataWidget() | ||
|  |         # self.loadingDataWidget.show() | ||
|  |         # self.loadingDataWidget.loadData(1, 1) | ||
|  |         self.loadingDataWidget = LoadingDataWidget(refreshType = True) | ||
|  |         self.loadingDataWidget.exec_() | ||
|  |         model.updateColumn(sender.index[0], value) | ||
|  |         # self.parent().resizeHeader() | ||
|  |         blockView.proxy.invalidate() | ||
|  | 
 | ||
|  |      | ||
|  | 
 | ||
|  | 
 |