Is there circular QProgressbar with range (0,0) in

2020-05-09 11:51发布

问题:

I want to have circular QProgressbar which it's appearance must look like the normal QProgressbar with the Range between 0 and 0.

The code for the linear QProgressbar is some thing like below:

QProgressBar *_progressBar = new QProgressBar();
_progressBar->setTextVisible(false);
_progressBar->setRange(0, 0);

but I want it to be circular. Is there any way to implement it in qt?

回答1:

One day I wrote a simple class to implement a circular progress bar for my purposes (Qt 4.6). You can modify its appearance as you need. Hope it will help.

loading.h

#pragma once

#include <QtGui>

class Loading : public QWidget {
    Q_OBJECT
public:
    explicit Loading(QWidget *parent);

protected:
    double current;
    bool eventFilter(QObject *obj, QEvent *ev);
    bool event(QEvent *);
    void paintEvent(QPaintEvent *);
    void timerEvent(QTimerEvent *);
};

loading.cpp

#include "loading.h"

/**
 * @brief Creates a circular loading
 * @param parent - non-NULL widget that will be contain a circular loading
 */
Loading::Loading(QWidget *parent) : QWidget(parent), current(0) {
    Q_ASSERT(parent);
    parent->installEventFilter(this);
    raise();
    setAttribute(Qt::WA_TranslucentBackground);
    startTimer(20);
}

bool Loading::eventFilter(QObject *obj, QEvent *ev) {
    if (obj == parent()) {
        if (ev->type() == QEvent::Resize) {
            QResizeEvent * rev = static_cast<QResizeEvent*>(ev);
            resize(rev->size());
        }
        else if (ev->type() == QEvent::ChildAdded)
            raise();
    }
    return QWidget::eventFilter(obj, ev);
}

bool Loading::event(QEvent *ev) {
    if (ev->type() == QEvent::ParentAboutToChange) {
        if (parent()) parent()->removeEventFilter(this);
    }
    else if (ev->type() == QEvent::ParentChange) {
        if (parent()) {
            parent()->installEventFilter(this);
            raise();
        }
    }
    return QWidget::event(ev);
}

void Loading::paintEvent(QPaintEvent *) {
    QPainter p(this);
    p.fillRect(rect(), QColor(100, 100, 100, 64));

    QPen pen;
    pen.setWidth(12);
    pen.setColor(QColor(0, 191, 255));  // DeepSkyBlue
    p.setPen(pen);

    p.setRenderHint(QPainter::Antialiasing);

    QRectF rectangle(width()/2 - 40.0, height()/2 - 40.0, 80.0, 80.0);

    int spanAngle = (int)(qMin(0.2, current) * 360 * -16);
    int startAngle = (int)(qMin(0.0, 0.2 - current) * 360 * 16);

    p.drawArc(rectangle, startAngle, spanAngle);
}

void Loading::timerEvent(QTimerEvent *) {
    if (isVisible()) {
        current += 0.03;
        if (current > 1.2) current = 0.2; // restart cycle
        update();
    }
}

Usage

#include "loading.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QLabel w;
    w.setMinimumSize(400, 400);
    Loading *loading = new Loading(&w);
    QTimer::singleShot(4000, loading, SLOT(hide()));
    w.show();
    return a.exec();
}