i was experimenting with QThread the other day and i wanted to create an infinite loop by using signals only and not for, foreach or while but then my code would crash after emitting the signal and executing the slot for a number of times here's my code:
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "worker.h"
#include <QThread>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void startthreads();
private:
Ui::MainWindow *ui;
QThread thread;
worker *work;
};
#endif // MAINWINDOW_H
//worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QDebug>
#include <QMutex>
#include "insiderobject.h"
class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = 0);
signals:
void doagain();
void okidid();
void finished();
public slots:
void printing();
};
#endif // WORKER_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
startthreads();
}
MainWindow::~MainWindow()
{
thread.wait();
delete ui;
delete work;
}
void MainWindow::startthreads()
{
work = new worker;
work->moveToThread(&thread);
connect(&thread, SIGNAL(started()), work, SLOT(printing()));
connect(work, SIGNAL(finished()), &thread, SLOT(quit()));
thread.start();
}
//worker.cpp
#include "worker.h"
worker::worker(QObject *parent) :
QObject(parent)
{
connect(this, SIGNAL(okidid()), this, SLOT(printing()));
}
void worker::printing()
{
qDebug() << "printing";
emit okidid();
}
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
i have read the entire documentation for signal/slots and threads and queued connections or whatever i could get my hands on but i could not understand the reason for this crash... also i tried chatting with people and developers at Qt irc chat room but no one could tell me the reason.
What you are doing is an infinite recursion. emit okidid();
is actually a direct call to worker::printing()
. That will cause a stack overflow.
You can fix this by using a queued signal connection:
connect(this, SIGNAL(okidid()), this, SLOT(printing()), Qt::QueuedConnection);
Now the emit okidid();
is not a direct function call anymore. The worker::printing()
function will be called in the Qt's event loop.