QT5+ cmake+ qthread:来自抽象基类的信号未连接到另一个线程中的插槽

发布于 2025-01-21 06:40:28 字数 2767 浏览 1 评论 0原文

我实现了类的层次结构,以多线程qthread基于基于的方式处理传感器交互,就像在QT文档中推荐的那样。在这里,我有“标题文件” types.h带有抽象基本传感器读取器类:

#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实现实际传感器读取器我有以下文本:

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

信号获取()readdata()处理程序中发出时,当数据包在传感器轮询期间完全组装时。插槽runpoll()用于初始化和启动计时器。然后我实现了控制器类:

#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
    )

问题是Signal QSENSOR :: RUNREADER已成功连接到QABSTRACTSENSREADER :: RUNPOLL slot slot:虚拟函数qbaseserialSorreader: :runpoll()被调用。计时器也已启动,readdata()函数可起作用获得的信号。但是,此信号似乎并未连接到QSENSOR :: packet() slot。

您能否尝试解释此代码发生了什么问题?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自由如风 2025-01-28 06:40:28

您没有输入申请活动循环。从主函数中删除睡眠,然后调用 qcoreApplication :: exec 。即

sleep(10);
return 0;

return app.exec();

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文