Hi, I have a simple problem which I have not been able to solve yet. At least not in the way I think is nicer...
The setup is a simple worker object that should be run in a different thread. I connect the thread start signal to the worker slot function that should be run and I connect the worker done signal to the thread terminate slot. Then I move the worker to the thread using moveToThread().
I want to wait for the thread, t, to finish so I call:
t->start();
t->wait();
The work is done, but the program never gets through the wait-condition. So somehow the emitted signal is not triggering the thread terminate slot.
If I instead call thread()->quit() or thread->exit() instead of emitting the signal everything works.
If I try and connect to terminate or quit does not matter.
Here is some sample code, please help me/tell me what the "right" way to solve this problem is and how/why 
Best regards //
Daniel
Header:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUrl>
#include <QThread>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class DownloadWorker
: public QObject{
Q_OBJECT
public:
explicit DownloadWorker
(QObject *parent
= 0) {
qDebug() << "Creating worker";
}
private:
public slots:
void slotWork();
void slotWorkDone(QNetworkReply *reply);
{
this->url = url;
}
signals:
void workDone();
};
{
Q_OBJECT
public:
explicit MainWindow
(QWidget *parent
= 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUrl>
#include <QThread>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class DownloadWorker : public QObject
{
Q_OBJECT
public:
explicit DownloadWorker(QObject *parent = 0)
: QObject(parent)
{
qDebug() << "Creating worker";
}
QByteArray* getba() {return &ba;}
private:
QString url;
QByteArray ba;
public slots:
void slotWork();
void slotWorkDone(QNetworkReply *reply);
void prepareDownload(QString url)
{
this->url = url;
}
signals:
void workDone();
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
To copy to clipboard, switch view to plain text mode
#include "mainwindow.h"
#include "ui_mainwindow.h"
void DownloadWorker::slotWork()
{
QNetworkAccessManager *man = new QNetworkAccessManager(this);
connect(man, SIGNAL(finished(QNetworkReply*)),
this,SLOT(slotWorkDone(QNetworkReply*)));
man
->get
(QNetworkRequest
(QUrl(this
->url
)));
}
void DownloadWorker::slotWorkDone(QNetworkReply *reply)
{
reply->deleteLater();
ba = reply->readAll();
qDebug() << "Download done, exit thread?";
emit workDone();
//thread()->exit(); //things work with this but is it the "right" way to do it?
}
MainWindow
::MainWindow(QWidget *parent
) :{
ui->setupUi(this);
DownloadWorker *dw = new DownloadWorker();
dw->prepareDownload("http://www.google.com");
dw->moveToThread(t);
connect(t, SIGNAL(started()),
dw, SLOT(slotWork()));
connect(dw, SIGNAL(workDone()),
t, SLOT(terminate()));
t->start();
qDebug() << "Waiting for thread...";
qDebug() << *dw->getba();
t->wait();
qDebug() << "...done!";
qDebug() << *dw->getba();
}
MainWindow::~MainWindow()
{
delete ui;
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
void DownloadWorker::slotWork()
{
QNetworkAccessManager *man = new QNetworkAccessManager(this);
connect(man, SIGNAL(finished(QNetworkReply*)),
this,SLOT(slotWorkDone(QNetworkReply*)));
man->get(QNetworkRequest(QUrl(this->url)));
}
void DownloadWorker::slotWorkDone(QNetworkReply *reply)
{
reply->deleteLater();
ba = reply->readAll();
qDebug() << "Download done, exit thread?";
emit workDone();
//thread()->exit(); //things work with this but is it the "right" way to do it?
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
QThread *t = new QThread();
DownloadWorker *dw = new DownloadWorker();
dw->prepareDownload("http://www.google.com");
dw->moveToThread(t);
connect(t, SIGNAL(started()),
dw, SLOT(slotWork()));
connect(dw, SIGNAL(workDone()),
t, SLOT(terminate()));
t->start();
qDebug() << "Waiting for thread...";
qDebug() << *dw->getba();
t->wait();
qDebug() << "...done!";
qDebug() << *dw->getba();
}
MainWindow::~MainWindow()
{
delete ui;
}
To copy to clipboard, switch view to plain text mode
Bookmarks