import json import re from PyQt6 import * from PyQt6.QtCore import * from PyQt6.QtGui import * from PyQt6.QtWidgets import * from ui.Ui_taskListForm import Ui_taskListForm from taskModel.taskManager import taskManager from instructionModel.instructionManager import instructionManager from taskGroupModel.taskGroupManager import taskGroupManager from taskInstructionModel.taskInstructionManager import taskInstructionManager from taskModel.taskActuatorManager import taskActuatorManager from logs import log from common import NoWheelComboBox from common import TaskProgressBar from common import common # class ProgressBarDelegate(QStyledItemDelegate): # def paint(self, painter, option, index): # if index.column() == 1: # 列索引为 1 的项添加进度条 # data = index.data(Qt.ItemDataRole.UserRole) # 从 UserRole 中获取进度条数据 # if data is not None and isinstance(data, dict): # value = data.get('value', 0) # maximum = data.get('maximum', 100) # progressBar = QStyleOptionProgressBar() # progressBar.rect = option.rect # progressBar.minimum = 0 # progressBar.maximum = maximum # progressBar.progress = value # progressBar.textVisible = True # progressBar.textAlignment = Qt.AlignmentFlag.AlignCenter # QApplication.style().drawControl(QStyle.ControlElement.CE_ProgressBar, progressBar, painter) # else: # super().paint(painter, option, index) class ProgressBarDelegate(QStyledItemDelegate): def paint(self, painter, option, index): if index.column() == 1: # 仅对第二列添加进度条 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 QxStandardItem(QStandardItem): def __init__(self, text=''): 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.setData({'value': value, 'maximum': maxValue, 'task_instruction_id': obj.get('task_instruction_id'), 'name':obj.get('name')}, Qt.ItemDataRole.UserRole) class TaskListForm(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_taskListForm() self.ui.setupUi(self) self.model = QStandardItemModel() self.model.setHorizontalHeaderLabels(["任务","进度"]) self.rootItem = self.model.invisibleRootItem() self.ui.treeView.setModel(self.model) self.ui.treeView.setColumnWidth(0, 400) taskActuatorManager.taskStart.connect(self.appendTask) taskActuatorManager.taskStop.connect(self.clearTaskData) taskActuatorManager.updateDetails.connect(self._onUpdateDetails) delegate = ProgressBarDelegate() self.ui.treeView.setItemDelegateForColumn(1, delegate) # 为列索引为 1 的项设置自定义委托 self.ui.treeView.expandAll() def clearTaskData(self, taskId): for row in range(self.model.rowCount()): index = self.model.index(row, 1) data = index.data(Qt.ItemDataRole.UserRole) if data is not None and isinstance(data, dict): if str(data.get('task_instruction_id')) == str(taskId): self.model.removeRow(row) break def appendTask(self, taskId): for row in range(self.model.rowCount()): index = self.model.index(row, 1) data = index.data(Qt.ItemDataRole.UserRole) if data is not None and isinstance(data, dict): if str(data.get('task_instruction_id')) == str(taskId): print(f"TaskId {taskId} already exists, removing existing item...") self.model.removeRow(row) break task = taskManager.getInfo(str(taskId)) if task: name = task["name"] item = QStandardItem(str(name)) progressItem = QxStandardItem() progressItem.setData({'task_instruction_id': task["id"], 'name': name}, Qt.ItemDataRole.UserRole) self.appendChildTask(item, str(taskId), str(taskId)) self.rootItem.appendRow([item, progressItem]) self.ui.treeView.expandAll() def appendChildTask(self, parent, taskId, parentId): 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)) childProgressItem = QxStandardItem() childProgressItem.setData({'task_instruction_id': parentId + task_instruction_id, 'name': name}, Qt.ItemDataRole.UserRole) self.appendChildTask(childItem, str(taskInstruction["target_id"]), parentId + task_instruction_id) parent.appendRow([childItem, childProgressItem]) elif target_type == "instruction": instruction = instructionManager.getInfo(str(taskInstruction["target_id"])) if instruction: name = instruction["name"] childItem = QStandardItem(str(name)) childProgressItem = QxStandardItem() childProgressItem.setData({'task_instruction_id': parentId + task_instruction_id, 'name': name}, Qt.ItemDataRole.UserRole) parent.appendRow([childItem, childProgressItem]) def _onUpdateDetails(self, taskId, value, maxValue): self._updateTreeProgress(self.model.invisibleRootItem(), taskId, value, maxValue) def _updateTreeProgress(self, parentItem, taskId, value, maxValue): for row in range(parentItem.rowCount()): progressItem = parentItem.child(row, 1) if progressItem is not None: obj = progressItem.data(Qt.ItemDataRole.UserRole) if obj is not None and isinstance(obj, dict): if str(taskId) == str(obj.get('task_instruction_id')): progressItem.setData({'value': value, 'maximum': maxValue, 'task_instruction_id': obj.get('task_instruction_id'), 'name': obj.get('name')}, Qt.ItemDataRole.UserRole) return childItem = parentItem.child(row, 0) if childItem is not None and childItem.hasChildren(): self._updateTreeProgress(childItem, taskId, value, maxValue)