自定义内存分配池
This commit is contained in:
@@ -1,13 +1,21 @@
|
||||
#include "ProgressBar.h"
|
||||
#include <QPainter>
|
||||
#include <QMetaObject>
|
||||
#include <QThread>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
Progress_Bar::Progress_Bar(const QVector<Tick>& tick_list, QWidget *parent) : QWidget(parent), tick_list(tick_list) {
|
||||
Progress_Bar::Progress_Bar(const std::vector<Tick>& tick_list, QWidget *parent) : QWidget(parent), tick_list(tick_list) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||
timer = startTimer(30);
|
||||
}
|
||||
|
||||
double Progress_Bar::get_draw_width(double value) {
|
||||
int n = tick_list.size();
|
||||
if (n < 2 || QWidget::width() <= 0)
|
||||
return 0.0;
|
||||
if (!std::isfinite(value))
|
||||
value = tick_list.front().value;
|
||||
int i = 1;
|
||||
for(; i < n - 1; ++i) {
|
||||
double cur = tick_list[i].value;
|
||||
@@ -20,21 +28,28 @@ double Progress_Bar::get_draw_width(double value) {
|
||||
double lower = tick_list[lower_offset].value;
|
||||
double upper = tick_list[upper_offset].value;
|
||||
double w_step = (double)QWidget::width()/(double)(n-1);
|
||||
double last_rate = qMax(0.0, (value - lower)/(upper - lower));
|
||||
double last_rate = upper == lower ? 0.0 : (value - lower)/(upper - lower);
|
||||
last_rate = std::clamp(last_rate, 0.0, 1.0);
|
||||
double draw_width = w_step * (last_rate + lower_offset);
|
||||
QString ticks;
|
||||
for(Tick& tick : tick_list) {
|
||||
ticks.append(" " + QString::number(tick.value));
|
||||
}
|
||||
// qDebug() << QString("%1->[%2,%3] i=%4 n=%5 draw_width:%6 width:%7 ticks:%8 w_step:%9 last_rate:%10")
|
||||
// .arg(value).arg(lower).arg(upper).arg(i).arg(n).arg(draw_width).arg(width()).arg(ticks)
|
||||
// .arg(w_step).arg(last_rate);
|
||||
return draw_width;
|
||||
return std::clamp(draw_width, 0.0, (double)QWidget::width());
|
||||
}
|
||||
void Progress_Bar::setValue(double value) {
|
||||
if (thread() != QThread::currentThread()) {
|
||||
queued_value.store(value, std::memory_order_release);
|
||||
if (!queued_value_update.exchange(true, std::memory_order_acq_rel)) {
|
||||
QMetaObject::invokeMethod(this, [this]() {
|
||||
double value = queued_value.load(std::memory_order_acquire);
|
||||
queued_value_update.store(false, std::memory_order_release);
|
||||
setValue(value);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this->value = value;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Progress_Bar::paintEvent(QPaintEvent *event) {
|
||||
Q_UNUSED(event)
|
||||
QPainter painter(this);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.fillRect(rect(), QApplication::style()->standardPalette().brush(QPalette::Window));
|
||||
@@ -44,18 +59,19 @@ void Progress_Bar::paintEvent(QPaintEvent *event) {
|
||||
int n = tick_list.size();
|
||||
int tick_w = 1;
|
||||
double draw_width = get_draw_width(value);
|
||||
// 背景
|
||||
painter.fillRect(0, 0, draw_width - tick_w - 4, height()/2, Qt::black);
|
||||
int fill_width = std::max(0, static_cast<int>(draw_width) - tick_w - 4);
|
||||
if (fill_width > 0)
|
||||
painter.fillRect(0, 0, fill_width, height()/2, Qt::black);
|
||||
int cur_x = 0;
|
||||
// 进度条
|
||||
int tick_step = std::max(1, tick_w + (int)tick_space_w);
|
||||
while(cur_x + tick_w + 4 < draw_width){
|
||||
painter.fillRect(cur_x, 0, tick_w, height()/2, Qt::gray);
|
||||
cur_x += tick_w + (int)tick_space_w;
|
||||
cur_x += tick_step;
|
||||
}
|
||||
int line_y = (int)hh + 2;
|
||||
painter.fillRect(cur_x -(int)tick_space_w , 0, 4, line_y - 0, Qt::yellow);
|
||||
int marker_x = std::clamp(cur_x - (int)tick_space_w, 0, std::max(0, QWidget::width() - 4));
|
||||
painter.fillRect(marker_x, 0, 4, line_y, Qt::yellow);
|
||||
painter.drawLine(0, line_y , (int)w, line_y);
|
||||
// 画刻度
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
QFontMetrics fm(font);
|
||||
|
||||
Reference in New Issue
Block a user