线程关联性:无法为位于不同线程中的父级创建子级

Posted

技术标签:

【中文标题】线程关联性:无法为位于不同线程中的父级创建子级【英文标题】:Thread Affinity: Cannot create children for a parent that is in a different thread 【发布时间】:2015-11-24 09:10:55 【问题描述】:

我见过similar question,但我觉得我正在实施正确的模式,但我仍然无法完成!

好吧,我有一个 Gui 来启动和停止从 serial port 获取数据并显示必要的通信消息。为了保持Gui 的响应,我将 worker 移动到一个线程。我尝试实现线程关联,根据:How to Use QThread in the Right Way 和How To Really, Truly Use QThreads。当我点击开始按钮时,我会收到;

QWinEventNotifier: event notifiers cannot be enabled from another thread
QWinEventNotifier: event notifiers cannot be enabled from another thread
QWinEventNotifier: event notifiers cannot be enabled from another thread
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0x142cd390), parent's thread is QThread(0x1259b070), current thread is QThread(0x142db1f0)

我错过了什么?这是与我的问题相关的部分代码:

工作器标头

#ifndef COMPORT_H
#define COMPORT_H

#include <QObject>
#include <QDebug>
#include <QSerialPort>

class QTimer;

class ComPort : public QObject

    Q_OBJECT

public:
    explicit ComPort(const QString &portName, QObject* parent = 0);
    ~ComPort();

private:
    QSerialPort*    port;
    QString         portMsg;
    QByteArray      responseData;
signals:
    void finished();

private slots:
    void onReadyRead();
    void setupPort();

;

#endif // COMPORT_H

工人 cpp

#include "comport.h"

ComPort::ComPort(const QString &portName, QObject *parent)
    :QObject(parent)

    this->port = new QSerialPort(portName);


ComPort::~ComPort()

    port->close();
    delete port;


void ComPort::setupPort()

    port->setBaudRate(QSerialPort::Baud19200);
    port->setDataBits(QSerialPort::Data8);
    port->setFlowControl(QSerialPort::NoFlowControl);
    port->setParity(QSerialPort::NoParity);
    port->setStopBits(QSerialPort::OneStop);

    connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));

    *SOME CODE HERE*


void ComPort::onReadyRead()

    QByteArray bytes = port->readAll() ;
    qDebug() << "bytes:" << bytes <<"\n";
    responseData.append(bytes);

#include "gui.h"
#include "ui_gui.h"

gui::gui(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::gui)

    ui->setupUi(this);
    connect(ui->startButton, SIGNAL(clicked()), this, SLOT(OnstartButtonClicked()));


gui::~gui()

    delete ui;


void gui::OnstartButtonClicked()

    QThread*  cThread = new QThread;
    ComPort*  cPort   = new ComPort(QString("COM4"));
    cPort->moveToThread(cThread);
    connect(cPort, SIGNAL(finished()), cThread, SLOT(quit()));
    connect(cPort, SIGNAL(finished()), cPort, SLOT(deleteLater()));
    connect(cThread, SIGNAL(finished()), cThread, SLOT(deleteLater()));
    connect(cThread, SIGNAL(started()), cPort, SLOT(setupPort()));
    cThread->start();

【问题讨论】:

【参考方案1】:

感谢Kim Bowles Sørhus的回答,我解决了我的问题。我在主线程中调用的ComPort 的构造函数中创建了一个串行端口。当cPort 对象移动到cThread 时,QSerialPort 仍将其线程关联设置为原始线程。一种解决方案是在ComPort::setupPort 中创建QSerialPort

【讨论】:

以上是关于线程关联性:无法为位于不同线程中的父级创建子级的主要内容,如果未能解决你的问题,请参考以下文章

无法为不同线程中的父级创建子级

PyQt4 & flask:无法为不同线程中的父级创建子级

(QNativeSocketEngine)QObject:无法为不同线程中的父级创建子级

PyQt 多线程,无法为父级创建子级

QTcpSocket Disconnected() 未发出信号

如何在 .NET Core 中使用默认依赖注入从父级创建子范围?