好的,我可以帮你整理一份 Qt 实战教程:第16章 构建甘特图 的思路与实现方法。这里我会把步骤、关键类、绘图思路和示例代码都整理出来,方便你快速上手。
Qt 实战 16:构建甘特图
一、甘特图概述
甘特图(Gantt Chart)是一种常用的项目管理工具,用于展示任务的时间进度和依赖关系。
特点:
- 横轴:时间轴
- 纵轴:任务列表
- 图形表示:任务条、完成比例、里程碑、依赖关系箭头
在 Qt 中,常用 QGraphicsView / QGraphicsScene 或 QTableView + 自定义绘制 来实现甘特图。
二、关键技术点
- 任务数据模型
- 定义任务类 Task:
class Task { public: QString name; QDate startDate; QDate endDate; double progress; // 0.0~1.0 QList<Task*> dependencies; };
- 可以用 QList 或 QStandardItemModel 保存任务列表。
- 时间轴映射
- 将日期映射到横坐标:
int dayWidth = 20; // 每天的像素宽度 int x = (task.startDate.toJulianDay() - projectStartDate.toJulianDay()) * dayWidth; int width = (task.endDate.toJulianDay() - task.startDate.toJulianDay()) * dayWidth;
- 绘制任务条
- 使用 QGraphicsRectItem 或 QPainter 绘制任务条:
QGraphicsRectItem *rect = scene->addRect(x, y, width, taskHeight, pen, brush);
- 可使用 不同颜色表示任务状态:
- 绿色:已完成
- 蓝色:进行中
- 灰色:未开始
- 绘制依赖箭头
- 使用 QGraphicsLineItem 或 QPainterPath 画箭头:
QGraphicsLineItem *line = scene->addLine(x1, y1, x2, y2, pen);
- 可以添加三角形箭头表示依赖方向。
- 绘制时间刻度
- 横轴显示日期:
for (QDate date = projectStartDate; date <= projectEndDate; date = date.addDays(1)) { int x = (date.toJulianDay() - projectStartDate.toJulianDay()) * dayWidth; scene->addLine(x, 0, x, 20, pen); // 刻度线 scene->addText(date.toString("MM-dd"))->setPos(x, 0); }
- 任务滚动和缩放
- 使用 QGraphicsView 的 setHorizontalScrollBarPolicy / setVerticalScrollBarPolicy
- 支持鼠标滚轮缩放时间轴(可用 QTransform 缩放)
三、示例代码(核心部分)
// main.cpp
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QDate>
#include <QBrush>
struct Task {
QString name;
QDate startDate;
QDate endDate;
double progress; // 0~1
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
int dayWidth = 20;
int taskHeight = 20;
QDate projectStart = QDate::currentDate();
QList<Task> tasks = {
{"Task 1", projectStart, projectStart.addDays(5), 0.5},
{"Task 2", projectStart.addDays(3), projectStart.addDays(10), 0.2},
{"Task 3", projectStart.addDays(6), projectStart.addDays(12), 0.0}
};
int y = 30;
for (const Task &task : tasks) {
int x = (task.startDate.toJulianDay() - projectStart.toJulianDay()) * dayWidth;
int width = (task.endDate.toJulianDay() - task.startDate.toJulianDay()) * dayWidth;
QGraphicsRectItem *rect = scene.addRect(x, y, width, taskHeight, QPen(Qt::black), QBrush(Qt::blue));
// 绘制完成进度
scene.addRect(x, y, width*task.progress, taskHeight, Qt::NoPen, QBrush(Qt::green));
y += taskHeight + 10;
}
view.setScene(&scene);
view.setWindowTitle("Qt 甘特图示例");
view.show();
return a.exec();
}
✅ 特点:
- 支持基本任务条显示
- 绘制任务完成进度
- 横向时间映射到像素
四、扩展功能建议
- 里程碑标记
- 使用三角形或小圆点表示关键时间点。
- 任务拖动修改
- 为 QGraphicsRectItem 添加 鼠标事件,拖动修改开始/结束时间。
- 多行任务显示
- 支持任务嵌套或子任务,用缩进或颜色区分。
- 数据导入导出
- 从 JSON / XML / CSV 导入任务
- 支持导出甘特图为 PNG / PDF
- UI 美化
- 使用渐变填充任务条
- 支持主题切换(暗色模式/浅色模式)
发表回复