Before I answer your question I will first say that, despite examples given in the docs, it is generally considered a bad idea to subclass QThread and instead create a worker object that is moved into a thread. To stop a QThread you need to call quit() and, if that fails, terminate(). The issue here is that you're running a blocking method and no event loop so these methods will not work on there own. What you therefore need is a flag that is checked on every iteration of the forever loop and set by a signal/slot call from your main thread when the GUI exits. The following files form a minimal working example:
widget.h
@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class QThread;
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
QThread *thread;
signals:
void stopThread();
public slots:
void start();
void tick();
};
#endif // WIDGET_H
@
widget.cpp
@
#include "widget.h"
#include "threaded.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
QVBoxLayout *l=new QVBoxLayout(this);
QPushButton *startButton=new QPushButton("Start", this);
connect(startButton, SIGNAL(clicked()), this, SLOT(start()));
l->addWidget(startButton);
}
Widget::~Widget()
{
if(thread->isRunning()){
emit stopThread();
thread->quit();
if(!thread->wait(5000)){
thread->terminate();
if(!thread->wait(5000)) qDebug() << "Failed to terminate!";
}
}
}
void Widget::start(){
thread=new QThread();
Threaded *threaded=new Threaded();
connect(this, SIGNAL(stopThread()), threaded, SLOT(stop()));
connect(threaded, SIGNAL(tick()), this, SLOT(tick()));
connect(thread, SIGNAL(started()), threaded, SLOT(work()));
threaded->moveToThread(thread);
thread->start();
}
void Widget::tick(){
qDebug() << "tick";
}
@
threaded.h
@
#ifndef THREADED_H
#define THREADED_H
#include <QObject>
class Threaded : public QObject
{
Q_OBJECT
public:
explicit Threaded(QObject *parent = 0);
private:
bool mStop;
signals:
void tick();
public slots:
void work();
void stop();
};
#endif // THREADED_H
@
threaded.cpp
@
#include "threaded.h"
#include <QMutex>
#include <QWaitCondition>
#include <QCoreApplication>
Threaded::Threaded(QObject *parent) :
QObject(parent), mStop(false)
{}
void Threaded::work(){
QMutex dummy;
QWaitCondition waitCondition;
forever{
dummy.lock();
waitCondition.wait(&dummy, 1000);
emit tick();
dummy.unlock();
QCoreApplication::processEvents();
if(mStop) break;
}
}
void Threaded::stop(){
mStop=true;
}
@
main.cpp
@
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
@
Hope this helps ;o)