TaskTree 演示
演示了不同的执行模式和工作流策略如何影响复杂的 TaskTree 执行。
TaskTree 演示展示了如何使用 `timeoutTask` 构建嵌套的 TaskTree 配方,并演示了不同的 `execution modes ` 和 `workflow policies`。该应用程序通过图形化界面,直观展示 TaskTree 在执行构成任务的各项工作项时的进度概览。

该演示应用程序使用单个 QWidget 来显示和管理 TaskTree 层次结构。界面中包含以下内容:
- 任务以叶节点形式显示在树的右侧。
对于每个任务,您可以设置执行时长,并配置成功或错误的完成状态。
- 组节点显示在树的左侧和中部。
每个组可以包含多个子任务或嵌套组。您可以为每个组配置execution modes 和workflow policies 。
- 颜色指示器显示每个节点的当前执行状态。
以下各节将详细介绍该示例代码。
辅助粘合类
GlueItem 抽象类将用户界面(UI)组件与其对应的 TaskTree 配方连接起来。这种设计模式实现了 UI 与任务逻辑之间的清晰分离。
class GlueItem
{
public:
virtual ExecutableItem recipe() const = 0;
virtual QWidget *widget() const = 0;
virtual void reset() const = 0;
virtual ~GlueItem() = default;
};GlueItem 类定义了三个关键的虚方法:
| 方法 | 用途 |
|---|---|
recipe() | 创建并返回一个定义该项行为的 TaskTree 配方 |
widget() | 提供对相关 UI 组件的访问权限 |
reset() | 将 UI 组件恢复到初始状态 |
GroupGlueItem 类用于管理任务层次结构中的Group 元素。每个组都可以将其他GlueItem 元素作为子元素包含其中,包括嵌套的GroupGlueItem或TaskGlueItem。
以下是recipe() 方法如何创建和配置一个组:
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)); })
};
}实现的关键组件:
- 创建一个包含子配方的新Group
- 根据 UI 设置应用 `execution mode ` 和 `workflow policy `
- 在执行开始时使用 `onGroupSetup()` 更新 UI
- 使用 `onGroupDone()` 在 UI 中反映执行结果
TaskGlueItem 类通过timeoutTask 实现任务树中的叶节点。
以下是创建任务的 `recipe() ` 实现:
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)); })
};
}实现代码:
- 创建一个Group ,该类封装了一个timeoutTask
- 使用 UI 设置配置持续时间和预期结果
- 在任务开始时通过 `onGroupSetup()` 更新 UI 状态
- 通过 `onGroupDone()` 反映任务完成状态
构建任务层次结构
两个辅助方法可简化任务树的创建:
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(): 创建一个新的GroupGlueItemtask(): 创建一个新的TaskGlueItem
定义树结构
以下代码演示了如何构建完整的任务层次结构:
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()
})
};您可以修改上述结构来创建不同的树结构。
将 UI 与 TaskTree 连接
最后一步是将任务树与应用程序的用户界面控件连接起来:
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();此代码:
- 创建一个 QSingleTaskTreeRunner 来执行任务树
- 为“开始”、“取消”和“重置”按钮设置处理程序
- 连接进度条以跟踪任务执行情况
运行示例
您可以通过以下方式运行示例:
- Qt Creator
打开“Welcome ”模式,并从“Examples ”中选择该示例。有关更多信息,请参阅Qt Creator :教程:构建和运行。
- Qt Extension for Visual Studio Code
在Command Palette 中运行Qt: Open Qt examples 命令,并从列表中选择该示例。有关详细信息,请参阅Qt Extension for Visual Studio Code :教程:构建和运行。
© 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.