import re from socket import AI_ADDRCONFIG import sys import json import qtawesome from tkinter import N from functools import partial from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout, QLabel, QPushButton, QLayout, \ QHBoxLayout, QComboBox, QLineEdit, QSpacerItem, QSizePolicy, QGridLayout, QMessageBox, QSplitter, QFrame from PyQt5.QtGui import QIcon from PyQt5.QtCore import QSize from model.ProjectModel.DeviceManage import Device, DevicesManange from UI.RightAreaWidget import RightAreaWidgets from utils.DBModels.DeviceModels import DeviceDB class AreaTabWidget(QTabWidget): def __init__(self, deviceWidget): super().__init__() self.deviceWidget = deviceWidget self.devicesManange = self.deviceWidget.devicesManange self.initUI() def initUI(self): self.deviceName = self.deviceWidget.deviceName # 创建一个 QTabWidget self.setObjectName('areaTabWidget') self.setTabPosition(QTabWidget.South) self.tabBar().setObjectName('areaTabBar') self.addAreaButton = QPushButton("添加通道 ") self.addAreaButton.setObjectName('addareabutton') self.addAreaButton.setIcon(QIcon('Static/add.png')) self.addAreaButton.setFlat(True) self.addAreaButton.clicked.connect(self.addAreaTab) self.setCornerWidget(self.addAreaButton) # self.state = True self.initWidget() #初始化界面 # self.tabCloseRequested.connect(self.closeTab) # self.setTabPosition(QTabWidget.West) # self.setTabsClosable(True) # 设置主窗口的中心部分为 QTabWidget def initWidget(self): alldevices = DevicesManange.getAllDevice() if alldevices: for devices in alldevices: if self.deviceName in devices: areas = json.loads(devices[3]) if areas: self.removeTab(0) # self.state = False for area in areas: dataType, order = self.tran(area["type"], area["order"]) channelBytes = area["bytes"] settingValue = [dataType, order, channelBytes] self.addAreaTab(settingValue=settingValue) else: widget = QWidget() widget.setObjectName('initWidget') layout = QHBoxLayout() addButton = QPushButton('添加通道') addButton.setObjectName('initAreaAddButton') icon = QIcon('Static/add.png') iconSize = QSize(50,50) addButton.setIcon(icon) addButton.setIconSize(iconSize) addButton.clicked.connect(lambda: self.addAreaTab(True)) layout.addWidget(QSplitter()) layout.addWidget(addButton) layout.addWidget(QSplitter()) widget.setLayout(layout) self.addTab(widget,'') self.tabBar().setHidden(True) def addAreaTab(self, init = False, settingValue = None): if settingValue is None: if init: self.removeTab(0) tabIndex = self.count() #判断area右侧布局是是否添加 if self.widget(int(tabIndex - 1)): if not self.widget(int(tabIndex - 1)).rightAreaWidgetState: QMessageBox.warning(self, '警告', '有值未输入。') return areaWidget = AreaWidget(self) self.addTab(areaWidget, '通道' + str(tabIndex + 1)) self.setCurrentIndex(tabIndex) self.tabBar().setHidden(False) else: tabIndex = self.count() areaWidget = AreaWidget(self, settingValue) self.addTab(areaWidget, '通道' + str(tabIndex + 1)) self.tabBar().setHidden(False) def tran(self, dataType, order): if dataType == 'AI': dataType = 0 if dataType == 'AO': dataType = 1 if dataType == 'DI': dataType = 2 if dataType == 'DO': dataType = 3 if order == 'ABCD': order = 0 if order == 'DCBA': order = 1 if order == 'CDAB': order = 2 if order == 'BADC': order = 3 return dataType, order class AreaWidget(QWidget): def __init__(self, areaTabWidget, settingValue = None): super().__init__() self.areaTabWidget = areaTabWidget self.settingValue = settingValue self.state = True self.devicesManange = self.areaTabWidget.devicesManange self.rightAreaWidgetState = False self.initUI() def initUI(self): self.mainLayout = QHBoxLayout() self.leftLayout = QGridLayout() self.rightLayout = QGridLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.leftLayout.setContentsMargins(0, 0, 0, 0) self.rightLayout.setContentsMargins(0, 0, 0, 0) LimitData = self.devicesManange.getLimitData(self.areaTabWidget.deviceName) self.pvUpperLimit = QLabel('量程上限: {}'.format(LimitData[0])) self.pvUpperLimit.setObjectName('pvUpperLimit') self.pvLowerLimit = QLabel('量程下限: {}'.format(LimitData[1])) self.pvLowerLimit.setObjectName('pvLowerLimit') self.pvUnit = QLabel('单 位: {}'.format(LimitData[2])) self.pvUnit.setObjectName('pvUnit') self.dataTypeLabel = QLabel('数据类型:') self.dataTypeLabel.setObjectName('dataTypeLabel') # self.dataTypeLabel.setFixedSize(90, 27) self.dataTypeCombox = QComboBox() self.dataTypeCombox.addItems(['AI', 'AO', 'DI', 'DO']) self.dataTypeCombox.setObjectName('dataTypeCombox') self.dataTypeCombox.currentIndexChanged.connect(self.setByteLineEditValue) # self.dataTypeCombox.setFixedSize(90, 27) self.dataOrderLabel = QLabel('数据格式:') self.dataOrderLabel.setObjectName('dataOrderLabel') # self.dataOrderLabel.setFixedSize(90, 27) self.orderCombox = QComboBox() self.orderCombox.addItems(['不转换', '字节转换', '字转换', '字内转换']) self.orderCombox.setObjectName('orderCombox') # self.orderCombox.setFixedSize(90, 27) self.byteLineLabel = QLabel('字节长度:') self.byteLineLabel.setObjectName('byteLineLabel') # self.byteLineLabel.setFixedSize(90, 27) self.byteLineEdit = QLineEdit() self.byteLineEdit.setPlaceholderText('字节长度') self.byteLineEdit.setObjectName('byteLineEdit') # self.byteLineEdit.setFixedSize(90, 27) self.okBtn = QPushButton('确定') # self.okBtn.setFixedSize(90, 27) self.okBtn.setObjectName('okBtn') self.okBtn.setIcon(qtawesome.icon('fa.pencil', color='#4c8cf2')) # self.okBtn.setIcon(QIcon('Static/delete.png')) self.okBtn.clicked.connect(self.addAreaWidget) self.okBtnValue = True self.delAreaBtn = QPushButton('删除') self.delAreaBtn.setIcon(QIcon('Static/delete.png')) self.delAreaBtn.setObjectName('delAreaBtn') # self.delAreaBtn.setFixedSize(90, 27) self.delAreaBtn.clicked.connect(self.removeAreaTab) hLayout = QHBoxLayout() hLayout.addWidget(QSplitter()) hLayout.addWidget(self.okBtn) hLayout.addWidget(QSplitter()) hLayout.addWidget(self.delAreaBtn) hLayout.addWidget(QSplitter()) # vlayout = QVBoxLayout() # vlayout.addWidget(self.pvUpperLimit) # vlayout.addWidget(self.pvLowerLimit) # vlayout.addWidget(self.pvUnit) self.leftLayout.addWidget(self.pvUpperLimit, 0, 0, 1, 2) self.leftLayout.addWidget(self.pvLowerLimit, 1, 0, 1, 2) self.leftLayout.addWidget(self.pvUnit,2, 0, 1, 2) self.leftLayout.addWidget(self.dataTypeLabel, 3, 0, 2, 1) self.leftLayout.addWidget(self.dataTypeCombox, 3, 1, 2, 1) self.leftLayout.addWidget(self.dataOrderLabel,4, 0, 2, 1) self.leftLayout.addWidget(self.orderCombox,4, 1, 2, 1) self.leftLayout.addWidget(self.byteLineLabel,5, 0, 2,1) self.leftLayout.addWidget(self.byteLineEdit,5, 1, 2, 1) self.leftLayout.addWidget(QSplitter(),6, 0, 2, 2) self.leftLayout.addLayout(hLayout, 7, 0, 2, 2) self.leftLayout.setContentsMargins(10, 10, 0, 20) # self.leftLayout.addWidget(self.delAreaBtn, 3, 1, 1, 1) self.rightLayout.addWidget(QWidget()) line = QFrame() line.setFrameShape(QFrame.VLine) line.setLineWidth(2) self.mainLayout.addLayout(self.leftLayout, 1) self.mainLayout.addWidget(line) self.mainLayout.addLayout(self.rightLayout, 20) self.mainLayout.setSpacing(10) # self.deviceWidgetManage.addArea(mainLayout=mainLayout, leftLayoutWidget=leftLayoutWidgets) self.setLayout(self.mainLayout) if self.settingValue is not None: self.addAreaWidget() self.settingValue = None def setByteLineEditValue(self): byteLineEditValue = self.dataTypeCombox.currentText() if byteLineEditValue in ['DI','DO']: self.byteLineEdit.setText('2') self.byteLineEdit.setEnabled(False) else: self.byteLineEdit.setEnabled(True) def removeAreaTab(self): # 只点击了新建区域按钮,未点击确定按钮时,直接点击删除按钮的删除情况 index = self.areaTabWidget.currentIndex() tabCount = self.areaTabWidget.count() if self.okBtn.text() == '确定': if index != -1: self.areaTabWidget.removeTab(index) #正常点击删除按钮的情况 else: deviceName = self.areaTabWidget.deviceName datatype = self.dataTypeCombox.currentText() if index != -1: self.areaTabWidget.removeTab(index) Device.delAreas(deviceName, index) self.devicesManange.getDevice(deviceName).delArea(index, datatype) self.devicesManange.recalculateAddress() if tabCount == 1: self.areaTabWidget.initWidget() self.state = True #重新设置通道显示值 else: for index in range(self.areaTabWidget.count()): self.areaTabWidget.setTabText(index, '通道{}'.format(index+1)) def addAreaWidget(self): curIndex = self.areaTabWidget.currentIndex() #获取左侧配置布局的参数 areaLayout = self.rightLayout deviceName = self.areaTabWidget.deviceName #开启软件时判断数据库是否有存在设备信息,并执行相应的操作 if self.settingValue is None: dataType = self.dataTypeCombox.currentText() order = self.dataTypeTranslate(self.orderCombox.currentText()) byteLineEdit = self.byteLineEdit.text() else: dataTypeIndex = self.settingValue[0] orderIndex = self.settingValue[1] byteLineEditIndex = self.settingValue[2] self.dataTypeCombox.setCurrentIndex(dataTypeIndex) self.orderCombox.setCurrentIndex(orderIndex) self.byteLineEdit.setText(byteLineEditIndex) dataType = self.dataTypeCombox.currentText() order = self.dataTypeTranslate(self.orderCombox.currentText()) byteLineEdit = self.byteLineEdit.text() #判断字节长度的输入是否是数字 pattern = re.compile(r'^[1-7]$') match = pattern.match(byteLineEdit) if not match: QMessageBox.warning(self, '提示', '请输入1 - 7。') return else: #设置点击确定后无法编辑,点击编辑后才能编辑 if self.okBtnValue: self.okBtn.setText('编辑') self.okBtn.setIcon(qtawesome.icon('fa.pencil', color='#4c8cf2')) self.dataTypeCombox.setEnabled(False ) self.orderCombox.setEnabled(False ) self.byteLineEdit.setEnabled(False ) self.okBtnValue = False if dataType in ['DI','DO']: self.okBtn.setEnabled(False) elif dataType in ['AI','AO']: self.okBtn.setText('保存') self.okBtn.setIcon(qtawesome.icon('fa.save', color='#1fbb6f')) self.orderCombox.setEnabled(True) self.byteLineEdit.setEnabled(True) self.okBtnValue = True return #修改配置后刷新布局内容 # if self.settingValue is None: while areaLayout.count(): items = areaLayout.takeAt(0) widget = items.widget() if widget: widget.setParent(None) widget.deleteLater() #添加按钮布局 self.rightAreaWidgets = RightAreaWidgets(self, order = order, byteLineEdit = byteLineEdit, dataType = dataType, deviceName = deviceName) areaLayout.addWidget(self.rightAreaWidgets) self.state = False self.rightAreaWidgetState = True areaId = DevicesManange.getAreaID(deviceName) if self.settingValue is not None: self.isRead = self.devicesManange.getDevice(deviceName).addArea(type = dataType, bytes = int(byteLineEdit), order = order, nums = 1) self.devicesManange.recalculateAddress() return elif areaId is not None and curIndex in areaId: # print(areaId,curIndex,2222) DevicesManange.updataAreas(dataType, order, byteLineEdit, deviceName, curIndex) # print(deviceName, curIndex, dataType, int(byteLineEdit)) self.isRead = self.devicesManange.getDevice(deviceName).editArea(index = curIndex, type = dataType, order = order, bytes = int(byteLineEdit)) # self.readVarTimer.start(500) else: DevicesManange.addAreas(dataType, order, byteLineEdit, deviceName) self.isRead = self.devicesManange.getDevice(deviceName).addArea(type = dataType, bytes = int(byteLineEdit), order = order, nums = 1) self.devicesManange.recalculateAddress() # self.readVarTimer.start(500) def dataTypeTranslate(self, order): self.dataTypeDict = {'不转换': 'ABCD', '字节转换': 'DCBA', '字转换': 'CDAB', '字内转换': 'BADC'} return self.dataTypeDict[order] if __name__ == '__main__': app = QApplication(sys.argv) window = AreaTabWidget() window.show() sys.exit(app.exec_())