Qt5 + CMake + QThread:来自抽象基class的信号未连接到另一个线程中的插槽

Qt5 + CMake + QThread: the signal from abstract base class is not connected to the slot in another thread

我实现了一个 classes 的层次结构,以基于多线程 QThread 的方式处理传感器交互,正如 Qt 文档中推荐的那样。这里我有头文件 types.h 和抽象基础传感器 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();
};

在实现实际传感器的文件 serial.h 中 reader 我有以下文本:

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

当数据包在传感器轮询期间完全组装时,信号 acquired()ReadData() 处理程序中发出。插槽 RunPoll() 用于初始化和启动定时器。然后我实现了控制器 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();
};

然后申请:

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

利用层次结构。

CMake 文件包含以下文本:

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
    )

问题是信号QSensor::RunReader成功连接到QAbstractSensorReader::RunPoll槽:虚函数QBaseSerialSensorReader::RunPoll()被调用。定时器也被启动并且 ReadData() 函数工作并发出 acquired 信号。但是这个信号似乎没有从 QAbstractSensorReaderQBaseSerialSensorReader 命名空间连接到 QSensor::Packet() 插槽。

能否请您解释一下这段代码出了什么问题?

您没有进入应用程序事件循环。从 main 函数中删除睡眠并调用 QCoreApplication::exec。 IE。替换这些行

sleep(10);
return 0;

return app.exec();