不能创建子对象

QObject: Cannot create children

本文关键字:对象 创建 不能      更新时间:2023-10-16

我想通过Qt (Qt 5.4.0, Ubuntu 14.04.3)中的串口进行通信,并且为了减少工作量,我想将通信部分转移到第二个线程中。因此,我创建了以下文件:

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:

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

现在我的问题是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

然后我得到了答案,但是之后我不能再调用serial_controller_worker::transaction()了,我只是没有得到它被执行的通知。为什么?我哪里做错了?

编辑1:问题1的解决方案是:替换

QSerialPort serial;

QSerialPort *serial;
serial = new QSerialPort(this);

第二个问题仍然没有解决。

好了,找到答案了。
第一个问题的解决方案是:
我必须替换

QSerialPort serial;

QSerialPort *serial;
serial = new QSerialPort(this);

第二个问题的解:
删除

this->process_data();

from function process_data()