#include #include #include #include #include #include "waitwidget.h" CircularProgress::CircularProgress(QWidget* parent) : QProgressBar(parent) { init(); } CircularProgress::~CircularProgress() { } void CircularProgress::setProgressType(ProgressType type) { m_progressType = type; update(); } CircularProgress::ProgressType CircularProgress::progressType() const { return m_progressType; } void CircularProgress::setUseThemeColors(bool value) { if (m_useThemeColors == value) { return; } m_useThemeColors = value; update(); } bool CircularProgress::useThemeColors() const { return m_useThemeColors; } void CircularProgress::setLineWidth(qreal width) { m_penWidth = width; update(); updateGeometry(); } qreal CircularProgress::lineWidth() const { return m_penWidth; } void CircularProgress::setSize(int size) { m_size = size; update(); updateGeometry(); } int CircularProgress::size() const { return m_size; } void CircularProgress::setColor(const QColor& color) { m_color = color; update(); } QColor CircularProgress::color() const { if (m_useThemeColors || !m_color.isValid()) { return QColor(37, 177, 218); } else { return m_color; } } QSize CircularProgress::sizeHint() const { const qreal s = m_size + m_penWidth + 8; return QSize(s, s); } void CircularProgress::paintEvent(QPaintEvent* event) { Q_UNUSED(event) QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); if (!isEnabled()) { QPen pen; pen.setCapStyle(Qt::RoundCap); pen.setWidthF(m_penWidth); pen.setColor(QColor(186, 186, 186)); painter.setPen(pen); painter.drawLine(rect().center() - QPointF(20, 20), rect().center() + QPointF(20, 20)); painter.drawLine(rect().center() + QPointF(20, -20), rect().center() - QPointF(20, -20)); return; } if (IndeterminateProgress == m_progressType) { painter.translate(width() / 2, height() / 2); painter.rotate(m_delegate->angle()); } QPen pen; pen.setCapStyle(Qt::RoundCap); pen.setWidthF(m_penWidth); // 绘制底部环 pen.setColor(QColor(165, 165, 165)); painter.setPen(pen); painter.drawEllipse(QPoint(0, 0), m_size / 2, m_size / 2); pen.setColor(color()); if (IndeterminateProgress == m_progressType) { QVector pattern; pattern << m_delegate->dashLength() * m_size / 50 << 30 * m_size / 50; pen.setDashOffset(m_delegate->dashOffset() * m_size / 50); pen.setDashPattern(pattern); painter.setPen(pen); painter.drawEllipse(QPoint(0, 0), m_size / 2, m_size / 2); } else { painter.setPen(pen); const qreal x = (width() - m_size) / 2; const qreal y = (height() - m_size) / 2; const qreal a = 360 * (value() - minimum()) / (maximum() - minimum()); QPainterPath path; path.arcMoveTo(x, y, m_size, m_size, 0); path.arcTo(x, y, m_size, m_size, 0, a); painter.drawPath(path); } } void CircularProgress::init() { m_delegate = new CircularProgressDelegate(this); m_progressType = IndeterminateProgress; m_penWidth = 6.25; m_size = 64; m_useThemeColors = true; setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); QParallelAnimationGroup* group = new QParallelAnimationGroup(this); group->setLoopCount(-1); QPropertyAnimation* animation; animation = new QPropertyAnimation(this); animation->setPropertyName("dashLength"); animation->setTargetObject(m_delegate); animation->setEasingCurve(QEasingCurve::InOutQuad); animation->setStartValue(0.1); animation->setKeyValueAt(0.15, 0.2); animation->setKeyValueAt(0.6, 20); animation->setKeyValueAt(0.7, 20); animation->setEndValue(20); animation->setDuration(2050); group->addAnimation(animation); animation = new QPropertyAnimation(this); animation->setPropertyName("dashOffset"); animation->setTargetObject(m_delegate); animation->setEasingCurve(QEasingCurve::InOutSine); animation->setStartValue(0); animation->setKeyValueAt(0.15, 0); animation->setKeyValueAt(0.6, -7); animation->setKeyValueAt(0.7, -7); animation->setEndValue(-25); animation->setDuration(2050); group->addAnimation(animation); animation = new QPropertyAnimation(this); animation->setPropertyName("angle"); animation->setTargetObject(m_delegate); animation->setStartValue(0); animation->setEndValue(719); animation->setDuration(2050); group->addAnimation(animation); group->start(); } CircularProgressDelegate::CircularProgressDelegate(CircularProgress* parent) : QObject(parent), m_progress(parent), m_dashOffset(0), m_dashLength(89), m_angle(0) { Q_ASSERT(parent); } CircularProgressDelegate::~CircularProgressDelegate() { } void CircularProgressDelegate::setDashOffset(qreal offset) { m_dashOffset = offset; m_progress->update(); } qreal CircularProgressDelegate::dashOffset() const { return m_dashOffset; } void CircularProgressDelegate::setDashLength(qreal length) { m_dashLength = length; m_progress->update(); } qreal CircularProgressDelegate::dashLength() const { return m_dashLength; } void CircularProgressDelegate::setAngle(int angle) { m_angle = angle; m_progress->update(); } int CircularProgressDelegate::angle() const { return m_angle; } WaitProgressWidget::WaitProgressWidget(QWidget* parent) : QWidget(parent) , m_parentWidget(parent) { m_progress = new CircularProgress(this); this->setAutoFillBackground(true); this->hide(); QColor color(165, 165, 165); color.setAlphaF(0.6); this->setBgColor(color); auto waitBgLayout = new QHBoxLayout(this); waitBgLayout->addWidget(m_progress); waitBgLayout->setAlignment(m_progress, Qt::AlignCenter); parent->installEventFilter(this); m_timer = new QTimer(this); connect(m_timer, &QTimer::timeout, this, [this]() { if (!this->isHidden()) { stop(false); } }); connect(this, &WaitProgressWidget::sig_finished, [this](bool isok) { if (isok) { if (!this->isHidden()) { stop(false); } } else { if (this->isHidden()) { start(); } } }); } WaitProgressWidget::~WaitProgressWidget() { stop(true); if (m_timer) { delete m_timer; m_timer = NULL; } } void WaitProgressWidget::setBgColor(QColor color) { QPalette palette; palette.setColor(QPalette::Background, color); this->setPalette(palette); update(); } bool WaitProgressWidget::eventFilter(QObject* obj, QEvent* ev) { if (obj == m_parentWidget && ev->type() == QEvent::Resize) { if (!this->isHidden()) { this->setFixedSize(m_parentWidget->size()); this->raise(); } } return QWidget::eventFilter(obj, ev); } void WaitProgressWidget::showEvent(QShowEvent* ev) { Q_UNUSED(ev);// 屏蔽鼠标事件 this->setFixedSize(m_parentWidget->size()); this->raise(); } void WaitProgressWidget::start(int msecs) { m_timer->start(msecs); this->show(); } void WaitProgressWidget::stop(bool isOk) { m_timer->stop(); this->hide(); emit sig_finished(isOk); } void WaitProgressWidget::show() { QWidget::show(); } void WaitProgressWidget::hide() { QWidget::hide(); }