QT threading No such signal QThread::
-
I am working on a project for passing argument and return the values in between thread. So far I have tried:
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // The thread and the worker are created in the constructor so it is always safe to delete them. thread = new QThread(); worker = new Worker(); worker->moveToThread(thread); connect(worker, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString))); connect(worker, SIGNAL(workRequested()), thread, SLOT(start())); // connect(thread, SIGNAL(started()), worker, SLOT(doWork(int))); connect(thread, SIGNAL(requestUpdate(int)), worker, SLOT(doWork(int))); connect(worker, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection); } MainWindow::~MainWindow() { worker->abort(); thread->wait(); qDebug()<<"Deleting thread and worker in Thread "<<this->QObject::thread()->currentThreadId(); delete thread; delete worker; delete ui; } void MainWindow::on_startButton_clicked() { // To avoid having two threads running simultaneously, the previous thread is aborted. worker->abort(); thread->wait(); // If the thread is not running, this will immediately return. int enc = 5; //worker->requestWork(); emit requestUpdate(enc); }
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QThread> #include "worker.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; /** * @brief Thread object which will let us manipulate the running thread */ QThread *thread; /** * @brief Object which contains methods that should be runned in another thread */ Worker *worker; private slots: void on_startButton_clicked(); public slots: // void addImage(int i); signals: void requestUpdate(int initial); }; #endif // MAINWINDOW_H
and worker.cpp
#include "worker.h" #include <QTimer> #include <QEventLoop> #include <QThread> #include <QDebug> Worker::Worker(QObject *parent) : QObject(parent) { _working =false; _abort = false; } void Worker::requestWork() { mutex.lock(); _working = true; _abort = false; qDebug()<<"Request worker start in Thread "<<thread()->currentThreadId(); mutex.unlock(); emit workRequested(); } void Worker::abort() { mutex.lock(); if (_working) { _abort = true; qDebug()<<"Request worker aborting in Thread "<<thread()->currentThreadId(); } mutex.unlock(); } void Worker::doWork(int initial) { qDebug()<<"Starting worker process in Thread "<<thread()->currentThreadId(); for (int i = initial; i < 60; i ++) { // Checks if the process should be aborted mutex.lock(); bool abort = _abort; mutex.unlock(); if (abort) { qDebug()<<"Aborting worker process in Thread "<<thread()->currentThreadId(); break; } // This will stupidly wait 1 sec doing nothing... QEventLoop loop; QTimer::singleShot(1000, &loop, SLOT(quit())); loop.exec(); // Once we're done waiting, value is updated emit valueChanged(QString::number(i)); } // Set _working to false, meaning the process can't be aborted anymore. mutex.lock(); _working = false; mutex.unlock(); qDebug()<<"Worker process finished in Thread "<<thread()->currentThreadId(); //Once 60 sec passed, the finished signal is sent emit finished(); }
worker.h
#ifndef WORKER_H #define WORKER_H #include <QObject> #include <QMutex> class Worker : public QObject { Q_OBJECT public: explicit Worker(QObject *parent = 0); /** * @brief Requests the process to start * * It is thread safe as it uses #mutex to protect access to #_working variable. */ void requestWork(); /** * @brief Requests the process to abort * * It is thread safe as it uses #mutex to protect access to #_abort variable. */ void abort(); private: /** * @brief Process is aborted when @em true */ bool _abort; /** * @brief @em true when Worker is doing work */ bool _working; /** * @brief Protects access to #_abort */ QMutex mutex; signals: /** * @brief This signal is emitted when the Worker request to Work * @sa requestWork() */ void workRequested(); /** * @brief This signal is emitted when counted value is changed (every sec) */ void valueChanged(const QString &value); /** * @brief This signal is emitted when process is finished (either by counting 60 sec or being aborted) */ void finished(); public slots: /** * @brief Does something * * Counts 60 sec in this example. * Counting is interrupted if #_aborted is set to true. */ void doWork(int initial); }; #endif // WORKER_H
The program compiles fine but while running, it gives
QObject::connect: No such signal QThread::requestUpdate(int)
What I am trying to do here is to pass an integer to doWork() function and return the value in mainwindow. Can someone help me where I am doing wrong?
-
I am working on a project for passing argument and return the values in between thread. So far I have tried:
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // The thread and the worker are created in the constructor so it is always safe to delete them. thread = new QThread(); worker = new Worker(); worker->moveToThread(thread); connect(worker, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString))); connect(worker, SIGNAL(workRequested()), thread, SLOT(start())); // connect(thread, SIGNAL(started()), worker, SLOT(doWork(int))); connect(thread, SIGNAL(requestUpdate(int)), worker, SLOT(doWork(int))); connect(worker, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection); } MainWindow::~MainWindow() { worker->abort(); thread->wait(); qDebug()<<"Deleting thread and worker in Thread "<<this->QObject::thread()->currentThreadId(); delete thread; delete worker; delete ui; } void MainWindow::on_startButton_clicked() { // To avoid having two threads running simultaneously, the previous thread is aborted. worker->abort(); thread->wait(); // If the thread is not running, this will immediately return. int enc = 5; //worker->requestWork(); emit requestUpdate(enc); }
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QThread> #include "worker.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; /** * @brief Thread object which will let us manipulate the running thread */ QThread *thread; /** * @brief Object which contains methods that should be runned in another thread */ Worker *worker; private slots: void on_startButton_clicked(); public slots: // void addImage(int i); signals: void requestUpdate(int initial); }; #endif // MAINWINDOW_H
and worker.cpp
#include "worker.h" #include <QTimer> #include <QEventLoop> #include <QThread> #include <QDebug> Worker::Worker(QObject *parent) : QObject(parent) { _working =false; _abort = false; } void Worker::requestWork() { mutex.lock(); _working = true; _abort = false; qDebug()<<"Request worker start in Thread "<<thread()->currentThreadId(); mutex.unlock(); emit workRequested(); } void Worker::abort() { mutex.lock(); if (_working) { _abort = true; qDebug()<<"Request worker aborting in Thread "<<thread()->currentThreadId(); } mutex.unlock(); } void Worker::doWork(int initial) { qDebug()<<"Starting worker process in Thread "<<thread()->currentThreadId(); for (int i = initial; i < 60; i ++) { // Checks if the process should be aborted mutex.lock(); bool abort = _abort; mutex.unlock(); if (abort) { qDebug()<<"Aborting worker process in Thread "<<thread()->currentThreadId(); break; } // This will stupidly wait 1 sec doing nothing... QEventLoop loop; QTimer::singleShot(1000, &loop, SLOT(quit())); loop.exec(); // Once we're done waiting, value is updated emit valueChanged(QString::number(i)); } // Set _working to false, meaning the process can't be aborted anymore. mutex.lock(); _working = false; mutex.unlock(); qDebug()<<"Worker process finished in Thread "<<thread()->currentThreadId(); //Once 60 sec passed, the finished signal is sent emit finished(); }
worker.h
#ifndef WORKER_H #define WORKER_H #include <QObject> #include <QMutex> class Worker : public QObject { Q_OBJECT public: explicit Worker(QObject *parent = 0); /** * @brief Requests the process to start * * It is thread safe as it uses #mutex to protect access to #_working variable. */ void requestWork(); /** * @brief Requests the process to abort * * It is thread safe as it uses #mutex to protect access to #_abort variable. */ void abort(); private: /** * @brief Process is aborted when @em true */ bool _abort; /** * @brief @em true when Worker is doing work */ bool _working; /** * @brief Protects access to #_abort */ QMutex mutex; signals: /** * @brief This signal is emitted when the Worker request to Work * @sa requestWork() */ void workRequested(); /** * @brief This signal is emitted when counted value is changed (every sec) */ void valueChanged(const QString &value); /** * @brief This signal is emitted when process is finished (either by counting 60 sec or being aborted) */ void finished(); public slots: /** * @brief Does something * * Counts 60 sec in this example. * Counting is interrupted if #_aborted is set to true. */ void doWork(int initial); }; #endif // WORKER_H
The program compiles fine but while running, it gives
QObject::connect: No such signal QThread::requestUpdate(int)
What I am trying to do here is to pass an integer to doWork() function and return the value in mainwindow. Can someone help me where I am doing wrong?
hi @sigmind said in QT threading No such signal QThread:::
connect(thread, SIGNAL(requestUpdate(int)), worker, SLOT(doWork(int)));
in this connect you tell the compiler that the signal
requestUpdate
is part of the QThread class, but that's not ture, you defined it as part ofMainWindow
->
connect(this, SIGNAL(requestUpdate(int)), worker, SLOT(doWork(int)));
//or Qt5 Syntax
connect(this, &MainWindow::requestUpdate, worker, &Worker::doWork);