Progress Bar: Difference between revisions
No edit summary |
(Cleanup) |
||
(6 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{LangSwitch}} | |||
[[Category:HowTo]] | [[Category:HowTo]] | ||
[[Category:Snippets]] | [[Category:Snippets]] | ||
[[Category:Tutorial]] | [[Category:Tutorial]] | ||
It is often necessary to display a progress bar while a long operation is happening. The case we are concerned about in this example is when there is no easy way to track the progress of the operation - all that is known is when it is done. There are many ways to do this. You could use a progressBar widget on your widget and run the operation in a different thread (using moveToThread()). This typically requires a special object to be created (a subclass of [http://doc.qt.io/qt-5/qobject.html QObject] that runs the operation and then emits a finished() signal), which can be a pain if you need to do this for many different operations. | |||
[ | However, using [http://doc.qt.io/qt-5/qfuturewatcher.html QFutureWatcher] and [http://doc.qt.io/qt-5/qtconcurrentrun.html QtConcurrent::run()], this is extremely easy. Below we demonstrate how to use this technique with both a [http://doc.qt.io/qt-5/qprogressdialog.html QProgressDialog] and a [http://doc.qt.io/qt-5/qprogressbar.html QProgressBar]. | ||
== QProgressBar Example == | == QProgressBar Example == | ||
Line 63: | Line 59: | ||
this->progressBar->hide(); | this->progressBar->hide(); | ||
connect(& | connect(&this->FutureWatcher, SIGNAL (finished()), this, SLOT (slot_finished())); | ||
} | } | ||
Line 77: | Line 73: | ||
// Start the computation. | // Start the computation. | ||
QFuture<void> future = QtConcurrent::run(& | QFuture<void> future = QtConcurrent::run(&this->MyObject, &MyClass::LongFunction); | ||
this->FutureWatcher.setFuture(future); | this->FutureWatcher.setFuture(future); | ||
} | } | ||
Line 244: | Line 240: | ||
this->ProgressDialog = new QProgressDialog(this); | this->ProgressDialog = new QProgressDialog(this); | ||
connect(& | connect(&this->FutureWatcher, SIGNAL (finished()), this, SLOT (slot_finished())); | ||
connect(& | connect(&this->FutureWatcher, SIGNAL (finished()), this->ProgressDialog , SLOT (cancel())); | ||
} | } | ||
Line 257: | Line 253: | ||
{ | { | ||
// Start the computation. | // Start the computation. | ||
QFuture<void> future = QtConcurrent::run(& | QFuture<void> future = QtConcurrent::run(&this->MyObject, &MyClass::LongFunction); | ||
this->FutureWatcher.setFuture(future); | this->FutureWatcher.setFuture(future); | ||
Latest revision as of 22:25, 27 June 2015
En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh
It is often necessary to display a progress bar while a long operation is happening. The case we are concerned about in this example is when there is no easy way to track the progress of the operation - all that is known is when it is done. There are many ways to do this. You could use a progressBar widget on your widget and run the operation in a different thread (using moveToThread()). This typically requires a special object to be created (a subclass of QObject that runs the operation and then emits a finished() signal), which can be a pain if you need to do this for many different operations.
However, using QFutureWatcher and QtConcurrent::run(), this is extremely easy. Below we demonstrate how to use this technique with both a QProgressDialog and a QProgressBar.
QProgressBar Example
form.h
#ifndef FORM_H
#define FORM_H
#include "ui_form.h"
#include <QFutureWatcher>
#include "MyClass.h"
class Form : public QWidget, private Ui::Form
{
Q_OBJECT
public slots:
void slot_finished();
void on_pushButton_clicked();
public:
Form(QWidget *parent = 0);
private:
QFutureWatcher<void> FutureWatcher;
MyClass MyObject;
};
#endif
form.cpp
#include <QtGui>
#include <QImage>
#include "form.h"
#include <iostream>
Form::Form(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
this->progressBar->setMinimum(0);
this->progressBar->setMaximum(0);
this->progressBar->hide();
connect(&this->FutureWatcher, SIGNAL (finished()), this, SLOT (slot_finished()));
}
void Form::slot_finished()
{
this->progressBar->hide();
}
void Form::on_pushButton_clicked()
{
this->progressBar->show();
// Start the computation.
QFuture<void> future = QtConcurrent::run(&this->MyObject, &MyClass::LongFunction);
this->FutureWatcher.setFuture(future);
}
form.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>24</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
FutureWatcher.cpp
#include <QApplication>
#include <QObject>
#include <QThread>
#include <iostream>
#include "form.h"
int main(int argc, char*argv[])
{
QApplication app(argc, argv);
Form form;
form.show();
return app.exec();
}
MyClass.h
#ifndef MyClass_H
#define MyClass_H
#include <iostream>
class MyClass
{
public:
void LongFunction()
{
for( int count = 0; count < 5; count++ )
{
sleep( 1 );
std::cout << "Ping long!" << std::endl;
}
}
};
#endif
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
PROJECT (FutureWatcher)
FIND_PACKAGE(Qt4 REQUIRED)
INCLUDE (${QT_USE_FILE})
QT4_WRAP_CPP(MOCSrcs form.h)
QT4_WRAP_UI(UISrcs form.ui)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
ADD_EXECUTABLE(FutureWatcher FutureWatcher.cpp MyClass.cpp form.cpp ${MOCSrcs} ${UISrcs})
TARGET_LINK_LIBRARIES(FutureWatcher ${QT_LIBRARIES})
QProgressDialog Example
form.h
#ifndef FORM_H
#define FORM_H
#include "ui_form.h"
#include <QFutureWatcher>
#include "MyClass.h"
class QProgressDialog;
class Form : public QWidget, private Ui::Form
{
Q_OBJECT
public slots:
void slot_finished();
void on_pushButton_clicked();
public:
Form(QWidget '''parent = 0);
private:
QFutureWatcher<void> FutureWatcher;
MyClass MyObject;
QProgressDialog''' ProgressDialog;
};
#endif
form.cpp
#include <QtGui>
#include <QImage>
#include "form.h"
#include <iostream>
Form::Form(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
this->ProgressDialog = new QProgressDialog(this);
connect(&this->FutureWatcher, SIGNAL (finished()), this, SLOT (slot_finished()));
connect(&this->FutureWatcher, SIGNAL (finished()), this->ProgressDialog , SLOT (cancel()));
}
void Form::slot_finished()
{
std::cout << "Finshed" << std::endl;
}
void Form::on_pushButton_clicked()
{
// Start the computation.
QFuture<void> future = QtConcurrent::run(&this->MyObject, &MyClass::LongFunction);
this->FutureWatcher.setFuture(future);
this->ProgressDialog->setMinimum(0);
this->ProgressDialog->setMaximum(0);
this->ProgressDialog->setWindowModality(Qt::WindowModal);
this->ProgressDialog->exec();
}
form.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
MyClass.h
#ifndef MyClass_H
#define MyClass_H
#include <iostream>
class MyClass
{
public:
void LongFunction()
{
for( int count = 0; count < 5; count++ )
{
sleep( 1 );
std::cout << "Ping long!" << std::endl;
}
}
};
#endif
FutureWatcherProgressDialog.cpp
#include <QApplication>
- include <QObject>
- include <QThread>
- include <iostream>
- include "form.h"
int main(int argc, char*argv[])
{
QApplication app(argc, argv);
Form form;
form.show();
return app.exec();