|  |  |  |  | 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 | 
					
						
							|  |  |  |  | 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 = [] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         varDatas = HartSimulateVarManage.getAllVar() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if not varDatas: | 
					
						
							|  |  |  |  |             # self.layoutChanged.emit() | 
					
						
							|  |  |  |  |             self.table.proxy.invalidate() | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |         for x in varDatas: | 
					
						
							|  |  |  |  |             for i in range(3, 9): | 
					
						
							|  |  |  |  |                 x.insert(i, '') | 
					
						
							|  |  |  |  |             x.append('') | 
					
						
							|  |  |  |  |             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: | 
					
						
							|  |  |  |  |             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): | 
					
						
							|  |  |  |  |     """该类用于向单元格中添加按钮  任务表格""" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     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)) | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         # 然后创建按钮部件 | 
					
						
							|  |  |  |  |         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("启动仿真") | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |             button2 = QPushButton( | 
					
						
							|  |  |  |  |                 qtawesome.icon('fa.pencil', color='#4c8cf2'), | 
					
						
							|  |  |  |  |                 "", | 
					
						
							|  |  |  |  |                 self.parent(), | 
					
						
							|  |  |  |  |                 clicked=self.edit_action | 
					
						
							|  |  |  |  |             ) | 
					
						
							|  |  |  |  |             button2.setToolTip("编辑变量") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             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("保存变量") | 
					
						
							|  |  |  |  |                 self.parent().model.editableList.append(button2.index[0]) | 
					
						
							|  |  |  |  |                  | 
					
						
							|  |  |  |  |             h_box_layout = QHBoxLayout() | 
					
						
							|  |  |  |  |             h_box_layout.addWidget(button1) | 
					
						
							|  |  |  |  |             h_box_layout.addWidget(button2) | 
					
						
							|  |  |  |  |             h_box_layout.setContentsMargins(2, 2, 2, 2) | 
					
						
							|  |  |  |  |             h_box_layout.setAlignment(Qt.AlignCenter) | 
					
						
							|  |  |  |  |             h_box_layout.setSpacing(3) | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |             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; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             """)
 | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |             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 | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         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) | 
					
						
							|  |  |  |  |         else: | 
					
						
							|  |  |  |  |             varMes = model.datas[source_row] | 
					
						
							|  |  |  |  |             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) | 
					
						
							|  |  |  |  |             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) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     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]] | 
					
						
							|  |  |  |  |         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): | 
					
						
							|  |  |  |  |                 reply = QMessageBox.question(self.parent(), | 
					
						
							|  |  |  |  |                                              '警告', | 
					
						
							|  |  |  |  |                                              "请输入强制值或数字", | 
					
						
							|  |  |  |  |                                              QMessageBox.Yes) | 
					
						
							|  |  |  |  |                 return | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             try: | 
					
						
							|  |  |  |  |                 self.parent().workThread.HartSimulate.writeValue(index, value) | 
					
						
							|  |  |  |  |             except: | 
					
						
							|  |  |  |  |                 reply = QMessageBox.question(self.parent(), | 
					
						
							|  |  |  |  |                                                  '警告', | 
					
						
							|  |  |  |  |                                                  "请先打开通讯", | 
					
						
							|  |  |  |  |                                                  QMessageBox.Yes) | 
					
						
							|  |  |  |  |                 return | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         forceVars = Globals.getValue('forceVars') | 
					
						
							|  |  |  |  |         forceVars.add(model.datas[source_row][1]) | 
					
						
							|  |  |  |  |         Globals.setValue('forceVars', forceVars) |