PDA

View Full Version : Creating thread for each function of a class



Astrologer
17th April 2010, 09:20
Hi there. I'm just a beginner in Qt and I have been wrapping my head about this question for quite a while. Could you please help me out?

I have got a class, named, let's say,

class BaseClass: public Thread
I have a bunch of functions and I want each function to run in a separate thread. All information I have stumbled across so far claims that if I want to run a function in a separate thread I have to create a class

class Thread: public QThread
that inherits QThread and override QThread::run() function. But I hope there is another solution apart from creating a class which inherits QThread for each function in BaseClass. I would appreciate any ideas on this. Thank you so much in advance.

Lykurg
17th April 2010, 09:25
See QtConcurrentRun/QtConcurrent::run(),

Astrologer
17th April 2010, 09:33
Thank you, it is exactly what I was craving for:)

Astrologer
19th April 2010, 17:29
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

connect(this->ui->button1, SIGNAL(clicked()), this, SLOT(startThread()));
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}

void MainWindow::startThread()
{
QFuture<void> f1 = QtConcurrent::run(mbox);
f1.waitForFinished();
}

void mbox()
{
for (int i=0; i < 100000; i++)
{
qDebug() << i;
}
}



After this, GUI dies. I don't know what to do with it. Furthermore, there is a limit of input arguments, which is 5. What am I to do if there has to be more than that? Might the problem of hanging be in using f1.waitForFinished()?

Lykurg
19th April 2010, 17:49
What do you mean by dies? Does your application crash or is it just not respondable? The later would be because of waitForFinished() since your code does nothing else than normally call the mbox function with blocking the gui thread. If you need more arguments use a QVariantList.

Lykurg
19th April 2010, 17:52
Using QFutureWatcher is asynchronous. So connect the finished signal of f1 to a slot where you can go on, after the work in the function is done.

Astrologer
19th April 2010, 18:03
What do you mean by dies? Does your application crash or is it just not respondable? The later would be because of waitForFinished() since your code does nothing else than normally call the mbox function with blocking the gui thread. If you need more arguments use a QVariantList. No, it doesn't respond. So, I excluded "waitFor" and GUI does respond. Without "wait" I would use final signal and some slot as you suggested and go on with whatever is needed and it will work, won't it? :) You meant QList<QVariant>, didn't you? Thank you.

Lykurg
19th April 2010, 18:11
You meant QList<QVariant>, didn't you? Thank you.
Yes, since Qt does a typedef, QVariantList == QList<QVariant>. (QVariant::QVariantList (http://doc.trolltech.com/4.6/qvariant.html#QVariantList-typedef))

Astrologer
19th April 2010, 18:13
Using [QTCLASS]So connect the finished signal of f1 to a slot where you can go on, after the work in the function is done.

If I do like this:



#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

connect(this->ui->button1, SIGNAL(clicked()), this, SLOT(startThread()));
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}

void MainWindow::startThread()
{
QFuture<void> f1 = QtConcurrent::run(this, &MainWindow::mbox);
//f1.waitForFinished();
}

void MainWindow::mbox()
{
for (int i=0; i < 20000; i++)
{
qDebug() << i;
}

emit done();
}

void MainWindow::done()
{
QMessageBox::aboutQt(this, "Done!");
}



It apparently tries and create widget from within the thread and fails. Could you please hint me?

Lykurg
19th April 2010, 18:31
First you have to declare done as a slot then I meant to use the QFutureWatcher signal finished! E.g.:
QFutureWatcher<void> watcher;
connect(&watcher, SIGNAL(finished()), this, SLOT(done()));
//...
QFuture<void> f1 = QtConcurrent::run(this, &MainWindow::mbox);
watcher.setFuture(f1);
(not tested, but you see the idea!)

Astrologer
19th April 2010, 18:34
Yes, I do. I think I will peep in again just in case. Thank you for your patience and great help ;)