En esta página

Demostración de TaskTree

Demuestra cómo los diferentes modos de ejecución y las políticas de flujo de trabajo afectan a la compleja ejecución de TaskTree.

La Demo de TaskTree muestra cómo construir una receta anidada de TaskTree utilizando timeoutTask, y demuestra diferentes execution modes y workflow policies. Su aplicación proporciona una visión gráfica del progreso a medida que el TaskTree ejecuta los diferentes elementos de trabajo que componen la tarea.

Grupos de tareas anidados con estados codificados por colores que muestran el progreso al 78%.

La aplicación de demostración utiliza un único QWidget para mostrar y gestionar una jerarquía TaskTree. Esto es lo que encontrarás en la interfaz:

  • Las tareas aparecen como nodos hoja en la parte derecha del árbol.

    Para cada tarea, puedes establecer la duración de la ejecución y configurar los estados de finalización de éxito o error.

  • Los nodos de grupo aparecen a la izquierda y en el centro del árbol.

    Cada grupo puede contener varias tareas secundarias o grupos anidados. Puede configurar execution modes y workflow policies para cada grupo.

  • Los indicadores de color muestran el estado de ejecución actual de cada nodo.

Las siguientes secciones describen más detalles del código del ejemplo.

Clases auxiliares de cola

La clase abstracta GlueItem conecta los componentes de la interfaz de usuario (UI) con sus correspondientes recetas TaskTree. Este patrón de diseño permite una separación clara entre la interfaz de usuario y la lógica de tareas.

class GlueItem
{
public:
    virtual ExecutableItem recipe() const = 0;
    virtual QWidget *widget() const = 0;
    virtual void reset() const = 0;

    virtual ~GlueItem() = default;
};

La clase GlueItem define tres métodos virtuales clave:

MétodoPropósito
recipe()Crea y devuelve una receta TaskTree que define el comportamiento del elemento
widget()Proporciona acceso al componente de interfaz de usuario asociado
reset()Restaura el componente UI a su estado inicial

La clase GroupGlueItem gestiona elementos Group en su jerarquía de tareas. Cada grupo puede contener otros elementos GlueItem como hijos, incluyendo GroupGlueItems o TaskGlueItems anidados.

Así es como el método recipe() crea y configura un grupo:

ExecutableItem GroupGlueItem::recipe() const
{
    GroupItems childRecipes;
    for (GlueItem *child : m_children)
        childRecipes.append(child->recipe());

    return Group {
        m_groupWidget->executeModeItem(),
        m_groupWidget->workflowPolicyItem(),
        onGroupSetup([this] { m_groupWidget->setState(State::Running); }),
        childRecipes,
        onGroupDone([this](DoneWith result) { m_groupWidget->setState(resultToState(result)); })
    };
}

Componentes clave de la implementación:

La clase TaskGlueItem implementa nodos hoja en su árbol de tareas usando timeoutTask.

Aquí está la implementación recipe() que crea la tarea:

ExecutableItem TaskGlueItem::recipe() const
{
    return Group {
        onGroupSetup([this] { m_taskWidget->setState(State::Running); }),
        timeoutTask(seconds(m_taskWidget->busyTime()), m_taskWidget->desiredResult()),
        onGroupDone([this](DoneWith result) { m_taskWidget->setState(resultToState(result)); })
    };
}

La implementación:

  • Crea un Group que envuelve un timeoutTask
  • Utiliza los ajustes de la interfaz de usuario para configurar la duración y el resultado esperado.
  • Actualiza el estado de la interfaz de usuario cuando comienza la tarea a través de onGroupSetup()
  • Refleja el estado de finalización de la tarea a través de onGroupDone()

Creación de la jerarquía de tareas

Dos métodos de ayuda simplifican la creación de árboles de tareas:

static GlueItem *group(const GroupSetup &groupSetup, const QList<GlueItem *> children)
{
    return new GroupGlueItem(groupSetup, children);
}

static GlueItem *task(int busyTime = 1, DoneResult result = DoneResult::Success)
{
    return new TaskGlueItem(busyTime, result);
}
  • group(): Crea un nuevo GroupGlueItem
  • task(): Crea un nuevo TaskGlueItem

Definición de la estructura de árbol

El siguiente código muestra cómo se puede construir una jerarquía de tareas completa:

    std::unique_ptr<GlueItem> tree {
        group({WorkflowPolicy::ContinueOnSuccess}, {
            group({}, {
                task(),
                task(2, DoneResult::Error),
                task(3)
            }),
            task(),
            task(),
            group({WorkflowPolicy::FinishAllAndSuccess}, {
                task(),
                task(),
                group({WorkflowPolicy::StopOnError, ExecuteMode::Parallel}, {
                    task(4),
                    task(2),
                    task(1),
                    task(3, DoneResult::Error)
                }),
                task(2),
                task(3)
            }),
            task()
        })
    };

Puede modificar la construcción anterior para crear diferentes estructuras de árbol.

Conexión de la interfaz de usuario con TaskTree

El paso final conecta el árbol de tareas con los controles de interfaz de usuario de la aplicación:

    QSingleTaskTreeRunner taskTreeRunner;

    const auto resetTaskTree = [&] {
        taskTreeRunner.reset();
        tree->reset();
        progressBar->setValue(0);
        cancelButton->setEnabled(false);
    };

    const auto cancelTaskTree = [&] { taskTreeRunner.cancel(); };

    const auto startTaskTree = [&] {
        resetTaskTree();
        cancelButton->setEnabled(true);

        const auto onTaskTreeSetup = [progressBar](QTaskTree &taskTree) {
            progressBar->setMaximum(taskTree.progressMaximum());
            QObject::connect(&taskTree, &QTaskTree::progressValueChanged,
                             progressBar, &QProgressBar::setValue);
        };

        const auto onTaskTreeDone = [cancelButton] { cancelButton->setEnabled(false); };

        taskTreeRunner.start({tree->recipe()}, onTaskTreeSetup, onTaskTreeDone);
    };

    QObject::connect(startButton, &QAbstractButton::clicked, &app, startTaskTree);
    QObject::connect(cancelButton, &QAbstractButton::clicked, &app, cancelTaskTree);
    QObject::connect(resetButton, &QAbstractButton::clicked, &app, resetTaskTree);

    mainWidget.show();

    return app.exec();

Este código:

  • Crea un QSingleTaskTreeRunner para ejecutar el árbol de tareas
  • Establece controladores para los botones Start, Cancel y Reset
  • Conecta la barra de progreso para seguir la ejecución de la tarea

Ejecutar el ejemplo

Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para más información, consulte Qt Creator: Tutorial: Construir y ejecutar.

Proyecto de ejemplo @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.