import sys import json import collections import time from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QMdiArea, QAction, QInputDialog, QDialog, QFormLayout, QLineEdit, \ QMdiSubWindow, QDialogButtonBox, QWidget, QComboBox, QTabBar, QTabWidget, QGridLayout, QLabel, QPushButton, QSpacerItem, QSizePolicy, QHBoxLayout, QTableWidget, QScrollArea from PyQt5 import QtCore from PyQt5.QtGui import QPixmap, QIcon from UI.DeviceWidget import DeviceDialog from UI.AreaSettingWidget import AreaSettingWidget from UI.DelAreaWidget import DelAreaWidget from model.ProjectModel.DeviceManage import DevicesManange, Device from protocol.ModBus.ModBusThread import MyThread from utils.DBModels.BaseModel import * from utils.DBModels.DeviceModels import DeviceDB from model.ClientModel.Client import Client class CommonHelper: def __init__(self): pass @staticmethod def readQss(style): with open(style,"r") as f: return f.read() class MainWindow(QMainWindow): def __init__(self): super().__init__() self.subWindows = [] #存储设备widget self.nowValue = [] #储存当前值 self.areaLabel = [] #存储通道信息文本 self.areaDict = {} self.widgetList= [] self.initUI() self.initAreaWidget() def initUI(self): self.toolbar = QToolBar() self.addToolBar(self.toolbar) # self.setWindowState(self.windowState() | QtCore.Qt.WindowMaximized) self.addDiviceBtn = QAction("添加设备", self) self.addDiviceBtn.setObjectName("addDiviceBtn") self.addDiviceBtn.triggered.connect(self.createDeciveWidget) self.startProtocolBtn = QAction("开始通讯", self) self.startProtocolBtn.setObjectName("startProtocolBtn") self.startProtocolBtn.triggered.connect(self.startProtocol) self.loadProjectBtn = QAction('导入工程', self) self.loadProjectBtn.setObjectName("loadProjectBtn") self.loadProjectBtn.triggered.connect(self.loadProject) self.toolbar.addAction(self.addDiviceBtn) self.toolbar.addAction(self.loadProjectBtn) self.toolbar.addAction(self.startProtocolBtn) self.mdi_area = QMdiArea() # self.scrollArea = QScrollArea() # self.scrollArea.setWidget(self.mdi_area) self.setCentralWidget(self.mdi_area) self.setWindowIcon(QIcon('Static/zhjt.ico')) # self.mdi_area.setViewMode(QMdiArea.TabbedView) # self.mdi_area.setTabsClosable(False) # self.mdi_area.setTabsMovable(True) self.setWindowTitle("PROFIBUS") self.setGeometry(1000, 500, 800, 600) def deviceWidget(self, windowTitle): sub_window = AreaQMdiSubWindow(self)# 创建一个子窗口 sub_window.setObjectName('sub_window') areaLayout1 = QGridLayout() areaLayout2 = QGridLayout() horizontalLayout = QHBoxLayout() horizontalLayout.setObjectName("horizontalLayout") # tableWidget = QTableWidget() widget = QWidget() widget.setLayout(areaLayout1) widgetArea = QWidget() widgetArea.setLayout(areaLayout2) newbtn = QPushButton('添加通道') delbth = QPushButton('删除通道') self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) horizontalLayout.addWidget(newbtn) horizontalLayout.addItem(self.horizontalSpacer) # horizontalLayout.addWidget(delbth) newbtn.clicked.connect(lambda: self.newAreaWidget(sub_window)) delbth.clicked.connect(lambda: self.delAreaWidget(sub_window)) areaLayout1.addLayout(horizontalLayout, 0, 0, 1, 1) areaLayout1.addWidget(widgetArea, 1, 0, 1, 1) areaLayout1.addItem(self.verticalSpacer) scroll_widget = QScrollArea() scroll_widget.setWidgetResizable(True) scroll_widget.setWidget(widget) sub_window.setWindowTitle(windowTitle) sub_window.setGeometry(0, 0, 600, 500) sub_window.setWidget(scroll_widget) sub_window.setWindowIcon(QIcon('Static/zhjt.ico')) self.mdi_area.addSubWindow(sub_window) # 将子窗口添加到MDI区域 # self.mdi_area.subWindowActivated.connect(self.adjustMdiAreaSize) sub_window.show() self.subWindows.append(sub_window) return sub_window def loadProject(self): pass def initAreaWidget(self): alldevices = DevicesManange().getAllDevice() for devices in alldevices: layout = self.deviceWidget(devices[0]).widget().widget().layout().itemAt(1).widget().layout() areas = devices[3] number = 0 masterSlaveModel = devices[2] deviceName = devices[0] if areas is not None: areas = json.loads(areas) for area in areas: varType = area["type"] channelNums = area["nums"] channelBytes = area["bytes"] areaID = area['id'] if masterSlaveModel == '主站': self.addAreaWidget(deviceName, number, channelNums, channelBytes, varType, layout, areaID) else: self.addAreaWidget(deviceName, number, channelNums, channelBytes, varType, layout, areaID) number = number + int(channelNums) self.nowValue.append(self.areaDict) def createDeciveWidget(self): dialog = DeviceDialog() if dialog.exec_() == QDialog.Accepted: deviceName, proType, masterSlaveModel, pvUpperLimit, pvLowerLimit, pvUnit = dialog.getParameters() windowTitle = deviceName + ' ' + proType + masterSlaveModel + ' ' + pvLowerLimit + '-' + pvUpperLimit + pvUnit DeviceDB().addDevice(deviceName = windowTitle, proType = proType, masterSlaveModel = masterSlaveModel, pvUpperLimit=pvUpperLimit, pvLowerLimit=pvLowerLimit, pvUnit=pvUnit) else: return self.deviceWidget(windowTitle) def newAreaWidget(self, sub_window): deviceName = sub_window.windowTitle() dialog = AreaSettingWidget() if dialog.exec_() == QDialog.Accepted: varType, channelNums, channelBytes = dialog.getParameters() number = DevicesManange.getChannelLength(deviceName) Device().addAreas(varType, channelNums, channelBytes, deviceName) areaId = Device().getAreaID(deviceName)[-1] else: return layout = sub_window.widget().widget().layout().itemAt(1).widget().layout() #获取sub_window的widgetArea的areaLayout2 self.addAreaWidget(deviceName, number, channelNums, channelBytes, varType, layout, areaId) number += int(channelNums) def addAreaWidget(self,deviceNames, numbers, channelNums, channelBytes , varTypes, layouts ,ID): deviceName = deviceNames number = numbers channelNum = channelNums channelByte = channelBytes varType = varTypes layout = layouts ID = ID widgetList = [] for i in range(int(channelNum)): if (i + number) % 2 == 0: areaLabel = QLabel(varType + str(i + 1 ) + ": " + channelByte + 'Byte' ) areaLabel2 =QLabel('0') areaLineEdit = QLineEdit('0') editbtn = QPushButton('强制') order = QComboBox() order.addItems(['不转换', '字节转换', '字转换', '字内转换']) layout.addWidget(areaLabel, (i + number)//2, (i + number) % 2) layout.addWidget(areaLabel2, (i + number)//2, (i + number) % 2 + 1 ) layout.addWidget(areaLineEdit, (i + number)//2, (i + number) % 2 + 2 ) layout.addWidget(order, (i + number)//2, (i + number) % 2 + 3) layout.addWidget(editbtn, (i + number) // 2, (i + number) % 2 + 4) editbtn.clicked.connect(lambda checked, btn=editbtn: self.forceEdit(btn)) widgetList.append([layout, ID, editbtn, areaLabel, areaLabel2, areaLineEdit, order]) else: areaLabel = QLabel(varType + str(i + 1) + ": " + channelByte + 'Byte') areaLabel2 = QLabel('0') areaLineEdit = QLineEdit('0') editbtn = QPushButton('强制') order = QComboBox() order.addItems(['不转换', '字节转换', '字转换', '字内转换']) layout.addWidget(areaLabel, (i + number) // 2, (i + number) % 2 + 4) layout.addWidget(areaLabel2, (i + number) // 2, (i + number) % 2 + 6) layout.addWidget(areaLineEdit, (i + number) // 2, (i + number) % 2 + 6) layout.addWidget(order, (i + number)//2, (i + number) % 2 + 7) layout.addWidget(editbtn, (i + number) // 2, (i + number) % 2 + 8) editbtn.clicked.connect(lambda checked, btn=editbtn: self.forceEdit(btn)) widgetList.append([layout, ID, editbtn, areaLabel, areaLabel2, areaLineEdit, order]) if not self.areaDict.get(deviceName): self.areaDict[deviceName] = [widgetList] else: self.areaDict[deviceName].append(widgetList) def delAreaWidget(self, subWindow): subwindow = subWindow deviceName = subwindow.windowTitle() areaLayout = subwindow.widget().widget().layout().itemAt(1).widget().layout() if self.nowValue: deviceName = subwindow.windowTitle() delAreaWidget = DelAreaWidget(deviceName) if delAreaWidget.exec_() == QDialog.Accepted: rowAndColumn = delAreaWidget.getDelAreaRowAndColunm() rowAndColumn.reverse() if rowAndColumn == []: return else: for areaId in rowAndColumn: for devicelist in self.nowValue: areas = devicelist[deviceName][:] area = areas[areaId - 1] for are in area: for widget in range(2, 6): areaLayout.removeWidget(are[widget]) are[widget].deleteLater() devicelist[deviceName].remove(area) Device().delAreas(deviceName,rowAndColumn) # self.updateLayout(areaLayout) else: return else: return def updateLayout(self, areaLayout): for devicelist in self.nowValue: for key in devicelist: areas = devicelist[key] print(areas,'vvvvvv') for area in areas: for widgets in area: for widget in range(2, 6): areaLayout.removeWidget(widgets[widget]) widgets[widget].deleteLater() for devicelist in self.nowValue: for key in devicelist: areas = devicelist[key] i = 0 for area in areas: if i // 2 == 0: pass def forceEdit(self, btn): forceValue = [] for devicelist in self.nowValue: for key in devicelist: areas = devicelist[key] print(areas,'vvvvvv') for area in areas: for widgets in area: if btn in widgets: widgets[4].setText(widgets[5].text()) order = self.dataTypeTranslate(widgets[6].currentText()) print(order) def dataTypeTranslate(self, order): self.dataTypeDict = {'不转换': 'ABCD', '字节转换': 'DCBA', '字转换': 'CDAB', '字内转换': 'BADC'} return self.dataTypeDict[order] # for item in self.nowValue: # if btn in item: # item[4].setText(item[5].text()) def writeValue(self): for deviceNames in self.subWindows: deviceName = deviceNames.windowTitle() areas = [[1,2,3,4,5],[2,3,4,5]] for area in areas: pass def startProtocol(self): self.writeValue() for i in range(len(self.nowValue)): a.append(i) for i in a : for j in self.nowValue: j[5].setText(str(i)) print(a) class AreaQMdiSubWindow(QMdiSubWindow): def __init__(self, parentWindow): super().__init__() self.parentWindow = parentWindow def closeEvent(self, event): print(self.parentWindow.subWindows) self.parentWindow.subWindows.remove(self) print(self.parentWindow.subWindows) DeviceDB.deleteDevice(deviceName = self.windowTitle()) if __name__ == '__main__': app = QApplication(sys.argv) Client.initDB() window = MainWindow() window.show() sys.exit(app.exec_())