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
信号。但是这个信号似乎没有从 QAbstractSensorReader
或 QBaseSerialSensorReader
命名空间连接到 QSensor::Packet()
插槽。
能否请您解释一下这段代码出了什么问题?
您没有进入应用程序事件循环。从 main 函数中删除睡眠并调用 QCoreApplication::exec。 IE。替换这些行
sleep(10);
return 0;
和
return app.exec();
我实现了一个 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
信号。但是这个信号似乎没有从 QAbstractSensorReader
或 QBaseSerialSensorReader
命名空间连接到 QSensor::Packet()
插槽。
能否请您解释一下这段代码出了什么问题?
您没有进入应用程序事件循环。从 main 函数中删除睡眠并调用 QCoreApplication::exec。 IE。替换这些行
sleep(10);
return 0;
和
return app.exec();