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();