In the mainwindow.ui
I created a QProgressBar
named progressBar
and a QPushButton
named speckle
which starts the heavy computation.
Inside the mainwindow.h
I have an appropriate private slot
for the button and a private function which represents the heavy computation. mainwindow.h
:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_speckle_clicked();
...
private:
Ui::MainWindow *ui;
QFutureWatcher<std::vector<cv::Mat>> futureWatcher;
std::vector<cv::Mat> progressSpecle();//heavy computation
};
The futureWatcher
is supposed to watch the the QFuture
object that gets returned from QtConcurrent
:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
...
connect(&this->futureWatcher, SIGNAL(progressValueChanged(int)), ui->progressBar, SLOT(setValue(int)));
...
}
...
void MainWindow::on_speckle_clicked()
{
//Start the computation.
QFuture<std::vector<cv::Mat>> future;
future = QtConcurrent::run(this, &MainWindow::progressSpecle);
this->futureWatcher.setFuture(future);
QThreadPool::globalInstance()->waitForDone();
vector<cv::Mat> result = future.result();
specklevisualization *s = new specklevisualization;
s-> setAttribute(Qt::WA_DeleteOnClose);
s-> start(result);
s-> show();
}
But the the application does not work like that. After compiling and clicking on speckle the mainwindow
is not responsive. Here is the progressSpecle
member function in which x Threads gets created:
void MainWindow::progressSpecle(){
vector<cv::Mat> input;
...//do something with input
vector<cv::Mat> result;
vector<cv::Mat> *all;
all = &result;
QThreadPool *threadPool = QThreadPool::globalInstance();
for(unsigned int i = 1; i<input.size(); i++) {
cv_speckle_algorithm *work = new cv_speckle_algorithm(input.at(i-1), input.at(i), all, i-1);
work->setAutoDelete(false);
threadPool->start(work);
}
while(true){
if(threadPool->activeThreadCount() == 1) return result;
}
}
The application works without errors but the mainWindow is not responsible because (I think) of the while(true)
. But I do not understand why this should block the mainWindow, because the whole progressSpecle
function works in a seperate thread created and started with QtConcurrent
.
Why does the progressSpecle
function Blocks the mainWindow?
So how can I get the progressBar
to work?