我有一个日记程序,其中用户可以创建任务,然后添加休息。每个Task对象都有一个QTime start_time、QTime end_time和vector of Breaks。每个Break都有一个QTime start_time和QTime end_time成员,就像Task一样。我想通过使用自定义QProgressBar来显示“时间线”来可视化当前任务的进度。它应该是一条由红色块分隔的绿线,红色块表示中断,上面的三角形表示当前进度。这是我最好的画作:

要求:三角形应该每分钟左右平稳地向末端移动,并且不能跳跃。它还必须改变它的颜色,这取决于它是红色块还是绿色块。行必须是可调整大小的,但这不应该影响task或break的时间变量。用户不能添加具有后续时间的多个中断。
现在我的问题是,这有可能吗?如果是,那是怎么做的?
我试着不间断地做一项任务,只画一条绿线和一个没有红色块的三角形,但我立即遇到了调整大小的问题。如果线条宽度增加,那么三角形的“按分钟步长”也应该增加。我试图实现这一点,但没有取得太大的成功。
代码如下:
//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)));
}发布于 2016-07-30 04:01:57
我调整了你的paint事件,并扩展了一些简单的格式来显示中断和奔跑,看看这个。
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)));
}
}上面提到的跳跃是由于整数运算造成的。强制转换为float和back可以修复此行为。
此外,不要尝试将开始和停止时间与图形上的开始和停止点紧密地联系在一起。在所提供的示例中,我有一个中间步骤,它生成百分比值。
https://stackoverflow.com/questions/38661229
复制相似问题