C++ 定制QProgressBar

C++ 定制QProgressBar,c++,qt,qprogressbar,C++,Qt,Qprogressbar,我有一个日记程序,用户可以在其中创建任务,然后在其中添加休息。每个任务对象都有QTime开始时间、QTime结束时间和向量的中断时间。每个Break都有QTime start\u time和QTime end\u time成员,就像任务一样。我想通过使用自定义QProgressBar显示“时间线”,可视化当前任务的进度。它应该是一条绿线,由表示中断的红色块和上面的三角形分隔,以指示当前进度。这是我的顶级画作: 要求:三角形应每隔一分钟左右平稳地向末端移动,不得跳跃。它还必须改变它的颜色,这取决

我有一个日记程序,用户可以在其中创建任务,然后在其中添加休息。每个
任务
对象都有
QTime开始时间
QTime结束时间
向量
中断时间。每个
Break
都有
QTime start\u time
QTime end\u time
成员,就像
任务一样。我想通过使用自定义
QProgressBar
显示“时间线”,可视化当前任务的进度。它应该是一条绿线,由表示中断的红色块和上面的三角形分隔,以指示当前进度。这是我的顶级画作:

要求:三角形应每隔一分钟左右平稳地向末端移动,不得跳跃。它还必须改变它的颜色,这取决于它是红色还是绿色。行必须可调整大小,但这不应影响
任务
s或
中断
s时间变量。用户不能在随后的时间内添加多个中断。
现在我的问题是,这可能吗?如果是,那么如何进行?
我试着做一个不间断的任务,只画一条绿线和一个没有红块的三角形,但我马上就遇到了调整大小的问题。如果线宽增加,那么三角形的“步长”也会增加。我试图实现这一点,但没有取得多大成功。
代码如下:

//class CustomProgressBar: public QProgressBar
void CustomProgressBar::paintEvent(QPaintEvent* event)
{
    setMaximum(this->width());
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    QPoint start_point;
    start_point.setX(0);
    start_point.setY(13);
    QPoint end_point;
    end_point.setY(13);
    end_point.setX(this->width()); //has to be resizable

    //"TimeLine"
    painter.setPen(QPen(Qt::green, 2, Qt::SolidLine, Qt::RoundCap));
    painter.drawLine(start_point, end_point);

    //Triangle
    int progress = this->value();
    QPoint triangle_start_point;
    triangle_start_point.setX(this->value() + this->width() / 15  + 1);
    triangle_start_point.setY(0);
    QPoint triangle_bot_point;
    triangle_bot_point.setX(this->value() + this->width() / 15 + 6);
    triangle_bot_point.setY(10);
    QPoint triangle_top_point;
    triangle_top_point.setX(this->value() + this->width() / 15 + 11);
    triangle_top_point.setY(0);
    QPainterPath path;
    path.moveTo(triangle_start_point);
    path.lineTo(triangle_bot_point);
    path.lineTo(triangle_top_point);
    path.lineTo(triangle_start_point);
    painter.setPen (Qt :: NoPen);
    painter.fillPath(path, QBrush(QColor (Qt::green)));
}

我调整了你的绘画活动,并扩展了一些简单的格式来显示休息和跑步,看看它

QList<QPoint> CustomProgessBar::breaks()
{
    QList<QPoint> times;
    times.append(QPoint(0, 20));
    times.append(QPoint(20, 50));
    times.append(QPoint(50, 80));
    times.append(QPoint(80, 100));
    return times;
}

void CustomProgessBar::paintEvent(QPaintEvent *e)
{
    Q_UNUSED(e)
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    QPoint start_point;
    start_point.setX(0);
    start_point.setY(13);
    QPoint end_point;
    end_point.setY(13);
    end_point.setX(this->width());

    //"TimeLine"
    for (int i = 0; i < breaks().length(); ++i) {
        start_point.setX((int)((float)this->width() / 100 * breaks().at(i).x()));
        end_point.setX((int)((float)this->width() / 100 * breaks().at(i).y()));
        if (i % 2 == 0) {
            painter.setPen(QPen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap));
        } else {
            painter.setPen(QPen(Qt::green, 2, Qt::SolidLine, Qt::RoundCap));
        }
        painter.drawLine(start_point, end_point);
    }

    //Triangle
    QPoint triangle_start_point;
    triangle_start_point.setX((int)((float)this->width() / this->maximum() * this->value()) - 5);
    triangle_start_point.setY(0);
    QPoint triangle_bot_point;
    triangle_bot_point.setX((int)((float)this->width() / this->maximum() * this->value()) + 0);
    triangle_bot_point.setY(10);
    QPoint triangle_top_point;
    triangle_top_point.setX((int)((float)this->width() / this->maximum() * this->value()) + 5);
    triangle_top_point.setY(0);
    QPainterPath path;
    path.moveTo(triangle_start_point);
    path.lineTo(triangle_bot_point);
    path.lineTo(triangle_top_point);
    path.lineTo(triangle_start_point);
    painter.setPen (Qt :: NoPen);

    for (int i = 0; i < breaks().length(); ++i) {
        int x = (int)((float)triangle_bot_point.x() * 100 / this->width());
        if (x >= breaks().at(i).x() && x <= breaks().at(i).y() && i % 2 == 0)
            painter.fillPath(path, QBrush(QColor (Qt::red)));
        if (x >= breaks().at(i).x() && x <= breaks().at(i).y() && i % 2 == 1)
            painter.fillPath(path, QBrush(QColor (Qt::green)));
    }
}
QList CustomProgessBar::breaks() { QList时代; 追加(QPoint(0,20)); 追加(QPoint(20,50)); 追加(QPoint(50,80)); 追加(QPoint(80100)); 返回次数; } void CustomProgessBar::paintEvent(QPaintEvent*e) { Q_(e) 油漆工(本); painter.setRenderHint(QPainter::抗锯齿,true); QPoint起点; 起始点setX(0); 起始点setY(13); QPoint end_point; 终点setY(13); end_point.setX(this->width()); //“时间线” 对于(int i=0;iwidth()/100*breaks().at(i.x()); 端点.setX((int)((float)this->width()/100*breaks().at(i).y()); 如果(i%2==0){ setPen(QPen(Qt::red,2,Qt::SolidLine,Qt::RoundCap)); }否则{ setPen(QPen(Qt::green,2,Qt::SolidLine,Qt::RoundCap)); } 绘制线(起点、终点); } //三角 点三角形\起点\点; 三角形的起点。setX((int)((float)this->width()/this->max()*this->value())-5); 三角形的起始点setY(0); 点三角形\机器人\点; 三角形\u bot\u point.setX((int)((float)this->width()/this->max()*this->value())+0); 三角形机器人点setY(10); 点三角形\顶点\点; 三角形顶点。setX((int)((float)this->width()/this->max()*this->value())+5); 三角形顶点集(0); QPainterPath路径; 移动到(三角形的起点); lineTo(三角点); lineTo(三角形顶点); lineTo(三角形\起点\点); painter.setPen(Qt::NoPen); 对于(int i=0;iwidth());
如果(x>=breaks().at(i).x()&&x=breaks().at(i).x()&&x即使这样做有效,也不能满足所有要求。我一定会尝试使用“时间线”和三角形着色部分,但目前我不能接受这个答案。如果我能想出一个使用您的代码的有效实现,我会在编辑中发布它并接受您的答案。@7Y3RPXK3ETDCNRDD行可以调整大小,着色有效,没有跳跃。哪些要求没有得到满足?而是给您一个完整的解决方案,所有类都能很好地工作但答案解决了你的问题,让你更进一步。我不明白你的意思。你的代码解决了部分问题,但不是全部问题。三角形表示从
任务到
任务的进度。开始时间
任务。结束时间
,也就是说,它应该移动固定的次数,但其“步数”(每次前进通过的像素数)我还写了
Break
s有
start\u time
end\u time
,还有一个
Break
s向量。所以红色块的大小和数量可能有所不同。也许我在我的帖子中不够明确。如果是这样的话,我很抱歉搞混了。但我还是不能接受你的答案,bec因为问题尚未完全解决。@7Y3RPXK3ETDCNRDD仔细查看方法
breaks
,该方法返回一个同时包含breaks和progression的
QList
。每个元素都有起点和终点,这两个起点和终点可能各不相同。因此,这一步已经完成。
paint
方法使用一些模2操作进行着色,因此每个元素cond entry是一个break。这只是两种状态的简单转换。您也可以很容易地在队列中纠缠另一个break,请注意,所选的值与进度条的最大数量相匹配。而且,三角形不是直接移动一个像素,而是正好移动
QProgressBar
的一个值。完成