Lehtim Lehtim - 1 year ago 179
C++ Question

Qt: Multithreading connect does not work

I want to connect two threads. One Thread is the Mainthread of my application the other on is a workerthread. I have based my code on the following example doc.qt.io/qt-5/. For me it does not work completely. I am sending a QString to my WorkerThread (this works) and want to send it afterwards back to the MainThread (does not work). Before asking why I am doing this that's just a very simple example. The real Code is much more complex but I have exactly the same problem. If those example would run I am very sure that the complex one would work too. Here the code:

Main.cpp

#include "Controller_C.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Controller_C Controller;
Controller.SendData("Hello World!");
return a.exec();
}


Controller_C.cpp

#include "Controller_C.h"
#include <qmessagebox.h>

Controller_C::Controller_C(QWidget *parent)
: QMainWindow(parent),
Worker(new Worker_C())
{
ui.setupUi(this);

Worker->moveToThread(&WorkerThread);
connect(&WorkerThread, SIGNAL(started()), this, SLOT(ThreadStarted()));
connect(this, SIGNAL(SendToWorker(QString)), Worker, SLOT(DoWork(QString)));
connect(Worker, SIGNAL(SendToController()), this, SLOT(ReceiveData()));
WorkerThread.start();
}

Controller_C::~Controller_C()
{

}

void Controller_C::SendData(QString aString)
{
QThread* Controller = QThread::currentThread();
QMessageBox::information(this, "Info", QString("We have send the following to the Worker Thread: %1").arg(aString));
emit SendToWorker(aString);
}

void Controller_C::ReceiveData(QString aString)
{
QThread* Controller = QThread::currentThread();
QMessageBox::information(this, "Info", QString("The Controller received the following: %1").arg(aString));
}


Controller_C.h

#ifndef CONTROLLER_C_H
#define CONTROLLER_C_H

#include <QtWidgets/QMainWindow>
#include "ui_Controller_C.h"
#include "Worker_C.h"
#include <qthread.h>

class Controller_C : public QMainWindow
{
Q_OBJECT

public:
Controller_C(QWidget *parent = 0);
~Controller_C();

void SendData(QString aString);

private:
Ui::Qt_TestEnvironmentClass ui;
Worker_C* Worker;
QThread WorkerThread;

signals:

void SendToWorker(QString);

public slots:

void ReceiveData(QString aString);
};

#endif // CONTROLLER_C_H


Worker_C.cpp

#include "Worker_C.h"
#include <qmessagebox.h>
#include <qthread.h>

Worker_C::Worker_C()
{

}

Worker_C::~Worker_C()
{

}

void Worker_C::DoWork(QString aString)
{
QThread* Worker = QThread::currentThread();
emit SendToController(aString);
}


Worker_C.h

#ifndef WORKER_C_H
#define WORKER_C_H

#include <QObject>

class Worker_C : public QObject
{
Q_OBJECT

public:
Worker_C();
~Worker_C();

public slots:

void DoWork(QString aString);

signals:

void SendToController(QString);

};

#endif // WORKER_C_H


Thanks for your help.

Answer Source

Like the way you definied the Slot/Signal in your header:

void ReceiveData(QString aString);
void SendToController(QString);

You should also use them like this in your connect:
connect(Worker, SIGNAL(SendToController(QString)), this, SLOT(ReceiveData(QString)));
Furthermore I would suggest you to use QApplication::processEvents() in your more complex code if you emit many signals. But that is just an idea when you have some more pending Events caused by your complex code.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download