Home > Mobile >  Qt5 CMake QThread: the signal from abstract base class is not connected to the slot in another t
Qt5 CMake QThread: the signal from abstract base class is not connected to the slot in another t

Time:04-15

I implemented a hierarchy of classes to handle sensor interaction in a multithreaded QThread-based manner, as how it is recommended in Qt documentation. Here I have the header file types.h with the abstract base sensor reader class:

#include <QtCore>
class QAbstractSensorReader: public QObject
{   Q_OBJECT
protected slots:
    virtual void ReadData() = 0;
public slots:
    virtual void RunPoll() = 0;
signals:
    void acquired();
};

In the file serial.h implementing the actual sensor reader I have the following text:

#include "types.h"
class QBaseSerialSensorReader: public QAbstractSensorReader
{
    Q_OBJECT
private:
    /*===*/
protected:
    QTextStream ttyout;
    QTimer* poll_timer;
    virtual void ReadData();
public:
    QBaseSerialSensorReader(const QString device);
    virtual ~QBaseSerialSensorReader();
    virtual void RunPoll();
};

The signal acquired() is emitted in the ReadData() handler when the data packet is assembled completely during the sensor poll. The slot RunPoll() is used to initialize and start a timer. Then I implemented the controller class:

#include "serial.h"
class QSensor: public QObject
{
    Q_OBJECT
private:
    QThread reader_thread;
    QBaseSerialSensorReader* reader;

public:
    QSensor()
{
    reader = new QBaseSerialSensorReader();
    reader->moveToThread(&reader_thread);
    connect(&reader_thread, &QThread::finished, reader, &QObject::deleteLater);
    connect(this, &QSensor::RunReader, reader, &QAbstractSensorReader::RunPoll);
    connect(reader, &QBaseSerialSensorReader::acquired, this, &QSensor::Packet);
    reader_thread.start();
}

    void Start() {emit RunReader();}
    virtual ~QSensor();
public slots:
    void Packet(){ttyout << "ACQUIRED!";}
signals:
    void RunReader();
};

Then the application:

#include "controller.h"
int main(int argc, char** args)
{
    QCoreApplication app(argc, args);
    QSensor sensor();
    sensor.Start();
    sleep(10);
    return 0;
}

exploits the hierarchy.

The CMake file contains the following text:

find_package(Qt5 REQUIRED COMPONENTS Core SerialPort)
set(CMAKE_AUTOMOC ON)
qt5_wrap_cpp(MOC_SOURCES
    include/types.h
    include/serial.h
    include/contoller.h
    )
set(LIBRARY_SOURCES
    ${MOC_SOURCES}
    src/util.cpp
    src/serial.cpp
    src/controller.cpp
    )
add_library(sensor-serial SHARED ${LIBRARY_SOURCES})
target_link_libraries(sensor-serial Qt5::Core Qt5::SerialPort)
add_executable(library-init-test
    tests/library-init-test.cpp
    )
target_link_libraries(library-init-test
    Qt5::Core Qt5::SerialPort
    sensor-serial
    )

The problem is that the signal QSensor::RunReader is successfully connected to QAbstractSensorReader::RunPoll slot: the virtual function QBaseSerialSensorReader::RunPoll() is called. The timer is also started and the ReadData() function works emitting the acquired signal. But this signal then does not seem to be connected to the QSensor::Packet() slot neither from QAbstractSensorReader nor from QBaseSerialSensorReader namespace.

Could you please try to explain what wrong is happening with this code?

CodePudding user response:

You are not entering application event loop. Remove sleep from main function and call QCoreApplication::exec. I.e. replace these lines

sleep(10);
return 0;

with

return app.exec();
  • Related