线程亲和性:无法为处于不同线程中的父对象创建子对象
Thread Affinity: Cannot create children for a parent that is in a different thread
我看过一个similar question,但我觉得我正在实施正确的模式,但我仍然无法完成它!
好吧,我有一个 Gui
来启动和停止从 serial port
获取数据并显示必要的通信消息。为了保持 Gui
响应,我将 worker 移动到一个线程。我尝试根据:How to Use QThread in the Right Way and How To Really, Truly Use QThreads 实现 thread affinity。当我点击开始按钮时,我收到;
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();
}
感谢Kim Bowles Sørhus的解答,解决了我的问题。我在 ComPort
的构造函数中创建了一个在主线程中调用的串行端口。当 cPort
对象移动到 cThread
时,QSerialPort
仍然将其线程关联设置为原始线程。一个解决方案是在 ComPort::setupPort
.
中创建 QSerialPort
我看过一个similar question,但我觉得我正在实施正确的模式,但我仍然无法完成它!
好吧,我有一个 Gui
来启动和停止从 serial port
获取数据并显示必要的通信消息。为了保持 Gui
响应,我将 worker 移动到一个线程。我尝试根据:How to Use QThread in the Right Way and How To Really, Truly Use QThreads 实现 thread affinity。当我点击开始按钮时,我收到;
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();
}
感谢Kim Bowles Sørhus的解答,解决了我的问题。我在 ComPort
的构造函数中创建了一个在主线程中调用的串行端口。当 cPort
对象移动到 cThread
时,QSerialPort
仍然将其线程关联设置为原始线程。一个解决方案是在 ComPort::setupPort
.
QSerialPort