QT - threading, app freezing
-
Hi,
im starting programming in qt and i want to create app, which just load some data to list view, i want to learn model-view and threading. so i have written some code, but if i run it, and run function that takes some time, whole program freezes. how to avoid that? I thought, that if i make extra thread for it, it would be OK...@
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QtCore>
#include <QtGui>
#include <QDebug>
#include <QtConcurrent/QtConcurrentRun>
#include "datamodel.h"
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();private slots:
void on_pushButton_clicked();private:
Ui::MainWindow *ui;
QStringListModel * m_person_model;
DataModel m_model;};
#endif // MAINWINDOW_H
@@
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);}
MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::on_pushButton_clicked()
{
//freeze, why?
m_person_model = new QStringListModel();
QFuture<QStringList> future = QtConcurrent::run(&this->m_model ,&DataModel::getPersonList);
QStringList list = future.result();
m_person_model->setStringList(list);
ui->personListView->setModel(m_person_model);
}
@@
//datamodel.h
#ifndef DATAMODEL_H
#define DATAMODEL_H#include <QObject>
#include <QtCore>
class DataModel : public QObject
{
Q_OBJECT
public:
explicit DataModel(QObject *parent = 0);
QStringList getPersonList();
signals:public slots:
};
#endif // DATAMODEL_H
@@
//datamodel.cpp
#include "datamodel.h"DataModel::DataModel(QObject parent) :
QObject(parent)
{
}
QStringList DataModel::getPersonList(){
QStringList list;
for (int i = 0; i < 10000; ++i) {
for (int z = 0; z < 10; ++z) {
list.append(QString::number(iz));
}} return list;
};
@
Any advice would be helpful, thanks.
-
Are you sure that it freezes or does it just take very long? Have you tried to reduce the number of entries you generate in getPersonList to see whether the 'freeze' gets shorter?
One word to the usage of threads here. In on_pushButton_clicked you start the worker thread and directly afterwards you call result on your future. At that very point the main thread (which is the UI thread) blocks until the worker thread is done. Is that really what you intended?
Peer
-
Ok, so what i need is to do is make a connect, that triggers after result is finished, so main thread wont be blocked?
Will try to do that :) It may take some time... -
Have a look into "QFutureWatcher":http://qt-project.org/doc/qt-4.8/qfuturewatcher.html
That should make it easy ;)
Peer
-
I have made it working :D (finally!!!)
Problem was mentioned before, i was not waiting till finished, so it freezed for a while.
so here is what i did..
@{
ui->setupUi(this);
//this will trigger handlePersonWatcherData as it is finished
connect(&m_watcher, SIGNAL(finished()), this, SLOT(handlePersonWatcherData()));}
MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::on_pushButton_clicked()
{
m_person_model = new QStringListModel();
m_future = QtConcurrent::run(&this->m_model ,&DataModel::getPersonList);
m_watcher.setFuture(m_future);
}
void MainWindow::handlePersonWatcherData(){
QStringList list = m_future.result();
m_person_model->setStringList(list);
ui->personListView->setModel(m_person_model);
}@Now it works properly, it still freezes, but it is just because i was setting list with 100 000 rows - counting itself is now done properly in its own thread.
Thank you :)