QThread 与 QTimer 和 QSerial - 育儿

Posted

技术标签:

【中文标题】QThread 与 QTimer 和 QSerial - 育儿【英文标题】:QThread with QTimer and QSerial - parenting 【发布时间】:2017-12-07 11:05:40 【问题描述】:

我正在尝试在不同的线程中分配一个“自包含”通信对象,以使其与 GUI 处理延迟隔离。

因此,在“AppCore”对象创建中,我创建了一个没有父级的“CommCore”:

cAppCore::cAppCore(QObject *parent) : QObject(parent)

    ....
    CommCore = new cCommCore;
    (here I do signal-slot connections between CommCore and AppCore)
    ....

在 CommCore 构造函数中,我执行以下操作:

cCommCore::cCommCore(QObject *parent) : QObject(parent)

    CommThread = new QThread(this);
    CommSerial = new QSerialPort(this);
    CommTimer = new QTimer(this);

    connect(CommSerial,&QSerialPort::readyRead,this,&cCommCore::ProcessRXByte);
    connect(CommSerial, static_cast<void (QSerialPort::*)(QSerialPort::SerialPortError)>(&QSerialPort::error), this, &cCommCore::HandleSerialError);
    connect(CommTimer, &QTimer::timeout, this,&cCommCore::TimerTimeout);

    CommTimer->start(OFFLINE_POLL_TIME);
    this->moveToThread(CommThread);
    CommThread->start(QThread::HighPriority);

现在我的问题:

1- 可以使线程处理程序对象成为移动对象的子对象吗?因为它是在 GUI 线程(调用构造函数的地方)中创建的,然后移动到由它自己处理的线程(考虑到如果我需要对其进行任何控制,我将从 CommCore 对象内部处理它)

2- 可以在构造函数中启动计时器(与计时器构造函数,GUI线程在同一线程中),然后将所有内容移至新线程?

3- 如果我想稍后启动计时器,唯一的方法是通过信号槽吗?在 GUI 线程中发出信号并连接到 CommCore 插槽(然后将在 CommCore 线程中排队并执行)

4- 考虑到我的 CommCore 对象和 AppCore(GUI 线程)之间的所有交互都是通过信号槽(这是线程安全的)进行的,它在概念上是否正确? (对象将自身及其子项移动到新线程等的想法)

5- 我的基于池的串行通信例程(由计时器计时)将不受 GUI 处理延迟的影响? (我的意思是,Serial 和 Timer 对象产生的事件的生成和处理不会有延迟?)

【问题讨论】:

【参考方案1】:
this->moveToThread(CommThread);

如果对象 this 没有父对象,将会成功。因此,您需要更改构造函数的签名。除此之外没关系,因为对象与它的孩子一起移动......

计时器不应该这样启动,因为它被移到了不同​​的线程中。您应该使用 invokeMethod ,这样它就是执行操作的正确线程

QMetaObject::invokeMethod(CommTimer, "start");

对于您剩下的问题,所有答案都是肯定的。只要您使用信号并使用invokeMethod调用,就好像线程正在从可运行的池中获取并运行它们。

因此线程安全且不受主线程中断的影响。

【讨论】:

对!,谢谢,如果我使用invokeMethod,我可以在“movetothread”之后调用构造函数内部定时器的启动方法!?这将在目标对象的线程中“排队”方法调用(类似于信号槽交互)?好的!以前从未见过这种方式,谢谢!

以上是关于QThread 与 QTimer 和 QSerial - 育儿的主要内容,如果未能解决你的问题,请参考以下文章

在 QThread 中启动 QTimer

QTimer在QThread中失效

如何在 QThread 中使用 QTimer?

QTimer 只能用于以 QThread 启动的线程

在 QTimer Singleshot 之后终止 QThread

Python Qt GUI设计:QTimer计时器类QThread多线程类和事件处理类(基础篇—8)