[英]QObject: Cannot create children
I want to communicate via the serial port in Qt (Qt 5.4.0, Ubuntu 14.04.3), and for decreasing the workload I want to shift the communication part into a second thread. 我想通过Qt(Qt 5.4.0,Ubuntu 14.04.3)中的串行端口进行通信,为了减少工作量,我想将通信部分转移到第二个线程中。 Thus I created the following files:
因此,我创建了以下文件:
serial_controller.cpp: serial_controller.cpp:
#include "serial_controller.h"
serial_controller_worker::serial_controller_worker(const QString &portname, int waitTimeout, int BaudRate)
{
this->portName = portname;
this->waitTimeout = waitTimeout;
this->baudrate = BaudRate;
this->serial.setPortName(this->portName);
this->serial.setBaudRate(this->baudrate);
if (!serial.open(QIODevice::ReadWrite))
{
emit error(tr("Can't open %1, error code %2").arg(portName).arg(serial.error()));
qDebug() << tr("Can't open %1, error code %2").arg(portName).arg(serial.error());
return;
}
else
{
emit error(tr("Opened %1").arg(portName));
qDebug() << tr("Opened %1").arg(portName);
}
}
serial_controller_worker::~serial_controller_worker()
{
this->serial.close();
}
void serial_controller_worker::process_data()
{
bool newData = false;
bool run = false;
this->mutex.lock();
newData = this->sendNewData;
run = this->recvLoop;
this->mutex.unlock();
if(run == false)
{
qDebug() << "Run is false, returning!";
return;
}
else
{
if(newData == true)
{
qDebug() << "TransAction started!";
QByteArray requestData = request.toLocal8Bit();
qDebug() << "Writing data: " << requestData;
serial.write(requestData);
qDebug() << "Data written";
if(serial.waitForBytesWritten(waitTimeout))
{
if(serial.waitForReadyRead(waitTimeout))
{
qDebug() << "Waiting for data!";
QByteArray responseData = serial.readAll();
while(serial.waitForReadyRead(10))
responseData += serial.readAll();
QString response(responseData);
QByteArray response_arr = response.toLocal8Bit();
qDebug() << "Response is: " << response_arr.toHex();
emit this->response(response);
}
else
{
qDebug() << "Wait read response timeout";
emit this->timeout(tr("Wait read response timeout %1").arg(QTime::currentTime().toString()));
}
}
else
{
qDebug() << "Wait write request timeout!";
emit this->timeout(tr("Wait write request timeout %1").arg(QTime::currentTime().toString()));
}
mutex.lock();
this->sendNewData = false;
mutex.unlock();
}
QThread::msleep(10);
this->process_data();
}
}
void serial_controller_worker::transaction(const QString &request)
{
mutex.lock();
this->sendNewData = true;
this->recvLoop = true;
this->request = request;
mutex.unlock();
this->process_data();
}
//Serial_controller functions
serial_controller::serial_controller(const QString &portName, int waitTimeout, int BaudRate)
{
serial_controller_worker *newWorker = new serial_controller_worker(portName, waitTimeout, BaudRate);
newWorker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, newWorker, &QObject::deleteLater);
connect(this, &serial_controller::newTransaction, newWorker, &serial_controller_worker::transaction);
connect(newWorker, &serial_controller_worker::response, this, &serial_controller::response_slot);
workerThread.start();
}
serial_controller::~serial_controller()
{
workerThread.quit();
workerThread.wait();
}
void serial_controller::transaction(const QString &request)
{
emit this->newTransaction(request);
}
void serial_controller::response_slot(QString response)
{
emit this->response(response);
}
serial_controller.h: serial_controller.h:
#include <QObject>
#include <QThread>
#include <QVector>
#include <memory>
#include <QtSerialPort/QtSerialPort>
class serial_controller_worker: public QObject
{
Q_OBJECT
private:
QString portName;
QString request;
int waitTimeout;
QMutex mutex;
QWaitCondition cond;
int baudrate;
QSerialPort serial;
bool quit;
bool sendNewData = false;
bool recvLoop = false;
public slots:
void transaction(const QString &request);
signals:
void response(QString s);
void error(const QString &s);
void timeout(const QString &s);
public:
serial_controller_worker(const QString &portname, int waitTimeout, int BaudRate);
~serial_controller_worker();
void process_data(void);
};
class serial_controller: public QObject
{
Q_OBJECT
private:
QThread workerThread;
QString portName;
QString request;
int waitTimeout;
QMutex mutex;
QWaitCondition cond;
int baudrate;
QSerialPort serial;
public:
serial_controller(const QString &portName, int waitTimeout, int BaudRate);
~serial_controller();
public slots:
void transaction(const QString &request);
void response_slot(QString response);
signals:
void newTransaction(const QString &request);
void response(QString s);
void error(const QString &s);
void timeout(const QString &s);
};
Now I have the problem that a) when calling serial_controller_worker::process_data()
, I get the output 现在我有一个问题:a)调用
serial_controller_worker::process_data()
,我得到了输出
Writing data: "..."
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0x2533e60), parent's thread is QThread(0x2486850), current thread is QThread(0x25341e0)
Data written
QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
Then I get the answer, but afterwards I am not able to call serial_controller_worker::transaction()
anymore, I simply get no notice that it is executed. 然后我得到了答案,但是之后我再也无法调用
serial_controller_worker::transaction()
了,我根本不知道它已被执行。 Why? 为什么? What am I doing wrong here?
我在这里做错了什么?
Edit 1: Solution to problem 1 is: Replacing 编辑1:问题1的解决方案是:更换
QSerialPort serial;
with 与
QSerialPort *serial;
serial = new QSerialPort(this);
Still the second problem is unsolved. 第二个问题仍未解决。
Ok, found the answer. 好的,找到答案了。
The solution to the first problem is: 第一个问题的解决方案是:
I have to replace 我必须更换
QSerialPort serial;
with 与
QSerialPort *serial;
serial = new QSerialPort(this);
The solution to the second problem: 第二个问题的解决方案:
Remove the line 删除线
this->process_data();
from the function process_data()
来自函数
process_data()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.