Qt/C++实现的甘特图,有四种算法形式设置甘特图,可以设置任务条的数量,可以设置任务条的长度以及相对于X轴的先后顺序,可以将甘特图的任务条分割显示。 显示的面板是使用graphicsView控件实现的。 源码: 使用Qt5.5.1_MinGW、Qt5.6.1_MinGW、Qt5.13.1_MinGW编译通过,其他Qt版本请自行尝试。 c1.74

首先,我们来看一下实现的功能特点:

  1. 支持四种不同的算法设置甘特图布局
  2. 可以动态设置任务条的数量
  3. 支持自定义任务条的长度和顺序
  4. 任务条可以分段显示
  5. 使用GraphicsView作为显示面板,保证了良好的渲染性能

甘特图的基本结构

在开始动手编码之前,我们需要明确甘特图的基本结构。每个任务条由以下几个部分组成:

  • 任务名称
  • 任务开始时间
  • 任务时长
  • 任务进度
  • 任务颜色

为了方便管理任务,我们定义了一个Task结构体:

struct Task {
    QString name;       // 任务名称
    int start;          // 任务开始位置
    int length;         // 任务时长
    int progress;       // 任务进度
    QColor color;       // 任务颜色
    bool segmented;      // 是否分段显示
};

甘特图的绘制

甘特图的绘制核心在于GraphicsView的使用。我们通过重写paintEvent函数来实现自定义的绘制逻辑。以下是关键代码段:

void GanttChart::paintEvent(QPaintEvent *event) {
    QStyleOptionGraphicsItem option;
    option.rect = rect();
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing); // 启用抗锯齿
    painter.setPen(QPen(Qt::black, 1));            // 设置边框颜色和宽度

    // 绘制时间轴
    drawTimeAxis(&painter);

    // 绘制任务条
    drawTaskBars(&painter);

    // 绘制网格线
    drawGrid(&painter);
}

动态设置任务条

我们可以通过以下方法动态设置任务条的数量和属性:

// 添加任务条
void GanttChart::addTask(const Task &task) {
    tasks.append(task);
    update(); // 刷新视图
}

// 设置任务条分段显示
void GanttChart::setTaskSegmented(int index, bool segmented) {
    if (index >= 0 && index < tasks.size()) {
        tasks[index].segmented = segmented;
        update();
    }
}

分段显示任务条

为了实现任务条的分段显示,我们在绘制任务条时对任务进行判断:

void GanttChart::drawTaskBars(QPainter *painter) {
    foreach (const Task &task, tasks) {
        if (task.segmented) {
            // 绘制分段任务条
            int segments = 5; // 分成5段
            int segmentWidth = task.length / segments;
            
            for (int i = 0; i < segments; i++) {
                int x = task.start + i * segmentWidth;
                painter->drawRect(x, 0, segmentWidth, height());
            }
        } else {
            // 绘制整体任务条
            painter->drawRect(task.start, 0, task.length, height());
        }
    }
}

GraphicsView的选择

选择GraphicsView作为显示面板的原因在于它提供了更好的渲染性能和更灵活的图形操作。我们可以通过以下代码初始化GraphicsView:

GanttChart::GanttChart(QWidget *parent) : QGraphicsView(parent) {
    setRenderHint(QPainter::Antialiasing); // 启用抗锯齿
    setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); // 智能视口更新
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); // 显示水平滚动条
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 隐藏垂直滚动条
}

兼容性测试

为了确保代码的稳定性,我们在多个Qt版本上进行了测试:

- Qt 5.5.1_MinGW
- Qt 5.6.1_MinGW
- Qt 5.13.1_MinGW

其他版本的Qt可能需要根据具体情况进行调整。

总结

通过以上方法,我们实现了一个功能完善的甘特图控件。关键点在于:

  1. 使用GraphicsView实现高效的图形渲染
  2. 灵活的任务条管理接口
  3. 支持任务条的分段显示
  4. 优秀的跨平台兼容性

如果你有更多的需求,可以在现有代码基础上进行扩展和优化。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐