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
的一个值。完成