import json import os import uuid import base64 from PyQt6 import * from PyQt6.QtCore import * from PyQt6.QtGui import * from PyQt6.QtWidgets import * from ui.Ui_deviceForm import Ui_deviceForm from createDeviceDlg import CreateDeviceDlg from show_editor import CodeDialog from interfaceSession.interfaceManager import interfaceManager from instructionModel.instructionManager import instructionManager from deviceModel.deviceManager import deviceManager from devmodelModel.devModelManager import devModelManager from taskModel.taskActuatorManager import taskActuatorManager from devGroupModel.devGroupManager import devGroupManager from common import common from common import DragDropInfo from common import AlignDelegate from common import AlignNoDelegate from common import QxStandardItem class QxProgressStandardItem(QStandardItem): def __init__(self, text='', parent=None): self.obj = parent super().__init__(text) def updateProgress(self, instruction_id, value, maxValue): obj = self.data(Qt.ItemDataRole.UserRole) if obj is not None and isinstance(obj, dict): if str(instruction_id) == str(obj.get('instruction_id')): self.obj.instructionModelBlockSignals = True self.setData({'value': value, 'maximum': maxValue, 'instruction_id': obj.get('instruction_id'), 'name':obj.get('name')}, Qt.ItemDataRole.UserRole) self.obj.instructionModelBlockSignals = False class ProgressBarDelegate(QStyledItemDelegate): def paint(self, painter, option, index): if index.column() == 5: # 仅对第二列添加进度条 data = index.data(Qt.ItemDataRole.UserRole) # 获取进度条数据 if data is not None and isinstance(data, dict): value = data.get('value', -9999) maximum = data.get('maximum', -9999) progress_rect = option.rect # 进度条的矩形边界 progress_width = int((value / maximum) * progress_rect.width()) # 计算进度条的宽度 progress_rect.adjust(2, 2, -2, -2) # 绘制进度条背景 painter.fillRect(progress_rect, QColor("#F8FAFF")) # 绘制实际数值文本 text = f"{value}/{maximum}" text_rect = QRect(option.rect) # text_rect.adjust(0, 0, -1, 0) # 调整文本矩形边界 # 修改字体和颜色 # font = QFont("Arial", 10, QFont.Weight.Bold) # 创建字体对象 # painter.setFont(font) # 设置字体 pen = painter.pen() pen.setColor(Qt.GlobalColor.black) # 设置画笔颜色为红色 painter.setPen(pen) # 绘制实际进度 progress_rect.setWidth(progress_width) if value == -1 and maximum == -1: return if value >=0 and maximum >= 1 : painter.fillRect(progress_rect, QColor("#007EFF")) painter.drawText(text_rect, Qt.AlignmentFlag.AlignCenter, text) else: super().paint(painter, option, index) class DeviceForm(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_deviceForm() self.ui.setupUi(self) self.deviceModel = QStandardItemModel() self.propertyModel = QStandardItemModel() self.devGroupModel = QStandardItemModel() self.interfaceModel = QStandardItemModel() self.devInstructionModel = QStandardItemModel() self.createDevDlg = CreateDeviceDlg() self.codeDialog = CodeDialog("脚本编辑") self.interfaceCombModel = QStandardItemModel() self.supportedTypes = instructionManager.getSupportedType() self.devmodelProperty = {} self.interfaceModelSignalsBlock = False self.instructionModelBlockSignals = False self.interfaceTypeNames = [] self.selectedDeviceId = None self.topWidget = None self.selectedDeviceModelId = None self.devGroupModelBlockSignals = False self.current_groupId = None self.interfaceTypes = [] self.confInterfaces = [] self.realInterfaces = {} self.setTableViewModel() self.createDevDlg.editFinished.connect(self.editDeviceFinished) self.createDevDlg.createFinished.connect(self.createDeviceFinished) self.ui.tableViewDevice.doubleClicked.connect(self.editDevice) self.ui.tableViewDevCmd.doubleClicked.connect(self.handleDevCmdDoubleClicked) self.ui.tableViewDevCmd.selectionModel().selectionChanged.connect(self.handleDevCmdSelection) self.ui.tableViewDevice.selectionModel().selectionChanged.connect(self.handleDeviceSelection) self.ui.tableViewDevGroup.selectionModel().selectionChanged.connect(self.handleDevGroupSelection) self.ui.tableViewDevGroup.dropEvent = self.devGroupDropEvent self.ui.lbDeviceImage.mouseDoubleClickEvent = self.handleImageClick self.propertyModel.itemChanged.connect(self.updateProperty) self.interfaceModel.itemChanged.connect(self.updateProperty) self.devGroupModel.itemChanged.connect(self.updateDevGroup) self.ui.pbCreateDev.clicked.connect(self.showCreateDevDlg) self.ui.pbDeleteDev.clicked.connect(self.deleteDevice) self.ui.pbAddProperty.clicked.connect(self.addProperty) self.ui.pbDeleteProperty.clicked.connect(self.deleteProperty) self.ui.pbEditDev.clicked.connect(self.editDevice) self.ui.pbExportDev.clicked.connect(self.exportDevice) self.ui.pbEditScript.clicked.connect(self.editScript) self.ui.pbStart.clicked.connect(self.startInstruction) self.ui.pbStop.clicked.connect(self.stopInstruction) self.ui.pbCreateDevGroup.clicked.connect(self.createDevGroup) self.ui.pbDeleteDevGroup.clicked.connect(self.deleteDevGroup) self.setSplitterStretchFactor() # self.batchInstallEventFilter() self.batchSetItemDelegate() def showCreateDevDlg(self): if self.current_groupId != None: self.createDevDlg.showCreateDlg(self.current_groupId) def batchSetItemDelegate(self): self.ui.tableViewDevice.verticalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewDevCmd.verticalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewDevice.horizontalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewDevCmd.horizontalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewInterFace.horizontalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewProperty.horizontalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewInterFace.setItemDelegate(AlignDelegate(self.ui.tableViewInterFace)) self.ui.tableViewProperty.setItemDelegate(AlignDelegate(self.ui.tableViewProperty)) self.ui.tableViewDevice.setItemDelegate(AlignNoDelegate(self.ui.tableViewDevice,2)) self.ui.tableViewDevCmd.setItemDelegate(AlignNoDelegate(self.ui.tableViewDevCmd)) self.ui.tableViewDevGroup.setItemDelegate(AlignDelegate(self.ui.tableViewDevGroup)) def devGroupDropEvent(self, event: QDropEvent): if event.source() != self: mime_data = event.mimeData() source_index = mime_data.data('application/x-qabstractitemmodeldatalist') target_index = self.ui.tableViewDevGroup.indexAt(event.position().toPoint()) drag_drop_info = DragDropInfo(source_index, target_index) self.handleGroupDrop(drag_drop_info) event.accept() else: event.ignore() def handleGroupDrop(self, drag_drop_info): target_row = drag_drop_info.target_index.row() if target_row > -1: row_id_index = self.devGroupModel.index(target_row, 0, QModelIndex()) groupId = self.devGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) rows = self.ui.tableViewDevice.selectionModel().selectedRows() for row in rows: row_id_index = self.deviceModel.index(row.row(), 0, QModelIndex()) deviceId = self.deviceModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) param = { "group_id": groupId } result = deviceManager.update(deviceId, param) # deviceManager.createCopy(deviceId, groupId) self.refreshSelect() # def batchInstallEventFilter(self): # self.ui.w1.resizeEvent = self.onResize # self.ui.w2.resizeEvent = self.onResize # self.ui.w3.resizeEvent = self.onResize # def onResize(self, event): # self.setAllColumnWidth() def startInstruction(self): if len(self.ui.tableViewDevice.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevice.selectionModel().selectedRows()[0].row() row_deviceId_index = self.deviceModel.index(row, 0, QModelIndex()) deviceId = self.deviceModel.data(row_deviceId_index, Qt.ItemDataRole.DisplayRole) if len(self.ui.tableViewDevCmd.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevCmd.selectionModel().selectedRows()[0].row() row_instructionId_index = self.devInstructionModel.index(row, 0, QModelIndex()) instructionId = self.devInstructionModel.data(row_instructionId_index, Qt.ItemDataRole.DisplayRole) count = self.interfaceModel.rowCount() interfaceIndex = 0 for i in range(count): row_selected_index = self.interfaceModel.index(i, 4 , QModelIndex()) selected = self.interfaceModel.data(row_selected_index, Qt.ItemDataRole.DisplayRole) if selected == "True": interfaceIndex = i break attr = { "deviceId": deviceId, "param": "", "interfaceIndex": interfaceIndex } taskActuatorManager.startInstruction(instructionId, attr) def stopInstruction(self): if len(self.ui.tableViewDevCmd.selectionModel().selectedRows()) == 1: row = self.ui.tableViewDevCmd.selectionModel().selectedRows()[0].row() row_index = self.devInstructionModel.index(row, 0, QModelIndex()) instructionid = self.devInstructionModel.data(row_index, Qt.ItemDataRole.DisplayRole) taskActuatorManager.stop(instructionid) def findTopLevelParent(self, widget): parent = widget.parent() while parent and not isinstance(parent, QMainWindow): # 顶层窗口是 QMainWindow widget = parent parent = widget.parent() return parent def editScript(self): indexs = self.ui.tableViewDevice.selectionModel().selectedRows() if len(indexs) == 1: if len(self.ui.tableViewDevCmd.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevCmd.selectionModel().selectedRows()[0].row() row_index = self.devInstructionModel.index(row, 0, QModelIndex()) instructionId = self.devInstructionModel.data(row_index, Qt.ItemDataRole.DisplayRole) instruction = instructionManager.getInfo(instructionId) if instruction != None: dataAttr = instruction.get('attr') if dataAttr != None: if dataAttr.get('script') != None: base64_encoded_str = dataAttr.get('script') result = self.codeDialog.showEditDlg(str(base64.b64decode(base64_encoded_str).decode('utf-8'))) if result == "": return script = base64.b64encode(result.encode("utf-8")).decode('utf-8') dataAttr['script'] = script instructionManager.update(instructionId, {"attr": dataAttr}) script = base64.b64encode(result.encode("utf-8")).decode('utf-8') dataAttr['script'] = script instructionManager.update(instructionId, {"attr": dataAttr}) def exportDevice(self): try: filename = "data.zip" packeagePath = filename fname = QFileDialog.getSaveFileName(self, '保存文件', packeagePath, 'JSON files (*.zip)') if fname[0]: packeagePath = fname[0] exportPath = os.path.join(os.path.dirname(__file__),"export") #清空exportPath目录 common.clearDir(exportPath) #创建exportPath目录 common.createDir(exportPath) indexs = self.ui.tableViewDevice.selectionModel().selectedRows() for index in indexs: row = index.row() row_index = self.deviceModel.index(row, 0, QModelIndex()) deviceId = self.deviceModel.data(row_index, Qt.ItemDataRole.DisplayRole) deviceInfo = deviceManager.getOriginalInfo(deviceId) groupInfo = devGroupManager.getInfo(deviceInfo["group_id"]) #判断modelInfo 中的Id 长度是否小于10,如果是则改为uuid newdeviceId = str(uuid.uuid4()) if len(str(deviceId)) < 10: deviceInfo["id"] = newdeviceId if deviceInfo!= None: common.writeJson(os.path.join(os.path.dirname(__file__),"export"),"device", deviceInfo) if groupInfo!= None: common.writeJson(os.path.join(os.path.dirname(__file__),"export"),"device_group", groupInfo) common.writeZip(packeagePath, exportPath) except Exception as e: if self.topWidget == None: self.topWidget = self.findTopLevelParent(self) if self.topWidget != None: self.topWidget.alertDialog(e,"导出文件异常") def handleDevCmdDoubleClicked(self, index): self.startInstruction() def deleteDevice(self): indexs = self.ui.tableViewDevice.selectionModel().selectedRows() if len(indexs)== 1: row = indexs[0].row() row_devName_index = self.deviceModel.index(row, 3, QModelIndex()) devName = self.deviceModel.data(row_devName_index, Qt.ItemDataRole.DisplayRole) if self.topWidget == None: self.topWidget = self.findTopLevelParent(self) if self.topWidget != None: if self.topWidget.removeDialog(devName,"删除设备"): row_devModel_index = self.deviceModel.index(row, 0, QModelIndex()) deviceId = self.deviceModel.data(row_devModel_index, Qt.ItemDataRole.DisplayRole) deviceManager.delete(deviceId) if len(indexs)>1: if self.topWidget == None: self.topWidget = self.findTopLevelParent(self) if self.topWidget != None: #必须这样写,不能写else if self.topWidget.removeDialog(f"{len(indexs)}个设备"): for index in indexs: row = index.row() row_id_index = self.deviceModel.index(row, 0, QModelIndex()) instructionId = self.deviceModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) deviceManager.delete(instructionId) self.refreshSelect() def handleImageClick(self, event): if event.button() == Qt.MouseButton.LeftButton: if len(self.ui.tableViewDevice.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevice.selectionModel().selectedRows()[0].row() row_index = self.deviceModel.index(row, 0, QModelIndex()) deviceId = self.deviceModel.data(row_index, Qt.ItemDataRole.DisplayRole) data = deviceManager.getInfo(deviceId) description = "" extendedProperty = "" interfaceIndex = -1 file_dialog = QFileDialog(self) file_dialog.setWindowTitle('选择图片') file_dialog.setNameFilter('Supported file formats (*.png *.jpg)') # 设置文件过滤器 if file_dialog.exec(): file_path = file_dialog.selectedFiles()[0] pixmap = QPixmap(file_path) self.ui.lbDeviceImage.setPixmap(pixmap) self.ui.lbDeviceImage.setScaledContents(True) self.ui.lbDeviceImage.setAlignment(Qt.AlignmentFlag.AlignCenter) base64_data = common.base64Data(pixmap.toImage()) if 'attr' in data: attr_json_dict = data['attr'] if 'description' in attr_json_dict: description = attr_json_dict['description'] if 'extendedProperty' in attr_json_dict: extendedProperty = attr_json_dict['extendedProperty'] if 'interfaceIndex' in attr_json_dict: interfaceIndex = attr_json_dict['interfaceIndex'] attr = { "description": description, "image": base64_data, "extendedProperty" : extendedProperty, "interfaceIndex" : interfaceIndex } param = { "attr" : attr } result = deviceManager.update(deviceId, param) def editDevice(self): if len(self.ui.tableViewDevice.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevice.selectionModel().selectedRows()[0].row() row_dev_index = self.deviceModel.index(row, 0, QModelIndex()) row_devModel_index = self.deviceModel.index(row, 1, QModelIndex()) deviceId = self.deviceModel.data(row_dev_index, Qt.ItemDataRole.DisplayRole) devModelId = self.deviceModel.data(row_devModel_index, Qt.ItemDataRole.DisplayRole) device = deviceManager.getInfo(deviceId) if device != None: self.createDevDlg.showEditDlg( devModelId, device) def clearChildrenModel(self): self.devInstructionModel.clear() self.propertyModel.clear() self.interfaceModel.clear() self.ui.lbDeviceImage.setText("封面") def setTableViewModel(self): self.ui.tableViewDevGroup.setModel(self.devGroupModel) self.ui.tableViewDevice.setModel(self.deviceModel) self.ui.tableViewDevCmd.setModel(self.devInstructionModel) self.ui.tableViewProperty.setModel(self.propertyModel) self.ui.tableViewInterFace.setModel(self.interfaceModel) # def refreshSelect(self): # selectedRows = self.ui.tableViewDevice.selectionModel().selectedRows() # self.loadDevice() # if len(selectedRows) < 1: # self.ui.tableViewDevice.selectRow(0) # if len(selectedRows)== 1: # row = selectedRows[0].row() # self.ui.tableViewDevice.selectRow(row) def refreshSelect(self): selectedRows = self.ui.tableViewDevGroup.selectionModel().selectedRows() self.loadDevGroup() if len(selectedRows) < 1: self.ui.tableViewDevGroup.selectRow(0) if len(selectedRows) == 1: row = selectedRows[0].row() self.ui.tableViewDevGroup.selectRow(row) # 创建完成 def createDeviceFinished(self): self.loadDevice() if self.deviceModel.rowCount() > 0: self.ui.tableViewDevice.selectRow(self.deviceModel.rowCount()-1) # 编辑完成 def editDeviceFinished(self): if len(self.ui.tableViewDevice.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevice.selectionModel().selectedRows()[0].row() self.loadDevice() if self.deviceModel.rowCount() > 0: self.ui.tableViewDevice.selectRow(row) def updateDevBtnState(self): if len(self.ui.tableViewDevice.selectionModel().selectedRows())== 1: self.ui.pbEditDev.setEnabled(True) else: self.ui.pbEditDev.setEnabled(False) def handleDeviceSelection(self): selectedRows = self.ui.tableViewDevice.selectionModel().selectedRows() if len(selectedRows)== 1: row = selectedRows[0].row() row_deviceId_index = self.deviceModel.index(row, 0, QModelIndex()) row_devModelId_index = self.deviceModel.index(row, 1, QModelIndex()) self.selectedDeviceId = self.deviceModel.data(row_deviceId_index, Qt.ItemDataRole.DisplayRole) self.selectedDevModelId = self.deviceModel.data(row_devModelId_index, Qt.ItemDataRole.DisplayRole) self.loadInterface() self.loadDevModelProperty(row, self.selectedDevModelId) self.loadDevInstruction(self.selectedDevModelId) self.loadDeviceProperty(self.selectedDeviceId) self.updateDevBtnState() def handleDevCmdSelection(self): selectedRows = self.ui.tableViewDevCmd.selectionModel().selectedRows() if len(selectedRows)== 1: row = selectedRows[0].row() row_index = self.devInstructionModel.index(row, 6, QModelIndex()) description = self.devInstructionModel.data(row_index, Qt.ItemDataRole.DisplayRole) if description: self.ui.textEditDescription.setText(description) else: self.ui.textEditDescription.clear() self.updateDevBtnState() # 加载设备 def loadDevice(self): devices = deviceManager.getGroupDevices(self.current_groupId) self.deviceModel.clear() self.ui.textEditDescription.clear() if len(devices) > 0: for device in devices: index = self.deviceModel.rowCount() self.deviceModel.setItem(index, 0, QxStandardItem(str(device["id"]))) self.deviceModel.setItem(index, 1, QxStandardItem(str(device["dev_model_id"]))) self.deviceModel.setItem(index, 2, QxStandardItem(str(index+1))) self.deviceModel.setItem(index, 3, QxStandardItem(device["name"], max_length=15)) devModel = devModelManager.getInfo(device["dev_model_id"]) if devModel != None: self.deviceModel.setItem(index, 4, QxStandardItem(devModel["name"], max_length=8)) self.ui.tableViewDevice.sortByColumn(3, Qt.SortOrder.AscendingOrder) self.batchOperation() # 任务分组选中 def handleDevGroupSelection(self, index): if len(self.ui.tableViewDevGroup.selectionModel().selectedRows()) == 1: row = self.ui.tableViewDevGroup.selectionModel().selectedRows()[0].row() row_id_index = self.devGroupModel.index(row, 0, QModelIndex()) group_id = self.devGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) self.current_groupId = group_id self.loadDevice() self.clearChildrenModel() # 加载队列组 def loadDevGroup(self): self.devGroupModel.clear() self.ui.textEditDescription.clear() groups = devGroupManager.getInfo() self.devGroupModelBlockSignals = True if len(groups) > 0: for group in groups: index = self.devGroupModel.rowCount() self.devGroupModel.setItem(index, 0, QStandardItem(str(group["id"]))) self.devGroupModel.setItem(index, 1, QStandardItem(group["name"])) self.devGroupModelBlockSignals = False self.batchOperation() # 切换接口 def changeInterface(self,index): if len(self.ui.tableViewInterFace.selectionModel().selectedRows())== 1: row = self.ui.tableViewInterFace.selectionModel().selectedRows()[0].row() self.interfaceModel.setItem(row, 2 , QxStandardItem(str(self.sender().currentData()["id"]))) # 更新属性 def updateProperty(self): if self.interfaceModelSignalsBlock == False: self.interfaceModelSignalsBlock = True if len(self.ui.tableViewDevice.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevice.selectionModel().selectedRows()[0].row() row_id_index = self.deviceModel.index(row, 0, QModelIndex()) deviceId = self.deviceModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) interfaceIndex = -1 devinfo = deviceManager.getInfo(deviceId) if devinfo!= None: if 'attr' in devinfo: attr_json_dict = devinfo['attr'] if 'interfaceIndex' in attr_json_dict: interfaceIndex = attr_json_dict['interfaceIndex'] interfaceIds = [] extendedProperty = {} for row in range(self.interfaceModel.rowCount()): index = self.interfaceModel.index(row, 2) interfaceId = self.interfaceModel.data(index) interfaceIds.append(interfaceId) description = "" for row in range(self.propertyModel.rowCount()): if row >= len(self.devmodelProperty): if self.propertyModel.item(row, 0).text() == "设备描述": description = self.propertyModel.item(row, 1).text() else: if self.propertyModel.item(row, 0).text() != "": extendedProperty[self.propertyModel.item(row, 0).text()] = self.propertyModel.item(row, 1).text() image = common.base64Data(self.ui.lbDeviceImage.pixmap().toImage()) attr = { "description": description, "image": image, "extendedProperty" : extendedProperty, "interfaceIndex": interfaceIndex } param = { "id": deviceId, "interface": interfaceIds, "attr": attr } deviceManager.update(deviceId, param) self.interfaceModelSignalsBlock = False # 添加属性 def addProperty(self): if len(self.ui.tableViewDevice.selectionModel().selectedRows())== 1: # 列表末位名称为空不允许创建 if self.propertyModel.rowCount() > 0: lastIndex = self.propertyModel.rowCount() - 1 if self.propertyModel.item(lastIndex, 0).text().strip() == "": self.ui.tableViewProperty.edit(self.propertyModel.index(lastIndex, 0)) return index = self.propertyModel.rowCount() self.propertyModel.appendRow([QxStandardItem(), QxStandardItem()]) self.ui.tableViewProperty.setCurrentIndex(self.propertyModel.index(index, 0) ) self.ui.tableViewProperty.edit(self.propertyModel.index(index, 0)) # 删除属性 def deleteProperty(self): if len(self.ui.tableViewProperty.selectionModel().selectedRows())== 1: row = self.ui.tableViewProperty.selectionModel().selectedRows()[0].row() if row >= len(self.devmodelProperty): if not self.propertyModel.item(row, 0).text() == "设备描述": self.propertyModel.removeRow(row) self.updateProperty() #加载接口 def loadInterface(self): self.interfaceTypeNames = [] self.interfaceTypes = [] supportedType = interfaceManager.getSupportedType() for type in supportedType: self.interfaceTypeNames.append(supportedType[type]) self.interfaceTypes.append(type) self.confInterfaces = interfaceManager.getInfo() self.realInterfaces = {} for i in range (len(self.interfaceTypes)): interfaceType_list = [{"name":"未选择", "id":common.noChooseUuid}] for interface in self.confInterfaces: if interface["type"] == self.interfaceTypes[i]: interfaceType_list.append(interface) self.realInterfaces[self.interfaceTypeNames[i]] = interfaceType_list self.batchOperation() #默认接口选择 def interfaceModelCheckedChanged(self): checked = self.sender().isChecked() if self.interfaceModelSignalsBlock: return if len(self.ui.tableViewDevice.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevice.selectionModel().selectedRows()[0].row() row_index = self.deviceModel.index(row, 0, QModelIndex()) deviceId = self.deviceModel.data(row_index, Qt.ItemDataRole.DisplayRole) data = deviceManager.getInfo(deviceId) index = self.ui.tableViewInterFace.currentIndex() if index.isValid(): self.interfaceModelSignalsBlock = True count = self.interfaceModel.rowCount() for i in range(count): self.interfaceModel.setItem(i, 4 , QxStandardItem("False")) self.interfaceModel.setItem(index.row(), 4 , QxStandardItem("True")) description = "" extendedProperty = "" interfaceIndex = index.row() if 'attr' in data: attr_json_dict = data['attr'] if 'description' in attr_json_dict: description = attr_json_dict['description'] if 'extendedProperty' in attr_json_dict: extendedProperty = attr_json_dict['extendedProperty'] if 'image' in attr_json_dict: image = attr_json_dict['image'] attr = { "description": description, "image": image, "extendedProperty" : extendedProperty, "interfaceIndex" : interfaceIndex } param = { "attr" : attr } result = deviceManager.update(deviceId, param) self.interfaceModelSignalsBlock = False #加载设备属性和接口 def loadDeviceProperty(self, deviceId): if deviceId: device = deviceManager.getInfo(deviceId) if device != None: self.propertyModel.blockSignals(True) interfaceIndex = -1 if "attr" in device: attr_json_dict = device["attr"] description = "" pixmap = QPixmap() if "image" in attr_json_dict and attr_json_dict["image"]: pixmap = common.base64ToPixmap(attr_json_dict["image"]) #设置封面 self.ui.lbDeviceImage.setPixmap(pixmap) self.ui.lbDeviceImage.setScaledContents(True) self.ui.lbDeviceImage.setAlignment(Qt.AlignmentFlag.AlignCenter) if "description" in attr_json_dict: description = attr_json_dict["description"] index = self.propertyModel.rowCount() self.propertyModel.setItem(index, 0, QxStandardItem("设备描述")) self.propertyModel.setItem(index, 1, QxStandardItem(description)) self.setUnEditableStyle(self.propertyModel.item(index, 0)) deviceextendedProperty= {} if "extendedProperty" in attr_json_dict: deviceextendedProperty = attr_json_dict["extendedProperty"] #扩展属性添加 for key in deviceextendedProperty: index = self.propertyModel.rowCount() self.propertyModel.setItem(index, 0, QxStandardItem(key)) self.propertyModel.setItem(index, 1, QxStandardItem(deviceextendedProperty[key])) if "interfaceIndex" in attr_json_dict: interfaceIndex = attr_json_dict["interfaceIndex"] self.propertyModel.blockSignals(False) if "interface" in device: interface_id_list = device["interface"] #阻塞interfaceModel信号 self.interfaceModelSignalsBlock = True if len(interface_id_list) == self.interfaceModel.rowCount(): for index in range(len(interface_id_list)): interfaceId = interface_id_list[index] radio = QRadioButton() radio.setStyleSheet("QRadioButton::indicator {" " subcontrol-origin: padding;" " subcontrol-position: center;" "}") self.interfaceModel.setItem(index, 3 , QxStandardItem()) if index == interfaceIndex: radio.setChecked(True) self.interfaceModel.setItem(index, 4 , QxStandardItem("True")) else: radio.setChecked(False) self.interfaceModel.setItem(index, 4 , QxStandardItem("False")) radio.toggled.connect(self.interfaceModelCheckedChanged) cmb = QComboBox() type = self.interfaceModel.item(index, 1).text() currentIndex = 0 for i in range (len(self.realInterfaces[type])): cmb.addItem(self.realInterfaces[type][i]["name"], self.realInterfaces[type][i]) if interfaceId == self.realInterfaces[type][i]["id"]: currentIndex = i cmb.setCurrentIndex(currentIndex) self.interfaceModel.setItem(index, 2 , QxStandardItem(self.realInterfaces[type][currentIndex]["id"])) cmb.currentIndexChanged.connect(self.changeInterface) self.ui.tableViewInterFace.setIndexWidget(self.interfaceModel.index(index, 3), radio) self.ui.tableViewInterFace.setIndexWidget(self.interfaceModel.index(index, 2), cmb) else: for index in range(self.interfaceModel.rowCount()): self.interfaceModel.setItem(index, 2 , QxStandardItem()) radio = QRadioButton() radio.setStyleSheet("QRadioButton::indicator {" " subcontrol-origin: padding;" " subcontrol-position: center;" "}") self.interfaceModel.setItem(index, 3 , QxStandardItem()) if index == interfaceIndex: radio.setChecked(True) self.interfaceModel.setItem(index, 4 , QxStandardItem("True")) else: radio.setChecked(False) self.interfaceModel.setItem(index, 4 , QxStandardItem("False")) radio.toggled.connect(self.interfaceModelCheckedChanged) cmb = QComboBox() type = self.interfaceModel.item(index, 1).text() currentIndex = 0 for i in range (len(self.realInterfaces[type])): cmb.addItem(self.realInterfaces[type][i]["name"], self.realInterfaces[type][i]) cmb.setCurrentIndex(currentIndex) self.interfaceModel.setItem(index, 2 , QxStandardItem(self.realInterfaces[type][currentIndex]["id"])) cmb.currentIndexChanged.connect(self.changeInterface) self.ui.tableViewInterFace.setIndexWidget(self.interfaceModel.index(index, 3), radio) self.ui.tableViewInterFace.setIndexWidget(self.interfaceModel.index(index, 2), cmb) #解除阻塞 self.interfaceModelSignalsBlock = False self.batchOperation() #加载模型属性 def loadDevModelProperty(self,index, devModelId): if devModelId: devModel = devModelManager.getInfo(devModelId) if devModel != None: #更新扩展属性 if "attr" in devModel: #加载属性参数 attr_json_dict = devModel["attr"] devmodelInterfacetype = {} modelnumber = "" if "modelnumber" in attr_json_dict: modelnumber = attr_json_dict["modelnumber"] self.devmodelProperty= {"设备型号":modelnumber} if "interfaceType" in attr_json_dict: devmodelInterfacetype = attr_json_dict["interfaceType"] if "extendedProperty" in attr_json_dict: self.devmodelProperty.update( attr_json_dict["extendedProperty"] ) #阻塞propertyModel信号 self.propertyModel.blockSignals(True) self.propertyModel.clear() #扩展属性添加 for key in self.devmodelProperty: index = self.propertyModel.rowCount() self.propertyModel.setItem(index, 0, QxStandardItem(key)) self.propertyModel.setItem(index, 1, QxStandardItem(self.devmodelProperty[key])) self.setUnEditableStyle(self.propertyModel.item(index, 0)) self.setUnEditableStyle(self.propertyModel.item(index, 1)) #解除propertyModel阻塞 self.propertyModel.blockSignals(False) #阻塞interFaceTypeModel信号 self.interfaceModel.blockSignals(True) self.interfaceModel.clear() for interFaceType in devmodelInterfacetype: index = self.interfaceModel.rowCount() self.interfaceModel.setItem(index, 0, QxStandardItem(interFaceType)) self.interfaceModel.setItem(index, 1, QxStandardItem(devmodelInterfacetype[interFaceType])) #解除interFaceTypeModel阻塞 self.interfaceModel.blockSignals(False) self.batchOperation() # 加载设备指令 def loadDevInstruction(self,devModelId): instructions = instructionManager.getDevmodelInstructions(devModelId) self.devInstructionModel.clear() for data in instructions: index = self.devInstructionModel.rowCount() self.devInstructionModel.setItem(index, 0, QxStandardItem(str(data["id"]))) self.devInstructionModel.setItem(index, 1, QxStandardItem(str(index+1))) self.devInstructionModel.setItem(index, 2, QxStandardItem(data["name"])) attr = data["attr"] if data["type"] is not None and data["type"] in self.supportedTypes: self.devInstructionModel.setItem(index, 3, QxStandardItem(attr[self.supportedTypes[data["type"]]["digestAttr"]])) else: self.devInstructionModel.setItem(index, 3, QxStandardItem("")) self.devInstructionModel.setItem(index, 4, QxStandardItem(attr["remark"])) progressItem = QxProgressStandardItem('',self) progressItem.setData({'instruction_id': data["id"], 'name': data["name"]}, Qt.ItemDataRole.UserRole) self.devInstructionModel.setItem(index, 5, progressItem) delegate = ProgressBarDelegate() self.ui.tableViewDevCmd.setItemDelegateForColumn(5, delegate) # 为列索引为 1 的项设置自定义委托 taskActuatorManager.updateInstructProgress.connect(progressItem.updateProgress) if "description" not in attr: attr["description"] = "" self.devInstructionModel.setItem(index, 6, QStandardItem(attr["description"])) self.ui.tableViewDevCmd.sortByColumn(2, Qt.SortOrder.AscendingOrder) self.batchOperation() #设置不可编辑样式 def setUnEditableStyle(self, item): item.setEditable(False) def setSplitterStretchFactor(self): self.ui.splitter.setStretchFactor(1, 40) self.ui.splitter.setStretchFactor(2, 60) # 批量操作 def batchOperation(self): self.setAllHorizontalHeaderLabels() self.hideAllColumn() self.setAllColumnWidth() # 批量设置列宽 def setAllColumnWidth(self): try: if self.deviceModel.rowCount() > 0: self.ui.tableViewDevice.horizontalHeader().setSectionResizeMode(3,QHeaderView.ResizeMode.Stretch) self.ui.tableViewDevice.horizontalHeader().setSectionResizeMode(4,QHeaderView.ResizeMode.Stretch) self.ui.tableViewProperty.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch) self.ui.tableViewInterFace.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch) if self.devInstructionModel.rowCount() > 0: self.ui.tableViewDevCmd.horizontalHeader().setSectionResizeMode(2,QHeaderView.ResizeMode.ResizeToContents) self.ui.tableViewDevCmd.horizontalHeader().setSectionResizeMode(3,QHeaderView.ResizeMode.Stretch) self.ui.tableViewDevCmd.horizontalHeader().setSectionResizeMode(4,QHeaderView.ResizeMode.Stretch) self.ui.tableViewDevCmd.horizontalHeader().setSectionResizeMode(5,QHeaderView.ResizeMode.Stretch) if self.devGroupModel.rowCount() > 0: self.ui.tableViewDevGroup.horizontalHeader().setSectionResizeMode(1,QHeaderView.ResizeMode.Stretch) except Exception as e: print(e) def setSplitterStretchFactor(self): self.ui.splitter.setStretchFactor(0, 30) self.ui.splitter.setStretchFactor(1, 30) self.ui.splitter.setStretchFactor(2, 40) # 批量设置标题 def setAllHorizontalHeaderLabels(self): self.devGroupModel.setHorizontalHeaderLabels(["ID","名称"]) self.deviceModel.setHorizontalHeaderLabels(["ID","模型ID","", "名称","模型"]) self.devInstructionModel.setHorizontalHeaderLabels(["ID", "", "名称", "摘要", "备注", "进度", "描述"]) self.propertyModel.setHorizontalHeaderLabels([" 属性", " 值"]) self.interfaceModel.setHorizontalHeaderLabels([" 名称"," 类型", "接口", "默认"]) # 隐藏指定列 def hideAllColumn(self): self.ui.tableViewDevice.setColumnHidden(0, True) self.ui.tableViewDevGroup.setColumnHidden(0, True) self.ui.tableViewDevice.setColumnHidden(1, True) self.ui.tableViewDevice.setColumnHidden(2, True) self.ui.tableViewDevCmd.setColumnHidden(0, True) self.ui.tableViewDevCmd.setColumnHidden(1, True) self.ui.tableViewDevCmd.setColumnHidden(6, True) self.ui.tableViewInterFace.setColumnHidden(4, True) def createDevGroup(self): index = self.devGroupModel.rowCount() self.devGroupModel.appendRow([ QStandardItem(), QStandardItem()]) self.ui.tableViewDevGroup.setCurrentIndex(self.devGroupModel.index(index, 0) ) self.ui.tableViewDevGroup.edit(self.devGroupModel.index(index, 1)) def deleteDevGroup(self): if len(self.ui.tableViewDevGroup.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevGroup.selectionModel().selectedRows()[0].row() row_id_index = self.devGroupModel.index(row, 0, QModelIndex()) groupId = self.devGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) if groupId == common.defaultGroupId: return row_groupName_index = self.devGroupModel.index(row, 1, QModelIndex()) groupName = self.devGroupModel.data(row_groupName_index, Qt.ItemDataRole.DisplayRole) if self.topWidget == None: self.topWidget = self.findTopLevelParent(self) if self.topWidget != None: if self.deviceModel.rowCount() > 0: self.topWidget.alertDialog("分组下存在设备,不能删除分组", "警告") return if self.topWidget.removeDialog(groupName,"删除分组"): result = devGroupManager.delete(groupId) if result == True: self.clearChildrenModel() self.devGroupModel.removeRow(row) def updateDevGroup(self): if len(self.ui.tableViewDevGroup.selectionModel().selectedRows())== 1: row = self.ui.tableViewDevGroup.selectionModel().selectedRows()[0].row() row_id_index = self.devGroupModel.index(row, 0, QModelIndex()) groupId = self.devGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) row_nane_index = self.devGroupModel.index(row, 1, QModelIndex()) groupName = self.devGroupModel.data(row_nane_index, Qt.ItemDataRole.DisplayRole) if groupId == None and groupName.strip() != "": groupId = devGroupManager.create({"name":groupName}) self.devGroupModel.setData(row_id_index, groupId) else: if groupName.strip() != "": devGroupManager.update(groupId, {"name":groupName})