Unsolved Help using Qthread and signal/slot
-
Hello,
I'm a beginner and i try using qt with multi-thread and signal/slot.
This is my worker class worker.h:#ifndef GSTIMPL_H #define GSTIMPL_H #include <QObject> #include <QThread> #include <QDebug> class Worker : public QObject { Q_OBJECT public: Worker(); ~Worker(); public slots: void Process(); void Stop(); signals: void finished(); private: bool m_play; }; #endif // GSTIMPL_H
the corresponding worker.cpp:
#include "Worker.h" Worker::Worker() { // Constructor qDebug() << "-------------- Worker Constructor --------------" << endl; m_play = true; } Worker::~Worker() { // Destructor qDebug() << "-------------- Worker Destructor --------------" << endl; } void Worker::Process() { // Process. Start processing data. qDebug() << "-------------- Worker Process --------------" << endl; while(m_play == true) { qDebug("Hello World!"); QThread::sleep(1); } emit finished(); } void Worker::Stop() { qDebug() << "-------------- Worker Stop --------------" << endl; m_play = false; }
My controller class:
#ifndef CONTROLLER_H #define CONTROLLER_H #include <QObject> #include <QThread> #include "Worker.h" class Controller : public QObject { Q_OBJECT QThread workerThread; public: Controller(); public slots: signals: void Play(); void Stop(); }; #endif // CONTROLLER_H
and the corresponding controller.cpp:
#include "controller.h" Controller::Controller() { qDebug() << "-------------- Controller Constructor --------------" << endl; Worker* worker = new Worker(); worker->moveToThread(&workerThread); connect(&workerThread, SIGNAL (started()), worker, SLOT (Process())); connect(worker, SIGNAL (finished()), &workerThread, SLOT (quit())); connect(worker, SIGNAL (finished()), worker, SLOT (deleteLater())); connect(&workerThread, SIGNAL (finished()), &workerThread, SLOT (deleteLater())); connect(this, SIGNAL (Stop()), worker, SLOT (Stop())); workerThread.start(); emit Stop(); }
And this is my main:
int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; Controller c; return app.exec(); }
This is the output i get :
*Starting /opt/GstBind/bin/GstBind...
QML debugging is enabled. Only use this in a safe environment.
Using Wayland-EGL
-------------- Controller Constructor ---------------------------- Worker Constructor --------------
-------------- Worker Process --------------
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
User requested stop. Shutting down...
Process killed by signal*As you can see my problem is about signal/slot Stop(). It is never called whereas in my controller constructor it should be ! and so never printed too.
-
@fd101283 said in Help using Qthread and signal/slot:
QThread workerThread;
Hi! There's a double free in your code:
workerThread
is a member variable ofController
(thus gets automatically destroyed by the C++ runtime whenController
gets destroyed) and at the same time you connectedworkerThread
'sfinished
signal to itsdeleteLater
slot. -
@Wieland said in Help using Qthread and signal/slot:
Hi! There's a double free in your code: workerThread is a member variable of Controller (thus gets automatically destroyed by the C++ runtime when Controller gets destroyed) and at the same time you connected workerThread's finished signal to its deleteLater slot.
Hi,
In fact the code is extrated from here :
https://wiki.qt.io/QThreads_general_usageBUt even without the free, i can't see Stop signal working!
-
I think it may be because you are emitting the signal from within the constructor which means that the event loop isn't running yet. Try replacing:
emit Stop();
with
QTimer::singleShot(1000, [](){ emit Stop(); });
This will ensure that the loop is running before the signal is emitted.