-1

I am trying to send signal across threads.

For testing this situation, I wrote a test code. I am working on ubuntu 16.04 machine and qt version is 4.8.

In my code, three class exists:

1 - timer_class -> in this class, I emit signal in timeout slot.

2 - test_worker -> I am using this class as thread's worker.

3 - main_class -> I create timer_class instance, and also create thread in this class constructor.

I am trying to connect timer_class signal to test_worker slot.

Here is my code:

First; timer_class :

Header File:

#ifndef TIMER_CLASS_H
#define TIMER_CLASS_H

#include <QTimer>
#include <QDebug>
#include <QObject>

class timer_class : public QObject
{
    Q_OBJECT
public:
    timer_class(QObject *parent = 0);
    ~timer_class();

    void start_timer();

signals:
    void dummy_signal();

private slots:
    void on_timeout_occur();

private:
    QTimer *timer;
};

#endif // TIMER_CLASS_H

Source File :

#include "timer_class.h"

timer_class::timer_class(QObject *parent)
    :QObject(parent)
{
    timer = new QTimer();
    connect(timer, SIGNAL(timeout()), this, SLOT(on_timeout_occur()));
}

timer_class::~timer_class()
{

}

void timer_class::start_timer()
{
    timer->start(1000);
}

void timer_class::on_timeout_occur()
{
    qDebug() << "timeout occur";
    emit dummy_signal();
}

Second, thread_worker class : Header File :

#ifndef THREAD_WORKER_H
#define THREAD_WORKER_H

#include <QDebug>
#include <QObject>

class thread_worker : public QObject
{
    Q_OBJECT
public:
    thread_worker(QObject *parent = 0);
    ~thread_worker();

public slots:
    void main_loop();
    void on_dummy_signal();
};

#endif // THREAD_WORKER_H

Source File :

#include "thread_worker.h"

thread_worker::thread_worker(QObject *parent)
    :QObject(parent)
{

}

thread_worker::~thread_worker()
{

}

void thread_worker::main_loop()
{
    forever
    {
        //qDebug() << "In Main Loop";
    }
}

void thread_worker::on_dummy_signal()
{
    qDebug() << "dummy signal received";
}

And last, main_class : Header file :

#ifndef MAIN_CLASS_H
#define MAIN_CLASS_H

#include <QObject>
#include <QDebug>
#include <QThread>
#include "timer_class.h"
#include "thread_worker.h"

class main_class : public QObject
{
    Q_OBJECT
public:
    main_class(QObject *parent = 0);
    ~main_class();

private:
    QThread *thread;
    timer_class *tmr_class;
    thread_worker *worker;
};

#endif // MAIN_CLASS_H

Source File:

#include "main_class.h"

main_class::main_class(QObject *parent)
    :QObject(parent)
{
    tmr_class   = new timer_class();
    worker      = new thread_worker();
    thread      = new QThread();

    worker->moveToThread(thread);
    connect(tmr_class, SIGNAL(dummy_signal()), worker, SLOT(on_dummy_signal()));

    connect(thread, SIGNAL(started()), worker, SLOT(main_loop()));
    thread->start();
    tmr_class->start_timer();
}

main_class::~main_class()
{

}

In main.cpp, I just create main_class instance like this :

#include <QCoreApplication>
#include "main_class.h"

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);

        main_class *main_cl = new main_class();

        qDebug() << "executing a.exec";
        return a.exec();
    }

When I run the application, I saw "timeout occur" in console, but I don't saw "dummy signal received". I can not find problem.

Could you help me about this problem ? Thanks.

user3104363
  • 182
  • 1
  • 14

1 Answers1

0

The basic problem is that you're creating a new QThread, moving your timer_class instance onto that thread and then invoking thread_worker::main_loop when the thread starts. Since thread_worker::main_loop is basically a busy-waiting loop...

void thread_worker::main_loop ()
{
  forever
  {
    //qDebug() << "In Main Loop";
  }
}

...the QThread never gets a chance to process events thus preventing any signals being received via queued connections.

The correct fix for all of this depends to a large extent on what work (if any) you want thread_worker::main_loop to do.

To get things going in the mean time simply remove the forever loop or comment out the line...

connect(thread, SIGNAL(started()), worker, SLOT(main_loop()));

Having done that you should see the "dummy signal received" messages.

G.M.
  • 12,232
  • 2
  • 15
  • 18