import re from socket import AI_ADDRCONFIG import sys import json 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.QtCore import QLine from PyQt5.QtGui import QIcon from numpy import add, byte, delete from model.ProjectModel.AreaManage import Area from model.ProjectModel.DeviceWidgetManage import DeviceWidgetManage from UI.AreaMansge import AreaWidgetManage from model.ProjectModel.DeviceManage import Device, DevicesManange class forceButton(QPushButton): def __init__(self, valueEdit): super().__init__() self.valueEdit = valueEdit self.setText('强制') class ButtonLayout(QWidget): def __init__(self): super().__init__() # self.index = index self.addLayout() l = [] def addLayout(self): self.setLayout(self.areaLayout()) def areaLayout(self): areaLayout = QVBoxLayout() for i in range(8): hLayout = QHBoxLayout() hLayout.addLayout(self.dateLayout()) hLayout.addWidget(QSplitter()) hLayout.addLayout(self.dateLayout()) areaLayout.addLayout(hLayout) return areaLayout def dateLayout(self, force = True): forceLayout = QHBoxLayout() areaMessLabel = QLabel('DO' + str(1) + ": " + '字节长度: ' + '22' + ' 当前值: ' ) areaValueLabel = QLabel('0') forceLayout.addWidget(areaMessLabel) forceLayout.addWidget(areaValueLabel) if force: areaLineEdit = QLineEdit('0') forceBtn = forceButton(areaLineEdit) forceBtn.clicked.connect(self.forceValues) forceLayout.addWidget(areaLineEdit) forceLayout.addWidget(forceBtn) return forceLayout def forceValues(self): sender = self.sender() print(sender.valueEdit.text()) class AreaTabWidget(QTabWidget): def __init__(self, deviceWidget): super().__init__() self.deviceWidget = deviceWidget self.initUI() def initUI(self): self.areaWidgetmanage = AreaWidgetManage() self.deviceName = self.deviceWidget.deviceName # 创建一个 QTabWidget 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.setCornerWidget(self.addAreaButton) self.addAreaButton.clicked.connect(self.addAreaTab) 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) 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() layout = QHBoxLayout() addButton = QPushButton('添加区域') 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() areaWidget = AreaWidget(self, areaWidgetManage = self.areaWidgetmanage) self.addTab(areaWidget, '通道' + str(tabIndex + 1)) self.setCurrentIndex(tabIndex) self.tabBar().setHidden(False) else: tabIndex = self.count() areaWidget = AreaWidget(self, settingValue, areaWidgetManage = self.areaWidgetmanage) 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, areaWidgetManage = None): super().__init__() self.areaTabWidget = areaTabWidget self.settingValue = settingValue self.areaWidgetManage = areaWidgetManage self.initUI() def initUI(self): self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.mainLayout = QHBoxLayout() self.leftLayout = QGridLayout() self.rightLayout = QGridLayout() self.dataTypeLabel = QLabel('数据类型:') # self.dataTypeLabel.setFixedSize(90, 27) self.dataTypeCombox = QComboBox() self.dataTypeCombox.addItems(['AI', 'AO', 'DI', 'DO']) self.dataTypeCombox.setObjectName('dataTypeCombox') # self.dataTypeCombox.setFixedSize(90, 27) self.dataOrderLabel = QLabel('数据格式:') # self.dataOrderLabel.setFixedSize(90, 27) self.orderCombox = QComboBox() self.orderCombox.addItems(['不转换', '字节转换', '字转换', '字内转换']) # self.orderCombox.setFixedSize(90, 27) self.byteLineLabel = QLabel('字节长度:') # 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.clicked.connect(self.addAreaWidget) self.obBtnValue = True self.delAreaBtn = QPushButton('删除') # self.delAreaBtn.setFixedSize(90, 27) self.delAreaBtn.clicked.connect(self.removeAreaTab) self.leftLayout.addWidget(self.dataTypeLabel, 0, 0, 1, 1) self.leftLayout.addWidget(self.dataTypeCombox, 0, 1, 1, 1) self.leftLayout.addWidget(self.dataOrderLabel,1, 0, 1, 1 ) self.leftLayout.addWidget(self.orderCombox,1, 1, 1, 1 ) self.leftLayout.addWidget(self.byteLineLabel,2, 0, 1, 1 ) self.leftLayout.addWidget(self.byteLineEdit,2, 1, 1, 1 ) self.leftLayout.addWidget(self.okBtn, 3, 0, 1, 1) self.leftLayout.addWidget(self.delAreaBtn, 3, 1, 1, 1) self.rightWidget = ButtonLayout() # self.rightLayout.addWidget(self.rightWidget) line = QFrame() line.setFrameShape(QFrame.VLine) line.setLineWidth(2) self.mainLayout.addLayout(self.leftLayout, 1) self.mainLayout.addWidget(line) self.mainLayout.addWidget(self.rightWidget, 9) self.mainLayout.setSpacing(20) # self.deviceWidgetManage.addArea(mainLayout=mainLayout, leftLayoutWidget=leftLayoutWidgets) self.setLayout(self.mainLayout) if self.settingValue is not None: self.addAreaWidget() self.settingValue = None def removeAreaTab(self): # 获取 QTabWidget 并从中删除标签页 deviceName = self.areaTabWidget.deviceName index = self.areaTabWidget.currentIndex() tabCount = self.areaTabWidget.count() # alldevices = DevicesManange.getAllDevice() # for device in alldevices: # if deviceName in device: # areas = device[3] # if areas is not None: # areas = json.loads(areas) # if index >= len(areas): # self.areaTabWidget.removeTab(index) # return if index != -1: self.areaTabWidget.removeTab(index) Device.delAreas(deviceName, index) # self.mainwindow.devicesManange.getDevice(deviceName).delArea(index, type) # self.mainwindow.devicesManange.recalculateAddress() if tabCount == 1: self.areaTabWidget.initWidget() def addAreaWidget(self): curIndex = self.areaTabWidget.currentIndex() #获取左侧配置布局的参数 areaWidgets = [] 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'^\d+$') match = pattern.match(byteLineEdit) if not match: QMessageBox.warning(self, '提示', '请输入数字。') return else: #设置点击确定后无法编辑,点击编辑后才能编辑 if self.obBtnValue: self.okBtn.setText('编辑') self.dataTypeCombox.setEnabled(False ) self.orderCombox.setEnabled(False ) self.byteLineEdit.setEnabled(False ) self.obBtnValue = False else: self.okBtn.setText('确定') self.dataTypeCombox.setEnabled(True ) self.orderCombox.setEnabled(True ) self.byteLineEdit.setEnabled(True ) self.obBtnValue = True return #删除布局内容 if self.settingValue is None: self.areaWidgetManage.delareaWidget(curIndex) while areaLayout.count(): items = areaLayout.takeAt(0) if isinstance(items, QSpacerItem): areaLayout.removeItem(items) if isinstance(items, QHBoxLayout): while items.count(): item = items.takeAt(0) widget = item.widget() print(widget) if widget: widget.setParent(None) widget.deleteLater() items.deleteLater() # #添加布局 # if dataType in ['AI', 'AO']: # if '主站' in deviceName and dataType == 'AI' or ('从站' in deviceName and dataType == 'AO'): # buttonLayout = ButtonLayout(index = 1, dataType = dataType, byteLineEdit = byteLineEdit, devicetype = '主站AI') # areaLayout.addLayout(buttonLayout, 0, 0) # areaLayout.addItem(self.horizontalSpacer, 0, 1) # areaLayout.addItem(self.verticalSpacer, 1, 0) # areaWidgets.append([buttonLayout.areaLabe2]) # elif '主站' in deviceName and dataType == 'AO' or ('从站' in deviceName and dataType == 'AI'): # buttonLayout = ButtonLayout(index = 0, dataType = dataType, byteLineEdit = byteLineEdit, devicetype = '主站AO' ) # areaLayout.addLayout(buttonLayout, 0, 0) # areaLayout.addItem(self.horizontalSpacer, 0, 4) # areaLayout.addItem(self.verticalSpacer, 1, 0) # areaLineEdit = buttonLayout.areaLineEdit # buttonLayout.editbtn.clicked.connect(lambda: self.wirteValue(areaLineEdit, dataType='主站AO')) # areaWidgets.append([buttonLayout.areaLabe2, areaLineEdit,buttonLayout.editbtn]) # self.areaWidgetManage.addWidgets(areaWidgets) # else: # channelNumber = int(byteLineEdit) * 8 # if '主站' in deviceName and dataType == 'DI' or ( # '从站' in deviceName and dataType == 'DO'): # for i in range(int(channelNumber)): # buttonLayout = ButtonLayout(index = i + 1, dataType = dataType, byteLineEdit = byteLineEdit, devicetype = '主站DI' ) # type: ignore # if i % 2 == 0: # areaLayout.addLayout(buttonLayout, i // 2, i % 2) # else: # areaLayout.addLayout(buttonLayout, i // 2, i % 2 + 1 ) # areaWidgets.append([buttonLayout.areaLabe2]) # areaLayout.addItem(self.verticalSpacer, int(channelNumber) // 2 + 1, 0) # self.areaWidgetManage.addWidgets(areaWidgets) # if '主站' in deviceName and dataType == 'DO' or ( # '从站' in deviceName and dataType == 'DI'): # for i in range(int(channelNumber)): # buttonLayout = ButtonLayout(index = i + 1, dataType = dataType, byteLineEdit = byteLineEdit, devicetype = '主站DO' ) # type: ignore # if i % 2 == 0: # areaLayout.addLayout(buttonLayout, i // 2, i % 2) # areaLineEdit = buttonLayout.areaLineEdit # buttonLayout.editbtn.clicked.connect(partial(self.wirteValue, areaLineEdit, '主站DO')) # else: # areaLayout.addLayout(buttonLayout, i // 2, i % 2 + 1 ) # areaLineEdit = buttonLayout.areaLineEdit # buttonLayout.editbtn.clicked.connect(partial(self.wirteValue, areaLineEdit, '主站DO')) # areaWidgets.append([buttonLayout.areaLabe2, areaLineEdit,buttonLayout.editbtn]) # areaLayout.addItem(self.verticalSpacer, int(channelNumber) // 2 + 1, 0) # self.areaWidgetManage.addWidgets(areaWidgets) # index = curIndex + 1 # areaId = DevicesManange.getAreaID(deviceName) # if self.settingValue is not None: # return # elif areaId is not None and index in areaId: # DevicesManange.updataAreas(dataType, order, byteLineEdit, deviceName, index) # else: # DevicesManange.addAreas(dataType, order, byteLineEdit, deviceName) # if areaId is not None and index in areaId: # # if loacl: # # del self.widgetList[index - 1] # if init: # return # DevicesManange.updataAreas(dataType, order, byteLineEdit, deviceName, index) # self.mainwindow.devicesManange.getDevice(deviceName).editArea(index = index - 1, type = dataType, order = order, bytes = int(byteLineEdit)) # self.mainwindow.devicesManange.recalculateAddress() # self.mainwindow.readVarTimer.start(500) # else: # DevicesManange.addAreas(dataType, order, byteLineEdit, deviceName) # self.mainwindow.devicesManange.getDevice(deviceName).addArea(type = dataType, bytes = int(byteLineEdit), order = order, nums = 1) # self.mainwindow.devicesManange.recalculateAddress() # self.mainwindow.readVarTimer.start(500) def dataTypeTranslate(self, order): self.dataTypeDict = {'不转换': 'ABCD', '字节转换': 'DCBA', '字转换': 'CDAB', '字内转换': 'BADC'} return self.dataTypeDict[order] def wirteValue(self, editbtn, dataType = None): #判断输入值是否为数字 if dataType == '主站AO': editbtnText = editbtn.text() print(editbtn, editbtnText) pattern = re.compile(r'^\d+(\.\d+)?$') match = pattern.match(editbtnText) if not match: QMessageBox.warning(self, '提示', '请输入数字。') return #判断输入值是否为0和1 elif dataType == '主站DO': editbtnText = editbtn.text() print(editbtn, editbtnText, 'sssss') pattern = re.compile(r'^[01]+$') match = pattern.match(editbtnText) if not match: QMessageBox.warning(self, '提示', '请输入0或1。') return areaWidgets = self.areaWidgetManage.getAllWidgets() valueList = [] didoValueList = [] if areaWidgets: for areaWidget in areaWidgets: if editbtn in areaWidget: areaWidget[0].setText(areaWidget[1].text()) if isinstance(areaWidget[1], QLineEdit): didoValueList.append(float(areaWidget[1].text())) print(didoValueList) if didoValueList: valueList.append(didoValueList) didoValueList = [] # self.mainwindow.devicesManange.writeAreas(deviceName = deviceName, values = valueList) # valueList = [] # didoValueList = [] # if len(self.widgetList) > 0: # for widgetLists in self.widgetList: # for widgetList in widgetLists: # if editBtn in widgetList: # widgetList[0].setText(widgetList[1].text()) # if isinstance(widgetList[1], QLineEdit): # dataType = widgetList[-1].text()[0:2] # # if dataType in ['DI', "DO"]: # didoValueList.append(float(widgetList[1].text())) # if didoValueList: # valueList.append(didoValueList) # didoValueList = [] # self.mainwindow.devicesManange.writeAreas(deviceName = deviceName, values = valueList) def readValue(self): deviceName = self.mainwindow.devicesManange.getDeviceName(self) curIndex = -1 areaIndex = self.areaTabWidget.currentIndex() if len(self.widgetList) > 0: inputIndex = 0 for index, widgetLists in enumerate(self.widgetList): #获取所有区域的所有的widgetlist for widgetList in widgetLists: #获取单个widgetlist if isinstance(widgetList[1], QLineEdit): pass else: # areaWidgets.append(widgetList) if areaIndex == index: curIndex = inputIndex inputIndex += 1 break if curIndex == -1: return else: device = self.mainwindow.devicesManange.getDevice(deviceName) values = device.getAreaValues(curIndex) areaWidgets = self.widgetList[areaIndex] for value, widgets in zip(values, areaWidgets): widgets[0].setText(str(value)) if __name__ == '__main__': app = QApplication(sys.argv) window = AreaTabWidget() window.show() sys.exit(app.exec_())