|  |  |  | import re | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from PyQt5.QtWidgets import  QWidget, QVBoxLayout, QLabel, QPushButton, QGridLayout, \ | 
					
						
							|  |  |  |     QHBoxLayout, QMessageBox, QSplitter, QRadioButton | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from UI.ProfibusWidgets.SoftKeyBoardEdit import SoftKeyBoardEdit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ForceButton(QPushButton): | 
					
						
							|  |  |  |     def __init__(self, number = None, valueLabel = None, valueEdit = None, qualityValueLabel = None, \ | 
					
						
							|  |  |  |         qualityLineEdit = None, btnName = None): | 
					
						
							|  |  |  |         super().__init__() | 
					
						
							|  |  |  |         self.valueEdit = valueEdit | 
					
						
							|  |  |  |         self.valueLabel = valueLabel | 
					
						
							|  |  |  |         self.qualityValueLabel = qualityValueLabel | 
					
						
							|  |  |  |         self.qualityLineEdit = qualityLineEdit | 
					
						
							|  |  |  |         self.number = number | 
					
						
							|  |  |  |         self.setObjectName('profibusForceBtn') | 
					
						
							|  |  |  |         self.setText(btnName) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ForceRadioButton(QRadioButton): | 
					
						
							|  |  |  |     def __init__(self, number = None): | 
					
						
							|  |  |  |         super().__init__() | 
					
						
							|  |  |  |         self.number = number | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class RightAreaWidgets(QWidget): | 
					
						
							|  |  |  |     def __init__(self, areaWidget, order, byteLineEdit, dataType, deviceName, valueName = None): | 
					
						
							|  |  |  |         super().__init__() | 
					
						
							|  |  |  |         self.areaLineEditValue = [] | 
					
						
							|  |  |  |         self.qualityEditValueList = [] | 
					
						
							|  |  |  |         self.areaLabel = {} | 
					
						
							|  |  |  |         self.qualityLabel = {} | 
					
						
							|  |  |  |         self.areaWidget = areaWidget | 
					
						
							|  |  |  |         self.devicesManange = self.areaWidget.devicesManange | 
					
						
							|  |  |  |         self.order = order | 
					
						
							|  |  |  |         self.byteLineEdit = byteLineEdit | 
					
						
							|  |  |  |         self.dataType = dataType | 
					
						
							|  |  |  |         self.deviceName = deviceName | 
					
						
							|  |  |  |         self.valueName = valueName | 
					
						
							|  |  |  |         if '主站' in self.deviceName and self.dataType == 'AI' or ('从站' in self.deviceName and self.dataType == 'AO'): | 
					
						
							|  |  |  |             self.force = False | 
					
						
							|  |  |  |         elif '主站' in self.deviceName and self.dataType == 'DI' or ('从站' in self.deviceName and self.dataType == 'DO'): | 
					
						
							|  |  |  |             self.force = False | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.force = True | 
					
						
							|  |  |  |         self.addLayout() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # self.setStyleSheet("background-color: black") | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     def addLayout(self): | 
					
						
							|  |  |  |         self.setLayout(self.areaLayout()) | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def areaLayout(self): | 
					
						
							|  |  |  |         areaLayout = QVBoxLayout() | 
					
						
							|  |  |  |         areaLayout.setContentsMargins(0, 0, 0, 0) | 
					
						
							|  |  |  |         if self.dataType in ['AI','AO']: | 
					
						
							|  |  |  |             hLayout = QHBoxLayout() | 
					
						
							|  |  |  |             hLayout.addWidget(QSplitter()) | 
					
						
							|  |  |  |             hLayout.addLayout(self.dateLayout(0)) | 
					
						
							|  |  |  |             hLayout.addWidget(QSplitter()) | 
					
						
							|  |  |  |             areaLayout.addWidget(QSplitter()) | 
					
						
							|  |  |  |             areaLayout.addLayout(hLayout) | 
					
						
							|  |  |  |             areaLayout.addWidget(QSplitter()) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             byteLineEdit = int(self.byteLineEdit) * 4 | 
					
						
							|  |  |  |             areaLayout.addWidget(QSplitter()) | 
					
						
							|  |  |  |             for i in range(int(byteLineEdit)): | 
					
						
							|  |  |  |                 hLayout = QHBoxLayout() | 
					
						
							|  |  |  |                 hLayout.addWidget(QSplitter(), 1) | 
					
						
							|  |  |  |                 hLayout.addLayout(self.dateLayout(number = (i), isAnalog = False), 3)  | 
					
						
							|  |  |  |                 hLayout.addWidget(QSplitter(), 1) | 
					
						
							|  |  |  |                 hLayout.addLayout(self.dateLayout(number = (i) + 8, isAnalog = False), 3) | 
					
						
							|  |  |  |                 hLayout.addWidget(QSplitter(), 1) | 
					
						
							|  |  |  |                 areaLayout.addLayout(hLayout) | 
					
						
							|  |  |  |             areaLayout.addWidget(QSplitter()) | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  |         return areaLayout | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     def dateLayout(self, number, isAnalog = True): | 
					
						
							|  |  |  |         if not isAnalog: | 
					
						
							|  |  |  |             forceLayout = QHBoxLayout() | 
					
						
							|  |  |  |             valueRadio = ForceRadioButton(number = number) | 
					
						
							|  |  |  |             valueRadio.setObjectName('valueRadio') | 
					
						
							|  |  |  |             valueRadio.setAutoExclusive(False) | 
					
						
							|  |  |  |             valueRadio.setText('OFF') | 
					
						
							|  |  |  |             valueRadio.toggled.connect(self.DIDOForceValues) | 
					
						
							|  |  |  |             massesageLabel = QLabel('通道 {} '.format(str(number + 1))) | 
					
						
							|  |  |  |             massesageLabel.setObjectName('massesageLabel') | 
					
						
							|  |  |  |             forceLayout.addWidget(massesageLabel) | 
					
						
							|  |  |  |             forceLayout.addWidget(valueRadio) | 
					
						
							|  |  |  |             forceLayout.setContentsMargins(0, 0, 0, 0) | 
					
						
							|  |  |  |             forceLayout.setSpacing(0) | 
					
						
							|  |  |  |             self.areaLabel[number] = valueRadio | 
					
						
							|  |  |  |             if not self.force: | 
					
						
							|  |  |  |                 valueRadio.setEnabled(False) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             forceLayout = QGridLayout() | 
					
						
							|  |  |  |             forceLayout.setContentsMargins(0, 0, 0, 0) | 
					
						
							|  |  |  |             areaMessLabel = QLabel('当前值:' ) | 
					
						
							|  |  |  |             areaMessLabel.setObjectName('areaMessLabel') | 
					
						
							|  |  |  |             areaValueLabel = QLabel('0') | 
					
						
							|  |  |  |             areaValueLabel.setObjectName('areaValueLabel') | 
					
						
							|  |  |  |             forceLayout.addWidget(areaMessLabel,0,0,1,1) | 
					
						
							|  |  |  |             forceLayout.addWidget(areaValueLabel,0,1,1,1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             #添加质量位置layout | 
					
						
							|  |  |  |             qualityLabel = QLabel('质量位状态值:' ) | 
					
						
							|  |  |  |             qualityLabel.setObjectName('areaMessLabel') | 
					
						
							|  |  |  |             qualityValueLabel = QLabel('0') | 
					
						
							|  |  |  |             qualityValueLabel.setObjectName('areaValueLabel') | 
					
						
							|  |  |  |             forceLayout.addWidget(qualityLabel,1,0,1,1) | 
					
						
							|  |  |  |             forceLayout.addWidget(qualityValueLabel,1,1,1,1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if self.force: | 
					
						
							|  |  |  |                 areaLineEdit = SoftKeyBoardEdit('0') | 
					
						
							|  |  |  |                 areaLineEdit.setObjectName('areaLineEdit') | 
					
						
							|  |  |  |                 areaLineEdit.setFixedSize(80, 33) | 
					
						
							|  |  |  |             | 
					
						
							|  |  |  |                 qualityLineEdit = SoftKeyBoardEdit('80') | 
					
						
							|  |  |  |                 qualityLineEdit.setObjectName('areaLineEdit') | 
					
						
							|  |  |  |                 qualityLineEdit.setFixedSize(80, 33) | 
					
						
							|  |  |  |                 forceBtn = ForceButton(number = number, valueLabel=areaValueLabel, valueEdit=areaLineEdit, qualityValueLabel=qualityValueLabel, \ | 
					
						
							|  |  |  |                     qualityLineEdit=qualityLineEdit, btnName = '强制') | 
					
						
							|  |  |  |                 forceBtn.clicked.connect(self.AIAOForceValues) | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 qualityBtn = ForceButton(number = number, valueLabel=areaValueLabel, valueEdit=areaLineEdit, qualityValueLabel=qualityValueLabel, \ | 
					
						
							|  |  |  |                     qualityLineEdit=qualityLineEdit, btnName = '故障') | 
					
						
							|  |  |  |                 qualityBtn.clicked.connect(lambda: self.AIAOForceValues(qualityValue = '0')) | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |                 # forceBtn.setFixedSize(50, 27) | 
					
						
							|  |  |  |                 forceLayout.addWidget(areaLineEdit,0,2,1,1) | 
					
						
							|  |  |  |                 forceLayout.addWidget(forceBtn,0,3,1,1) | 
					
						
							|  |  |  |                 forceLayout.addWidget(qualityLineEdit,1,2,1,1) | 
					
						
							|  |  |  |                 forceLayout.addWidget(qualityBtn,1,3,1,1) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.areaLabel[number] = areaValueLabel | 
					
						
							|  |  |  |                 self.qualityLabel[number] = qualityValueLabel | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.areaLineEditValue.append(0) | 
					
						
							|  |  |  |         self.qualityEditValueList.append(0) | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |             #     if self.deviceName[-2:] + self.dataType  in ['从站DI','主站DO']: | 
					
						
							|  |  |  |             #         areaMessLabel.setObjectName('wirteDIDOareaMessLabel') | 
					
						
							|  |  |  |             #         areaValueLabel.setObjectName('wirteDIDOareaValueLabel') | 
					
						
							|  |  |  |             #         areaLineEdit.setObjectName('wirteDIDOareaLineEdit') | 
					
						
							|  |  |  |             #         areaLineEdit.setFixedSize(30, 27) | 
					
						
							|  |  |  |             #         areaLineEdit.setAlignment(Qt.AlignHCenter) | 
					
						
							|  |  |  |             #         forceBtn.setObjectName('wirteDIDOforceBtn') | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             # if self.deviceName[-2:] + self.dataType  in ['主站DI','从站DO']: | 
					
						
							|  |  |  |             #     areaMessLabel.setObjectName('readDIDOareaMessLabel') | 
					
						
							|  |  |  |             #     areaValueLabel.setObjectName('readDIDOareaValueLabel') | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # forceLayout.setSpacing(10) | 
					
						
							|  |  |  |         return forceLayout | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def wirteAreaLineEditValue(self,dataTypeAndModel, number, value, qualityValue = None, valueLabel = None, \ | 
					
						
							|  |  |  |      qualityValueLabel = None): | 
					
						
							|  |  |  |         if self.areaWidget.okBtnValue: | 
					
						
							|  |  |  |             QMessageBox.warning(self, '提示', '请先保存通道信息') | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |         if dataTypeAndModel in ['主站AO','从站AI']: | 
					
						
							|  |  |  |             pattern = re.compile(r'^[+-]?(\d+(\.\d*)?|\.\d+)$') | 
					
						
							|  |  |  |             match = pattern.match(value) | 
					
						
							|  |  |  |             hexPattern = re.compile(r'^(0x)?[0-9A-Fa-f]{1,2}$') | 
					
						
							|  |  |  |             match2 = hexPattern.match(qualityValue) | 
					
						
							|  |  |  |             if  not match : | 
					
						
							|  |  |  |                 QMessageBox.warning(self, '提示', '请输入数字。') | 
					
						
							|  |  |  |                 return None, None | 
					
						
							|  |  |  |             if not match2: | 
					
						
							|  |  |  |                 QMessageBox.warning(self, '提示', '请输入0-FF') | 
					
						
							|  |  |  |                 return None, None | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 hexValue = int(match2.group(0), 16) | 
					
						
							|  |  |  |                 # 检查值是否小于等于 255 | 
					
						
							|  |  |  |                 if hexValue > 255: | 
					
						
							|  |  |  |                     QMessageBox.warning(self, '提示', '请输入0-FF') | 
					
						
							|  |  |  |                     return None, None | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     valueLabel.setText(str(float(value))) | 
					
						
							|  |  |  |                     qualityValueLabel.setText(str(qualityValue)) | 
					
						
							|  |  |  |                     self.areaLineEditValue[number] = float(value) | 
					
						
							|  |  |  |                     # print(self.areaLineEditValue,number, qualityValue ) | 
					
						
							|  |  |  |                     self.qualityEditValueList[number] = qualityValue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return self.areaLineEditValue , self.qualityEditValueList #返回值和质量位值 | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  |         #判断输入值是否为0和1 | 
					
						
							|  |  |  |         elif dataTypeAndModel in ['主站DO','从站DI']: | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             self.areaLineEditValue[number] = value | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |             return self.areaLineEditValue  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     def readValues(self, curIndex): | 
					
						
							|  |  |  |         # print(curIndex) | 
					
						
							|  |  |  |         if not self.force: | 
					
						
							|  |  |  |             device = self.devicesManange.getDevice(self.deviceName) | 
					
						
							|  |  |  |             values, qualityValueList = device.getAreaValues(curIndex) | 
					
						
							|  |  |  |             # print(qualityValueList) | 
					
						
							|  |  |  |             # print(self.deviceName, curIndex, values) | 
					
						
							|  |  |  |             if len(values) > len(self.areaLabel): | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             for index, value in enumerate(values): | 
					
						
							|  |  |  |                 # print(self.dataType, self.force) | 
					
						
							|  |  |  |                 if self.dataType in ['DI', 'DO'] and not self.force: | 
					
						
							|  |  |  |                     if value == 1: | 
					
						
							|  |  |  |                         value = 'ON' | 
					
						
							|  |  |  |                         self.areaLabel[index].setChecked(True) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         value = 'OFF' | 
					
						
							|  |  |  |                         self.areaLabel[index].setChecked(False) | 
					
						
							|  |  |  |                     self.areaLabel[index].setText(value) | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 self.areaLabel[index].setText(str(value)) | 
					
						
							|  |  |  |             for index, value in enumerate(qualityValueList): | 
					
						
							|  |  |  |                 self.qualityLabel[index].setText(str(value)) | 
					
						
							|  |  |  |                 # print(self.areaLabel[index],values) | 
					
						
							|  |  |  |                      | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def AIAOForceValues(self, qualityValue = None): | 
					
						
							|  |  |  |         sender = self.sender() | 
					
						
							|  |  |  |         number = sender.number | 
					
						
							|  |  |  |         valueLabel = sender.valueLabel | 
					
						
							|  |  |  |         qualityValueLabel = sender.qualityValueLabel | 
					
						
							|  |  |  |         value = sender.valueEdit.text() | 
					
						
							|  |  |  |         if qualityValue == '0': | 
					
						
							|  |  |  |             qualityValue = '0' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             qualityValue = sender.qualityLineEdit.text() | 
					
						
							|  |  |  |         # print(qualityValue) | 
					
						
							|  |  |  |         dataTypeAndModel = self.deviceName[-2:] + self.dataType | 
					
						
							|  |  |  |         curIndex = self.areaWidget.areaTabWidget.currentIndex() | 
					
						
							|  |  |  |         valueList, qualityValueList = self.wirteAreaLineEditValue(dataTypeAndModel=dataTypeAndModel, number=number, value=value, qualityValue=qualityValue, \ | 
					
						
							|  |  |  |             valueLabel=valueLabel, qualityValueLabel=qualityValueLabel ) | 
					
						
							|  |  |  |         # print(valueList, qualityValueList,222) | 
					
						
							|  |  |  |         if valueList is None: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.devicesManange.writeAreas(deviceName = self.deviceName, areaIndex = curIndex, values = valueList, qualityValueList = qualityValueList) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     def DIDOForceValues(self): | 
					
						
							|  |  |  |         sender = self.sender() | 
					
						
							|  |  |  |         number = sender.number | 
					
						
							|  |  |  |         value = 1 if sender.isChecked() else 0 | 
					
						
							|  |  |  |         dataTypeAndModel = self.deviceName[-2:] + self.dataType | 
					
						
							|  |  |  |         curIndex = self.areaWidget.areaTabWidget.currentIndex() | 
					
						
							|  |  |  |         valueList = self.wirteAreaLineEditValue(dataTypeAndModel=dataTypeAndModel, number=number, value=value) | 
					
						
							|  |  |  |         if valueList is None: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.devicesManange.writeAreas(deviceName = self.deviceName, areaIndex = curIndex, values = valueList) | 
					
						
							|  |  |  |         if sender.isChecked(): | 
					
						
							|  |  |  |             sender.setText('ON') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             sender.setText('OFF') |