#include "ProgressBar.h" #include ProgressBar::ProgressBar(const QVector& tickList, QWidget *parent) : QWidget(parent), mTickList(tickList) { setAttribute(Qt::WA_OpaquePaintEvent, true); mTimer = startTimer(30); } double ProgressBar::getDrawWidth(double value) { int n = mTickList.size(); int i = 1; for(; i < n - 1; ++i) { double cur = mTickList[i].mValue; if(mValue < cur || qFuzzyCompare(mValue, cur)) { break; } } int lowerOffset = i - 1; int upperOffset = i; double lower = mTickList[lowerOffset].mValue; double upper = mTickList[upperOffset].mValue; double w_step = (double)QWidget::width()/(double)(n-1); double lastRate = qMax(0.0, (mValue - lower)/(upper - lower)); double drawWidth = w_step * (lastRate + lowerOffset); QString ticks; for(Tick& tick : mTickList) { ticks.append(" " + QString::number(tick.mValue)); } // qDebug() << QString("%1->[%2,%3] i=%4 n=%5 drawWidth:%6 width:%7 ticks:%8 w_step:%9 lastRate:%10") // .arg(mValue).arg(lower).arg(upper).arg(i).arg(n).arg(drawWidth).arg(width()).arg(ticks) // .arg(w_step).arg(lastRate); return drawWidth; } void ProgressBar::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setPen(Qt::NoPen); painter.fillRect(rect(), QApplication::style()->standardPalette().brush(QPalette::Window)); painter.setPen(QPen(Qt::black)); auto w = (double)QWidget::width(); auto hh = (double)height()/2; int n = mTickList.size(); int tickW = 1; double drawWidth = getDrawWidth(mValue); // 背景 painter.fillRect(0, 0, drawWidth - tickW - 4, height()/2, Qt::black); int curX = 0; // 进度条 while(curX + tickW + 4 < drawWidth){ painter.fillRect(curX, 0, tickW, height()/2, Qt::gray); curX += tickW + (int)mTickSpaceW; } int lineY = (int)hh + 2; painter.fillRect(curX -(int)mTickSpaceW , 0, 4, lineY - 0, Qt::yellow); painter.drawLine(0, lineY , (int)w, lineY); // 画刻度 QFont font; font.setBold(true); QFontMetrics fm(font); for(int i = 0; i < n; ++i){ int tickX = (int)((double)(QWidget::width() * i)/(double)(n - 1)); int textW = fm.horizontalAdvance( mTickList[i].mText); int textX; if(i == n - 1) { textX = tickX - textW; tickX -=1; } else if( i == 0) { textX = tickX; } else { textX = tickX - textW/2; } painter.setPen(Qt::black); painter.drawLine(tickX, lineY, tickX, (lineY + 5)); painter.setPen(mTickList[i].mColor); painter.setFont(font); painter.drawText(QRectF(textX, lineY, textW, lineY), Qt::AlignCenter, mTickList[i].mText); } } void ProgressBar::timerEvent(QTimerEvent *event) { if(event->timerId() == mTimer) { if(mSetValue) mSetValue(); update(); } QObject::timerEvent(event); }