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?
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();
}