import json import base64 import os import re import uuid from PyQt6 import * from PyQt6.QtCore import * from PyQt6.QtGui import * from PyQt6.QtWidgets import * from insertInstructionDlg import InsertInstructionDlg from insertTaskDlg import InsertTaskDlg from ui.Ui_taskForm import Ui_taskForm from createTaskDlg import CreateTaskDlg from chooseDeviceDlg import ChooseDeviceDlg from interfaceSession.interfaceManager import interfaceManager from instructionModel.instructionManager import instructionManager from taskModel.taskManager import taskManager from deviceModel.deviceManager import deviceManager from devmodelModel.devModelManager import devModelManager from taskGroupModel.taskGroupManager import taskGroupManager from taskInstructionModel.taskInstructionManager import taskInstructionManager from taskModel.taskActuatorManager import taskActuatorManager from devGroupModel.devGroupManager import devGroupManager from show_editor import CodeDialog from logs import log from common import NoWheelComboBox from common import TaskProgressBar from common import DragDropInfo from common import AlignNoDelegate from common import AlignDevDelegate from common import AlignTaskNoDelegate # from common import EventFilter from common import common class QxStandardItem(QStandardItem): def __init__(self, text='', parent=None): self.obj = parent super().__init__(text) def updateProgress(self, taskId, value, maxValue): obj = self.data(Qt.ItemDataRole.UserRole) if obj is not None and isinstance(obj, dict): if str(taskId) == str(obj.get('task_instruction_id')): self.obj.taskModelBlockSignals = True self.setData({'value': value, 'maximum': maxValue, 'task_instruction_id': obj.get('task_instruction_id'), 'name':obj.get('name')}, Qt.ItemDataRole.UserRole) self.obj.taskModelBlockSignals = False class ProgressBarDelegate(QStyledItemDelegate): def paint(self, painter, option, index): if index.column() == 6: # 仅对第二列添加进度条 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 TaskForm(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_taskForm() self.ui.setupUi(self) self.defaultScriptBase64 = "aW1wb3J0IHRpbWUNCg0Kc3RhcnRUaW1lID0gdGltZS50aW1lKCkgDQpjdXJyZW50SW5kZXggPSAwDQpjdXJyZW50U3RhdGUgPSAwDQpkYXRlX2Zvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyINCg0KZGVmIHRvVGltZSh0YXJnZXRfdGltZV9zdHIpOg0KICAgIHRhcmdldF90aW1lID0gdGltZS5ta3RpbWUodGltZS5zdHJwdGltZSh0YXJnZXRfdGltZV9zdHIsIGRhdGVfZm9ybWF0KSkNCiAgICBjdXJyZW50X3RpbWUgPSB0aW1lLnRpbWUoKQ0KICAgICPmm7TmlrDml7bpl7Tov5vluqYNCiAgICB1cGRhdGVUaW1lKHN0YXJ0VGltZSwgY3VycmVudF90aW1lLCB0YXJnZXRfdGltZSkNCiAgICBpZiBjdXJyZW50X3RpbWUgPiB0YXJnZXRfdGltZToNCiAgICAgICAgcmV0dXJuIFRydWUNCiAgICByZXR1cm4gRmFsc2UNCg0KZGVmIHRvRGF5KGRheXMpOiAgDQogICAgdGFyZ2V0X3RpbWUgPSBzdGFydFRpbWUgKyBmbG9hdChkYXlzKSAqIDg2NDAwICAjIOWwhuWkqeaVsOi9rOaNouS4uuenkuW5tuWKoOWIsHN0YXJ0VGltZeS4iiAgDQogICAgY3VycmVudF90aW1lID0gdGltZS50aW1lKCkgIA0KICAgIHVwZGF0ZVRpbWUoc3RhcnRUaW1lLCBjdXJyZW50X3RpbWUsIHRhcmdldF90aW1lKSAgDQogICAgcmV0dXJuIGN1cnJlbnRfdGltZSA+IHRhcmdldF90aW1lICANCg0KZGVmIHRvSG91cihob3Vycyk6ICANCiAgICB0YXJnZXRfdGltZSA9IHN0YXJ0VGltZSArIGZsb2F0KGhvdXJzKSAqIDM2MDAgICMg5bCG5bCP5pe26L2s5o2i5Li656eS5bm25Yqg5Yiwc3RhcnRUaW1l5LiKICANCiAgICBjdXJyZW50X3RpbWUgPSB0aW1lLnRpbWUoKSAgDQogICAgdXBkYXRlVGltZShzdGFydFRpbWUsIGN1cnJlbnRfdGltZSwgdGFyZ2V0X3RpbWUpICANCiAgICByZXR1cm4gY3VycmVudF90aW1lID4gdGFyZ2V0X3RpbWUgIA0KICAgDQpkZWYgdG9NaW51dGUobWludXRlcyk6ICANCiAgICB0YXJnZXRfdGltZSA9IHN0YXJ0VGltZSArIGZsb2F0KG1pbnV0ZXMpICogNjAgICMg5bCG5YiG6ZKf6L2s5o2i5Li656eS5bm25Yqg5Yiwc3RhcnRUaW1l5LiKICANCiAgICBjdXJyZW50X3RpbWUgPSB0aW1lLnRpbWUoKSAgDQogICAgdXBkYXRlVGltZShzdGFydFRpbWUsIGN1cnJlbnRfdGltZSwgdGFyZ2V0X3RpbWUpICANCiAgICByZXR1cm4gY3VycmVudF90aW1lID4gdGFyZ2V0X3RpbWUgIA0KICANCmRlZiB0b1NlY29uZChzZWNvbmRzKTogIA0KICAgIHRhcmdldF90aW1lID0gc3RhcnRUaW1lICsgZmxvYXQoc2Vjb25kcykgICMg5bCG56eS55u05o6l5Yqg5Yiwc3RhcnRUaW1l5LiKICANCiAgICBjdXJyZW50X3RpbWUgPSB0aW1lLnRpbWUoKSAgDQogICAgdXBkYXRlVGltZShzdGFydFRpbWUsIGN1cnJlbnRfdGltZSwgdGFyZ2V0X3RpbWUpICANCiAgICByZXR1cm4gY3VycmVudF90aW1lID4gdGFyZ2V0X3RpbWUgIA0KICAgIA0KZGVmIGNhbGxCYWNrKGNvbXBsZXRlZF9zdGF0ZSk6DQogICAgZ2xvYmFsIGN1cnJlbnRJbmRleCwgY3VycmVudFN0YXRlDQogICAgY3VycmVudFN0YXRlID0gY29tcGxldGVkX3N0YXRlICMwOiDov5vlhaXku7vliqE7ICAx77ya5omn6KGM5Lu75YqhOyAgMu+8muaJp+ihjOaMh+S7pDsgIDPvvJrnrYnlvoXmjIfku6TplIHop6PpmaQ7ICA077yaIOaMh+S7pOW+queOrw0KICAgICNsb2coZiJjb21wbGV0ZWRfc3RhdGUgPXtjb21wbGV0ZWRfc3RhdGV9ICwgY3VycmVudEluZGV4ID0ge2N1cnJlbnRJbmRleH0sIHRhc2tQcm9jZXNzRmxhZyA9IHt0YXNrUHJvY2Vzc0ZsYWd9IikNCiAgICBpZiBsb29wID09IDA6DQogICAgICAgIGlmIGN1cnJlbnRJbmRleCA9PSAwOiAgICAgICAgICAgI+mmluasoei/m+WFpemYn+WIlw0KICAgICAgICAgICAgbG9nKGYiSW5pdGlhbGl6aW5nIGhlcmUuIikNCiAgICAgICAgICAgIGN1cnJlbnRJbmRleCArPSAxDQogICAgICAgICAgICB0aW1lLnNsZWVwKDEpDQogICAgICAgICAgICANCiAgICAgICAgbG9nKGYiY29tcGxldGVkX3N0YXRlID17Y29tcGxldGVkX3N0YXRlfSIpDQogICAgICAgICMg5Lu75Yqh5b6q546v5qyh5pWwPTAg5pe25Y+v55SoDQogICAgICAgICNpZiB0b1RpbWUoIjIwMjQtMDEtMDUgMjA6MDA6MDAiKToNCiAgICAgICAgIyAgICBmaW5pc2goKQ0KICAgICAgICAjaWYgdG9EYXkoMSk6DQogICAgICAgICMgICAgZmluaXNoKCkgICAgDQogICAgICAgICNpZiB0b0hvdXIoMSk6DQogICAgICAgICMgICAgZmluaXNoKCkNCiAgICAgICAgaWYgdG9NaW51dGUoMSk6DQogICAgICAgICAgICBmaW5pc2goKQ0KICAgICAgICAjaWYgdG9TZWNvbmQoMzApOg0KICAgICAgICAjICAgIGZpbmlzaCgpDQogICAgZWxzZTogDQogICAgICAgIG1hdGNoIGNvbXBsZXRlZF9zdGF0ZToNCiAgICAgICAgICAgIGNhc2UgMDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICPov5vlhaXpmJ/liJcNCiAgICAgICAgICAgICAgICBpZiBjdXJyZW50SW5kZXggPT0gMDogICAgICAgICAgICPpppbmrKHov5vlhaXpmJ/liJcNCiAgICAgICAgICAgICAgICAgICAgbG9nKGYiSW5pdGlhbGl6aW5nIGhlcmUuIikNCiAgICAgICAgICAgICAgICAgICAgdGltZS5zbGVlcCg1KQ0KICAgICAgICAgICAgICAgIGxvZyhmImNvbXBsZXRlZF9zdGF0ZSA9e2NvbXBsZXRlZF9zdGF0ZX0iKQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgY2FzZSAxOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI+aJp+ihjOmYn+WIlw0KICAgICAgICAgICAgICAgIGxvZyhmImNvbXBsZXRlZF9zdGF0ZSA9e2NvbXBsZXRlZF9zdGF0ZX0iKQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgY2FzZSAyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI+aJp+ihjOaMh+S7pA0KICAgICAgICAgICAgICAgIGxvZyhmImNvbXBsZXRlZF9zdGF0ZSA9e2NvbXBsZXRlZF9zdGF0ZX0iKQ0KDQpkZWYgbmV4dCgpOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAj6Zif5YiX5Y2V5qyh5omn6KGM5a6M5q+V5ZCO6LCD55SoDQogICAgZ2xvYmFsIGN1cnJlbnRJbmRleCwgY3VycmVudFN0YXRlDQogICAgY3VycmVudEluZGV4ID0gY3VycmVudEluZGV4ICsgMQ0KICAgIGlmIGN1cnJlbnRJbmRleCA+PSBsb29wOiAgICAgICAgICAgICAgICAgICAgI+atpOaXtuS7u+WKoeaJp+ihjOWujOavlQ0KICAgICAgICBsb2coJ0NsZWFuaW5nIHVwIGhlcmUuJykNCiAgICAgICAgZmluaXNoKCk=" self.taskModelBlockSignals = False self.taskDetailModelBlockSignals = False self.taskGroupModelSignalsBlock = False self.confInterfaces = interfaceManager.getInfo() self.supportedTypes = instructionManager.getSupportedType() self.codeDialog = CodeDialog("脚本编辑") self.chooseDeviceDlg = ChooseDeviceDlg() self.createTaskDlg = CreateTaskDlg() self.insertInstructionDlg = InsertInstructionDlg() self.insertTaskDlg = InsertTaskDlg() self.current_groupId = None self.topWidget = None self.taskModel = QStandardItemModel() self.taskGroupModel = QStandardItemModel() self.taskDetailModel = QStandardItemModel() self.taskDetailDescriptionModel = QStandardItemModel() self.rootItem = self.taskDetailDescriptionModel.invisibleRootItem() self.ui.treeViewDescription.setModel(self.taskDetailDescriptionModel) self.ui.treeViewDescription.setColumnWidth(0, 400) self.ui.treeViewDescription.setHeaderHidden(True) self.insertInstructionDlg.accepted.connect(self.refreshTaskDetail) self.insertTaskDlg.accepted.connect(self.refreshTaskDetail) self.createTaskDlg.createFinished.connect(self.createTaskFinished) self.createTaskDlg.editFinished.connect(self.editTaskFinished) self.chooseDeviceDlg.chooseFinished.connect(self.chooseDeviceFinished) self.ui.pbInsertInstruction.clicked.connect(self.insertInstruction) self.ui.pbInsertTask.clicked.connect(self.insertTask) self.taskModel.itemChanged.connect(self.updateTask) self.taskGroupModel.itemChanged.connect(self.updateTaskGroup) self.taskDetailModel.itemChanged.connect(self.updateTaskInstruction) self.ui.tableViewTask.setModel(self.taskModel) self.ui.tableViewTaskGroup.setModel(self.taskGroupModel) self.ui.tableViewTaskGroup.dropEvent = self.dropEvent self.ui.pbEditTaskScript.clicked.connect(self.editTaskScript) self.ui.pbCopyTask.clicked.connect(self.copyTask) self.ui.pbExportTask.clicked.connect(self.exportTask) self.ui.tableViewTaskDetail.setModel(self.taskDetailModel) self.ui.tableViewTaskDetail.doubleClicked.connect(self.editTaskDetail) self.ui.tableViewTaskDetail.selectionModel().selectionChanged.connect(self.handleTaskDetailSelection) self.ui.pbCreateGroup.clicked.connect(self.createGroup) self.ui.pbDeleteGroup.clicked.connect(self.deleteGroup) self.ui.pbCreateTask.clicked.connect(self.createTask) self.ui.pbEditTask.clicked.connect(self.editTask) self.ui.pbDeleteTask.clicked.connect(self.deleteTask) self.ui.pbUp.clicked.connect(self.handleUpClick) self.ui.pbDown.clicked.connect(self.handleDownClick) self.ui.pbDeleteTaskDetail.clicked.connect(self.deleteTaskDetail) self.ui.pbSort.clicked.connect(self.showSortBtn) self.ui.pbStartTask.clicked.connect(self.startTask) self.ui.pbStopTask.clicked.connect(self.stopTask) self.ui.pbSaveSort.clicked.connect(self.saveSort) self.ui.pbEditScript.clicked.connect(self.editScript) self.subTasks = {} self.hideSortBtn() self.ui.tableViewTaskGroup.selectionModel().selectionChanged.connect(self.handleGroupSelection) self.ui.tableViewTask.selectionModel().selectionChanged.connect(self.handleTaskSelection) self.setSplitterStretchFactor() self.batchSetItemDelegate() def batchSetItemDelegate(self): self.ui.tableViewTask.horizontalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewTaskGroup.horizontalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewTaskDetail.horizontalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter) self.ui.tableViewTask.setItemDelegate(AlignTaskNoDelegate(self.ui.tableViewTask)) self.ui.tableViewTaskGroup.setItemDelegate(AlignNoDelegate(self.ui.tableViewTaskGroup)) self.ui.tableViewTaskDetail.setItemDelegate(AlignDevDelegate(self.ui.tableViewTaskDetail,2)) def dropEvent(self, event: QDropEvent): if event.source() != self: mime_data = event.mimeData() source_index = mime_data.data('application/x-qabstractitemmodeldatalist') target_pos = event.position() target_index = self.ui.tableViewTaskGroup.indexAt(QPoint(int(target_pos.x()), int(target_pos.y()))) drag_drop_info = DragDropInfo(source_index, target_index) self.handleDrop(drag_drop_info) event.accept() else: event.ignore() # 双击编辑任务功能 def editTaskDetail(self, index): rows = self.ui.tableViewTaskDetail.selectionModel().selectedRows() if len(rows) == 1: row = rows[0].row() if index.column() == 3: row_id_index = self.taskDetailModel.index(row, 0, QModelIndex()) row_target_id_index = self.taskDetailModel.index(row, 11, QModelIndex()) id = self.taskDetailModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) target_id = self.taskDetailModel.data(row_target_id_index, Qt.ItemDataRole.DisplayRole) self.chooseDeviceDlg.showChooseDeviceDlg(id, target_id) def handleDrop(self, drag_drop_info): target_row = drag_drop_info.target_index.row() if target_row > -1: row_id_index = self.taskGroupModel.index(target_row, 0, QModelIndex()) groupId = self.taskGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) rows = self.ui.tableViewTask.selectionModel().selectedRows() for row in rows: row_id_index = self.taskModel.index(row.row(), 0, QModelIndex()) taskId = self.taskModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) taskParam = { "group_id": groupId } result = taskManager.update(taskId, taskParam) self.refreshSelect() def editScript(self): indexs = self.ui.tableViewTask.selectionModel().selectedRows() if len(indexs) == 1: if len(self.ui.tableViewTaskDetail.selectionModel().selectedRows())== 1: row = self.ui.tableViewTaskDetail.selectionModel().selectedRows()[0].row() row_target_id_index = self.taskDetailModel.index(row, 11, QModelIndex()) row_devicename_index = self.taskDetailModel.index(row, 3, QModelIndex()) devicename = self.taskDetailModel.data(row_devicename_index, Qt.ItemDataRole.DisplayRole) target_id = self.taskDetailModel.data(row_target_id_index, Qt.ItemDataRole.DisplayRole) if devicename == "任务": task = taskManager.getInfo(target_id) if task: scriptStr = task["script"] and str(base64.b64decode(task["script"] ), 'utf-8') or str(base64.b64decode(self.defaultScriptBase64).decode('utf-8')) scriptStr = self.codeDialog.showEditDlg(scriptStr,"task") if scriptStr == "": return script = base64.b64encode(scriptStr.encode("utf-8")) param = { "script": script } result = taskManager.update(target_id, param) else: instruction = instructionManager.getInfo(target_id) 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(target_id, {"attr": dataAttr}) script = base64.b64encode(result.encode("utf-8")).decode('utf-8') dataAttr['script'] = script instructionManager.update(target_id, {"attr": dataAttr}) def editTaskScript(self): if len(self.ui.tableViewTask.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() row_index = self.taskModel.index(row, 0, QModelIndex()) task_id = self.taskModel.data(row_index, Qt.ItemDataRole.DisplayRole) task = taskManager.getInfo(task_id) if task: scriptStr = task["script"] and str(base64.b64decode(task["script"] ), 'utf-8') or str(base64.b64decode(self.defaultScriptBase64).decode('utf-8')) scriptStr = self.codeDialog.showEditDlg(scriptStr,"task") if scriptStr == "": return script = base64.b64encode(scriptStr.encode("utf-8")) param = { "script": script } result = taskManager.update(task_id, param) def startTask(self): if len(self.ui.tableViewTask.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() row_index = self.taskModel.index(row, 0, QModelIndex()) taskid = self.taskModel.data(row_index, Qt.ItemDataRole.DisplayRole) taskActuatorManager.start(taskid) def stopTask(self): if len(self.ui.tableViewTask.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() row_index = self.taskModel.index(row, 0, QModelIndex()) taskid = self.taskModel.data(row_index, Qt.ItemDataRole.DisplayRole) taskActuatorManager.stop(taskid) def copyTask(self): if len(self.ui.tableViewTask.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() row_index = self.taskModel.index(row, 0, QModelIndex()) taskid = self.taskModel.data(row_index, Qt.ItemDataRole.DisplayRole) taskManager.createCopy(taskid) self.refreshSelect() # 覆盖方式导入设备模型 def overWriteTask(self): file_dialog = QFileDialog(self) file_dialog.setWindowTitle("选择JSON") file_dialog.setNameFilter("Supported file formats (*.json)") file_dialog.setFileMode(QFileDialog.FileMode.ExistingFile) if file_dialog.exec(): file_path = file_dialog.selectedFiles()[0] with open(file_path, "r", encoding="utf-8") as f: # 指定以utf-8编码打开文件 taskInfo = json.load(f) tasks = taskInfo.get("tasks",[]) instructions = taskInfo.get("task_instructions",[]) for task in tasks: groupId = task['group_id'] group_name = task['group_name'] if groupId != None: if taskGroupManager.getInfo( groupId ) == None: groupId = taskGroupManager.create({"id": groupId, "name": group_name}) task['group_id'] = groupId task_id = task['id'] if taskManager.getInfo(task_id) != None: taskManager.update(task_id, task) else: task_id = taskManager.create_from_json(task) for instruction in instructions: instructionId = instruction['id'] if instruction["task_id"] == task_id: if taskInstructionManager.getInstructionInfo(instructionId) != None: taskInstructionManager.update(instructionId, instruction) else: taskInstructionManager.create_from_json(instruction) self.refreshSelect() def exportSingleTask(self, task_id): tInfo = taskManager.getInfo(task_id) #判断taskInfo 中的Id 长度是否小于10,如果是则改为uuid new_task_id = str(uuid.uuid4()) if len(str(task_id)) < 10: tInfo["id"] = new_task_id common.writeJson(os.path.join(os.path.dirname(__file__),"export"),"task", tInfo) groupInfo = taskGroupManager.getInfo(tInfo["group_id"]) common.writeJson(os.path.join(os.path.dirname(__file__),"export"),"task_group", groupInfo) task_instructionInfos = taskInstructionManager.getTaskInstructions(task_id) for task_instructionInfo in task_instructionInfos: if len(str(task_instructionInfo["id"])) < 10: task_instructionInfo["id"] = str(uuid.uuid4()) if len(task_id) < 10: task_instructionInfo["task_id"] = new_task_id target_type = task_instructionInfo["target_type"] if target_type == "instruction": deviceInfo = deviceManager.getOriginalInfo(task_instructionInfo["device_id"]) groupInfo = devGroupManager.getInfo(deviceInfo["group_id"]) 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) elif target_type == "task": self.exportSingleTask(task_instructionInfo["target_id"]) common.writeJson(os.path.join(os.path.dirname(__file__),"export"),"task_instruction", task_instructionInfo) def exportTask(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.tableViewTask.selectionModel().selectedRows() for index in indexs: row = index.row() row_index = self.taskModel.index(row, 0, QModelIndex()) task_id = self.taskModel.data(row_index, Qt.ItemDataRole.DisplayRole) self.exportSingleTask(task_id) 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 chooseDeviceFinished(self): self.refreshTaskDetail() def saveSort(self): for row in range(self.taskDetailModel.rowCount()): row_id_index = self.taskDetailModel.index(row, 0, QModelIndex()) row_level_index = self.taskDetailModel.index(row, 10, QModelIndex()) taskInstanceId = self.taskDetailModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) level = self.taskDetailModel.data(row_level_index, Qt.ItemDataRole.DisplayRole) if not str(row) == level: param = { "level": row } if not taskInstructionManager.update(taskInstanceId, param): print("update error") self.refreshTaskDetail() self.hideSortBtn() def createGroup(self): index = self.taskGroupModel.rowCount() self.taskGroupModel.appendRow([ QStandardItem(),QStandardItem(str(index+1)), QStandardItem()]) self.ui.tableViewTaskGroup.setCurrentIndex(self.taskGroupModel.index(index, 0) ) self.ui.tableViewTaskGroup.edit(self.taskGroupModel.index(index, 2)) def deleteGroup(self): if len(self.ui.tableViewTaskGroup.selectionModel().selectedRows())== 1: row = self.ui.tableViewTaskGroup.selectionModel().selectedRows()[0].row() row_id_index = self.taskGroupModel.index(row, 0, QModelIndex()) groupId = self.taskGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) if groupId == common.defaultGroupId: return row_groupName_index = self.taskGroupModel.index(row, 2, QModelIndex()) groupName = self.taskGroupModel.data(row_groupName_index, Qt.ItemDataRole.DisplayRole) if self.topWidget == None: self.topWidget = self.findTopLevelParent(self) if self.topWidget != None: if self.taskModel.rowCount() > 0: self.topWidget.alertDialog("分组下存在任务,不能删除分组", "警告") return if self.topWidget.removeDialog(groupName,"删除分组"): result = taskGroupManager.delete(groupId) if result == True: self.clearChildrenModel() self.taskGroupModel.removeRow(row) def updateTaskGroup(self): if self.taskGroupModelSignalsBlock == False: if len(self.ui.tableViewTaskGroup.selectionModel().selectedRows())== 1: row = self.ui.tableViewTaskGroup.selectionModel().selectedRows()[0].row() row_id_index = self.taskGroupModel.index(row, 0, QModelIndex()) groupId = self.taskGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) row_nane_index = self.taskGroupModel.index(row, 2, QModelIndex()) groupName = self.taskGroupModel.data(row_nane_index, Qt.ItemDataRole.DisplayRole) if groupId == None: groupId = taskGroupManager.create({"name":groupName}) self.taskGroupModel.setData(row_id_index, groupId) else: taskGroupManager.update(groupId, {"name":groupName}) def showSortBtn(self): self.ui.pbUp.setVisible(True) self.ui.pbDown.setVisible(True) self.ui.pbSaveSort.setVisible(True) self.ui.pbDeleteTaskDetail.setVisible(False) self.ui.pbDeleteTask.setEnabled(False) self.ui.pbSort.setVisible(False) self.ui.pbInsertInstruction.setVisible(False) self.ui.pbInsertTask.setVisible(False) self.ui.pbEditScript.setVisible(False) self.ui.tableViewTaskDetail.setColumnHidden(9, True) self.ui.tableViewTaskDetail.setColumnHidden(8, True) self.ui.tableViewTaskDetail.setColumnHidden(7, True) self.ui.tableViewTaskDetail.setColumnHidden(6, True) self.setAllColumnWidth() def hideSortBtn(self): self.ui.pbUp.setVisible(False) self.ui.pbDown.setVisible(False) self.ui.pbSaveSort.setVisible(False) self.ui.pbSort.setVisible(True) self.ui.pbDeleteTaskDetail.setVisible(True) self.ui.pbDeleteTask.setEnabled(True) self.ui.pbInsertInstruction.setVisible(True) self.ui.pbInsertTask.setVisible(True) self.ui.pbEditScript.setVisible(True) self.ui.tableViewTaskDetail.setColumnHidden(9, False) self.ui.tableViewTaskDetail.setColumnHidden(8, False) self.ui.tableViewTaskDetail.setColumnHidden(7, False) self.ui.tableViewTaskDetail.setColumnHidden(6, False) self.setAllColumnWidth() def insertTask(self): if len(self.ui.tableViewTask.selectionModel().selectedRows())== 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() taskId=self.taskModel.item(row, 0).text() position = self.taskDetailModel.rowCount() self.insertTaskDlg.showDlg(taskId, position) def insertInstruction(self): if len(self.ui.tableViewTask.selectionModel().selectedRows())== 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() taskId=self.taskModel.item(row, 0).text() position = self.taskDetailModel.rowCount() self.insertInstructionDlg.showDlg(taskId, position) def createTaskFinished(self): self.loadTask() if self.taskModel.rowCount() > 0: self.ui.tableViewTask.selectRow(self.taskModel.rowCount()-1) def editTaskFinished(self): if len(self.ui.tableViewTask.selectionModel().selectedRows())== 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() self.loadTask() if self.taskModel.rowCount() > 0: self.ui.tableViewTask.selectRow(row) def createTask(self): if self.current_groupId != None: self.createTaskDlg.showCreateDlg(self.current_groupId) def editTask(self): if len(self.ui.tableViewTask.selectionModel().selectedRows())== 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() row_taskId_index = self.taskModel.index(row, 0, QModelIndex()) task_id = self.taskModel.data(row_taskId_index, Qt.ItemDataRole.DisplayRole) task = taskManager.getInfo(task_id) if task: self.createTaskDlg.showEditDlg(task) def findTopLevelParent(self, widget): parent = widget.parent() while parent and not isinstance(parent, QMainWindow): # 顶层窗口是 QMainWindow widget = parent parent = widget.parent() return parent def deleteTask(self): indexs = self.ui.tableViewTask.selectionModel().selectedRows() if len(indexs) == 1: row = indexs[0].row() row_id_index = self.taskModel.index(row, 0, QModelIndex()) row_name_index = self.taskModel.index(row, 2, QModelIndex()) taskName = self.taskModel.data(row_name_index, Qt.ItemDataRole.DisplayRole) if self.topWidget == None: self.topWidget = self.findTopLevelParent(self) if self.topWidget != None: if self.topWidget.removeDialog(taskName,"删除任务"): row_taskModel_index = self.taskModel.index(row, 0, QModelIndex()) result = taskManager.delete(self.taskModel.data(row_taskModel_index, Qt.ItemDataRole.DisplayRole)) if result == True: self.refreshSelect() elif 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.taskModel.index(row, 0, QModelIndex()) taskId = self.taskModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) taskManager.delete(taskId) self.refreshSelect() def clearChildrenModel(self): self.taskDetailModel.clear() self.ui.textEditDescription.clear() self.clearTreeModel() def clearTaskChildrenModel(self): self.taskModel.clear() self.ui.textEditDescription.clear() self.clearTreeModel() def handleUpClick(self): selectRows = self.ui.tableViewTaskDetail.selectionModel().selectedRows() if len(selectRows) == 1: row = selectRows[0].row() if row > 0: item = self.taskDetailModel.takeRow(row) self.taskDetailModel.insertRow(row - 1, item) self.ui.tableViewTaskDetail.selectRow(row - 1) def handleDownClick(self): selectRows = self.ui.tableViewTaskDetail.selectionModel().selectedRows() if len(selectRows) == 1: row = selectRows[0].row() if row < self.taskDetailModel.rowCount() - 1: item = self.taskDetailModel.takeRow(row) self.taskDetailModel.insertRow(row + 1, item) self.ui.tableViewTaskDetail.selectRow(row + 1) def refreshSelect(self): selectedRows = self.ui.tableViewTaskGroup.selectionModel().selectedRows() self.loadTaskGroup() if len(selectedRows) < 1: self.ui.tableViewTaskGroup.selectRow(0) if len(selectedRows) == 1: row = selectedRows[0].row() self.ui.tableViewTaskGroup.selectRow(row) def refreshTaskDetail(self): if len(self.ui.tableViewTask.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() row_index = self.taskModel.index(row, 0, QModelIndex()) taskid = self.taskModel.data(row_index, Qt.ItemDataRole.DisplayRole) self.loadTaskDetail(taskid) # 任务分组选中 def handleGroupSelection(self, index): if len(self.ui.tableViewTaskGroup.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTaskGroup.selectionModel().selectedRows()[0].row() row_id_index = self.taskGroupModel.index(row, 0, QModelIndex()) group_id = self.taskGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) self.current_groupId = group_id self.loadTask() self.clearChildrenModel() #任务列表选中 def handleTaskSelection(self, index): self.refreshTaskDetail() def handleTaskDetailSelection(self, index): if len(self.ui.tableViewTaskDetail.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTaskDetail.selectionModel().selectedRows()[0].row() row_target_id_index = self.taskDetailModel.index(row, 11, QModelIndex()) targetId = self.taskDetailModel.data(row_target_id_index, Qt.ItemDataRole.DisplayRole) row_target_type_name_index = self.taskDetailModel.index(row, 3, QModelIndex()) targetTypeName = self.taskDetailModel.data(row_target_type_name_index, Qt.ItemDataRole.DisplayRole) if targetTypeName == "任务": self.clearTreeModel() self.appendTaskItem(targetId) self.ui.stackedWidgetDescription.setCurrentIndex(1) else: info = instructionManager.getInfo(targetId) attr = info.get('attr') if attr == None: self.ui.textEditDescription.clear() else: description = attr.get('description') if description == None: self.ui.textEditDescription.clear() else: self.ui.textEditDescription.setText(description) self.ui.stackedWidgetDescription.setCurrentIndex(0) def appendTaskItem(self, taskId): try: task = taskManager.getInfo(str(taskId)) if task: name = task["name"] item = QStandardItem(str(name)) self.appendChildTask(item, str(taskId)) self.rootItem.appendRow([item]) self.ui.treeViewDescription.expandAll() except Exception as e: print(e) def appendChildTask(self, parent, taskId): try: taskInstructions = taskInstructionManager.getInfo(taskId) if taskInstructions: for taskInstruction in taskInstructions: target_type = taskInstruction["target_type"] task_instruction_id = str(taskInstruction["id"]) level = taskInstruction["level"] if target_type == "task": task = taskManager.getInfo(str(taskInstruction["target_id"])) if task: name = task["name"] childItem = QStandardItem(str(name)) parent.appendRow([childItem]) except Exception as e: print(e) def deleteTaskDetail(self): if len(self.ui.tableViewTaskDetail.selectionModel().selectedRows())== 1: row = self.ui.tableViewTaskDetail.selectionModel().selectedRows()[0].row() row_name_index = self.taskDetailModel.index(row, 4, QModelIndex()) targetName = self.taskDetailModel.data(row_name_index, Qt.ItemDataRole.DisplayRole) if self.topWidget == None: self.topWidget = self.findTopLevelParent(self) if self.topWidget != None: if self.topWidget.removeDialog(targetName,"删除功能"): row_taskDetail_index = self.taskDetailModel.index(row, 0, QModelIndex()) taskInstructionId = self.taskDetailModel.data(row_taskDetail_index, Qt.ItemDataRole.DisplayRole) if taskInstructionManager.delete(taskInstructionId): self.taskDetailModel.removeRow(row) def updateTask(self): if self.taskModelBlockSignals == True: return if len(self.ui.tableViewTask.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTask.selectionModel().selectedRows()[0].row() row_id_index = self.taskModel.index(row, 0, QModelIndex()) row_name_index = self.taskModel.index(row, 2, QModelIndex()) row_loop_index = self.taskModel.index(row, 3, QModelIndex()) row_delay_index = self.taskModel.index(row, 4, QModelIndex()) row_remark_index = self.taskModel.index(row, 5, QModelIndex()) name = self.taskModel.data(row_name_index, Qt.ItemDataRole.DisplayRole) delay = self.taskModel.data(row_delay_index, Qt.ItemDataRole.DisplayRole) loop = self.taskModel.data(row_loop_index, Qt.ItemDataRole.DisplayRole) remark = self.taskModel.data(row_remark_index, Qt.ItemDataRole.DisplayRole) taskId = self.taskModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) taskParam = { "name": name, "delay": delay, "loop": loop, "remark": remark } result = taskManager.update(taskId, taskParam) def updateTaskInstruction(self): if self.taskDetailModelBlockSignals == True: return if len(self.ui.tableViewTaskDetail.selectionModel().selectedRows()) == 1: row = self.ui.tableViewTaskDetail.selectionModel().selectedRows()[0].row() row_id_index = self.taskDetailModel.index(row, 0, QModelIndex()) row_delay_index = self.taskDetailModel.index(row, 6, QModelIndex()) row_loop_index = self.taskDetailModel.index(row, 7, QModelIndex()) row_param_index = self.taskDetailModel.index(row, 8, QModelIndex()) row_interfacenum_index = self.taskDetailModel.index(row, 9, QModelIndex()) delay = self.taskDetailModel.data(row_delay_index, Qt.ItemDataRole.DisplayRole) loop = self.taskDetailModel.data(row_loop_index, Qt.ItemDataRole.DisplayRole) param = self.taskDetailModel.data(row_param_index, Qt.ItemDataRole.DisplayRole) interfaceIndex = self.taskDetailModel.data(row_interfacenum_index, Qt.ItemDataRole.DisplayRole) taskInstanceId = self.taskDetailModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) taskInstanceParam = { "delay": delay, "loop": loop, "target_param": param, "interface_index": interfaceIndex } result = taskInstructionManager.update(taskInstanceId, taskInstanceParam) def setItemsEnable(self, enable): self.ui.pbInsertTask.setEnabled(enable) self.ui.pbDeleteTask.setEnabled(enable) self.ui.pbInsertInstruction.setEnabled(enable) if not enable: self.ui.tableViewTask.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) else: self.ui.tableViewTask.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) def clearTreeModel(self): try: for i in range(self.taskDetailDescriptionModel.rowCount()): self.taskDetailDescriptionModel.removeRow(0) except Exception as e: print(e) #加载任务详情 def loadTaskDetail(self, taskId): self.setItemsEnable(False) self.taskDetailModelBlockSignals = True self.taskDetailModel.clear() self.ui.textEditDescription.clear() self.clearTreeModel() self.loadPageTaskDetail(taskId, 0, 50) self.taskDetailModelBlockSignals = False self.setItemsEnable(True) self.batchOperation() def loadPageTaskDetail(self, taskId, row, limit): QCoreApplication.processEvents() if taskId: taskInstructions = taskInstructionManager.getPageInfo(taskId,row, limit) if len(taskInstructions) > 0: for taskInstruction in taskInstructions: index = self.taskDetailModel.rowCount() self.taskDetailModel.setItem(index, 0, QStandardItem(str(taskInstruction["id"]))) self.taskDetailModel.setItem(index, 1, QStandardItem(str(taskInstruction["task_id"]))) name = "" type = "" devicename = "" dev_model_id = "" devinterface = [] if taskInstruction["target_type"] == "instruction": instruction = instructionManager.getInfo(str(taskInstruction["target_id"])) if instruction: name = instruction["name"] type = instruction["type"] if instruction["type"] is not None and instruction["type"] in self.supportedTypes: type = self.supportedTypes[instruction["type"]]["name"] device_id = taskInstruction["device_id"] device = deviceManager.getInfo(device_id) if device != None: devicename = device["name"] dev_model_id = device["dev_model_id"] devinterface = device["interface"] elif taskInstruction["target_type"] == "task": task = taskManager.getInfo(taskInstruction["target_id"]) if task != None: devicename = "任务" name = task["name"] self.taskDetailModel.setItem(index, 2, QStandardItem(str(index+1))) self.taskDetailModel.setItem(index, 3, QStandardItem(devicename)) self.taskDetailModel.setItem(index, 4, QStandardItem(name)) self.taskDetailModel.setItem(index, 5, QStandardItem(type)) self.taskDetailModel.setItem(index, 6, QStandardItem(str(taskInstruction["delay"]))) self.taskDetailModel.setItem(index, 7, QStandardItem(str(taskInstruction["loop"]))) self.taskDetailModel.setItem(index, 8, QStandardItem(taskInstruction["target_param"])) self.taskDetailModel.setItem(index, 9, QStandardItem("")) self.taskDetailModel.setItem(index, 10, QStandardItem(str(taskInstruction["level"]))) self.taskDetailModel.setItem(index, 11, QStandardItem(str(taskInstruction["target_id"]))) self.setUnEditableStyle(self.taskDetailModel.item(index, 2)) self.setDeviceStyle(self.taskDetailModel.item(index, 2), devicename) self.setUnEditableStyle(self.taskDetailModel.item(index, 3)) self.setUnEditableStyle(self.taskDetailModel.item(index, 4)) self.setUnEditableStyle(self.taskDetailModel.item(index, 5)) devModel = devModelManager.getInfo(dev_model_id) if devModel != None: attr_json_dict = devModel["attr"] devmodelInterfacetypes = {} if "interfaceType" in attr_json_dict: devmodelInterfacetypes = attr_json_dict["interfaceType"] if len(devmodelInterfacetypes) > 0: cmb = NoWheelComboBox() cmb.currentIndexChanged.connect(self.changeInterface) for devmodelInterfacetype in devmodelInterfacetypes: cmb.addItem(devmodelInterfacetype) interface_index = "interface_index" in taskInstruction and taskInstruction["interface_index"] or 0 interface_index = interface_index != "" and interface_index or 0 if interface_index < len(devmodelInterfacetypes): cmb.setCurrentIndex(interface_index) self.taskDetailModel.setItem(index, 9, QStandardItem(str(interface_index))) else: if len(devmodelInterfacetypes) > 0: cmb.setCurrentIndex(0) taskInstructionManager.update(str(taskInstruction["id"]), {"interface_index":0}) # 更新 self.taskDetailModel.setItem(index, 9, QStandardItem("0")) self.ui.tableViewTaskDetail.setIndexWidget(self.taskDetailModel.index(index, 9), cmb) self.batchOperation() self.loadPageTaskDetail(taskId, row + limit,limit) else: return # 切换接口 def changeInterface(self,index): if len(self.ui.tableViewTaskDetail.selectionModel().selectedRows())== 1: row = self.ui.tableViewTaskDetail.selectionModel().selectedRows()[0].row() self.taskDetailModel.setItem(row, 9 , QStandardItem(str(index))) def setTaskStyle(self,item,type): if type == "parent": item.setForeground(QColor(255, 255, 255)) item.setBackground(QColor(240, 35, 35)) elif type == "child": item.setForeground(QColor(0, 0, 0)) item.setBackground(QColor(238, 191, 63)) def setDeviceStyle(self,item,device_name): if device_name == "": item.setBackground(QColor(229, 214, 223)) else: item.setForeground(QColor(0, 0, 0)) #设置不可编辑样式 def setUnEditableStyle(self, item): item.setEditable(False) def setSplitterStretchFactor(self): self.ui.splitter.setStretchFactor(0, 15) self.ui.splitter.setStretchFactor(1, 35) self.ui.splitter.setStretchFactor(2, 50) # 批量操作 def batchOperation(self): self.setAllHorizontalHeaderLabels() self.hideAllColumn() self.setAllColumnWidth() # 批量设置标题 def setAllHorizontalHeaderLabels(self): self.taskGroupModel.setHorizontalHeaderLabels(["ID","","名称"]) self.taskModel.setHorizontalHeaderLabels(["ID","","名称", "循环次数", "间隔时间(ms)", "备注", "进度","组ID"]) self.taskDetailModel.setHorizontalHeaderLabels(["ID","任务ID","","设备","名称", "类型", "间隔时间(ms)", "循环次数", "参数", "端口", "序号"]) # 隐藏指定列 def hideAllColumn(self): self.ui.tableViewTask.setColumnHidden(0, True) self.ui.tableViewTask.setColumnHidden(1, True) self.ui.tableViewTask.setColumnHidden(7, True) self.ui.tableViewTask.setColumnHidden(8, True) self.ui.tableViewTaskGroup.setColumnHidden(0, True) self.ui.tableViewTaskGroup.setColumnHidden(1, True) self.ui.tableViewTaskDetail.setColumnHidden(0, True) self.ui.tableViewTaskDetail.setColumnHidden(1, True) self.ui.tableViewTaskDetail.setColumnHidden(10, True) self.ui.tableViewTaskDetail.setColumnHidden(11, True) # 批量设置列宽 def setAllColumnWidth(self): if self.taskGroupModel.rowCount() > 0: self.ui.tableViewTaskGroup.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents) self.ui.tableViewTaskGroup.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch) if self.taskModel.rowCount() > 0: self.ui.tableViewTask.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents) self.ui.tableViewTask.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.Stretch) self.ui.tableViewTask.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.Stretch) self.ui.tableViewTask.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeMode.Stretch) self.ui.tableViewTask.horizontalHeader().setSectionResizeMode(6, QHeaderView.ResizeMode.Interactive) if self.taskDetailModel.rowCount() > 0: self.ui.tableViewTaskDetail.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents) self.ui.tableViewTaskDetail.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.Interactive) self.ui.tableViewTaskDetail.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.ResizeToContents) self.ui.tableViewTaskDetail.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeMode.Stretch) self.ui.tableViewTaskDetail.horizontalHeader().setSectionResizeMode(6, QHeaderView.ResizeMode.Stretch) self.ui.tableViewTaskDetail.horizontalHeader().setSectionResizeMode(7, QHeaderView.ResizeMode.Stretch) self.ui.tableViewTaskDetail.horizontalHeader().setSectionResizeMode(8, QHeaderView.ResizeMode.Stretch) self.ui.tableViewTaskDetail.horizontalHeader().setSectionResizeMode(9, QHeaderView.ResizeMode.Interactive) #加载全部被包含的子任务 def loadAllSubTasks(self): self.subTasks = {} self.parentTasks = {} includingsubtasks = taskInstructionManager.getIncludingsubtasks() if len(includingsubtasks) > 0: for task in includingsubtasks: taskInfo = taskManager.getInfo(str(task["task_id"])) if taskInfo: taskName = taskInfo["name"] self.parentTasks[str(task["task_id"])] = True if str(task["target_id"]) in self.subTasks: if taskName not in self.subTasks[str(task["target_id"])]: self.subTasks[str(task["target_id"])].append(taskName) else: self.subTasks[str(task["target_id"])] = [] self.subTasks[str(task["target_id"])].append(taskName) # 加载队列组 def loadTaskGroup(self): self.taskGroupModel.clear() self.ui.textEditDescription.clear() self.clearTreeModel() groups = taskGroupManager.getInfo() self.taskGroupModelBlockSignals = True if len(groups) > 0: for group in groups: index = self.taskGroupModel.rowCount() self.taskGroupModel.setItem(index, 0, QStandardItem(str(group["id"]))) self.taskGroupModel.setItem(index, 1, QStandardItem(str(index+1))) self.taskGroupModel.setItem(index, 2, QStandardItem(group["name"])) self.setUnEditableStyle(self.taskGroupModel.item(index, 1)) self.taskGroupModelBlockSignals = False self.batchOperation() # 加载队列 def loadTask(self): self.loadAllSubTasks() self.taskModel.clear() self.ui.textEditDescription.clear() self.clearTreeModel() tasks = taskManager.getGroupTask(self.current_groupId) self.taskModelBlockSignals = True if len(tasks) > 0: for task in tasks: index = self.taskModel.rowCount() progressItem = QxStandardItem('',self) progressItem.setData({'task_instruction_id': task["id"], 'name': task["name"]}, Qt.ItemDataRole.UserRole) self.taskModel.setItem(index, 0, QStandardItem(str(task["id"]))) self.taskModel.setItem(index, 1, QStandardItem(str(index+1))) self.taskModel.setItem(index, 2, QStandardItem(task["name"])) self.taskModel.setItem(index, 3, QStandardItem(str(task["loop"]))) self.taskModel.setItem(index, 4, QStandardItem(str(task["delay"]))) self.taskModel.setItem(index, 5, QStandardItem(task["remark"])) self.taskModel.setItem(index, 6, progressItem) self.taskModel.setItem(index, 7, QStandardItem(str(task["group_id"]))) self.taskModel.setItem(index, 8, QStandardItem("normal")) self.setUnEditableStyle(self.taskModel.item(index, 1)) delegate = ProgressBarDelegate() self.ui.tableViewTask.setItemDelegateForColumn(6, delegate) # 为列索引为 1 的项设置自定义委托 task_id = str(task["id"]) taskActuatorManager.updateProgress.connect(progressItem.updateProgress) if task_id in self.parentTasks: self.taskModel.setItem(index, 8, QStandardItem("parent")) if task_id in self.subTasks: self.taskModel.setItem(index, 8, QStandardItem("child")) self.taskModelBlockSignals = False self.batchOperation()