不能创建子对象
QObject: Cannot create children
我想通过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()
相关文章:
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 具有包含其他对象的类的对象创建顺序
- 为什么我们再次从结构对象创建结构变量?
- 将对象创建为全局/静态对象会崩溃,而本地对象不会崩溃
- 如何创建一个对象创建函数,该函数将由与其关联的名称调用?
- 如何为自定义模板对象创建专门的函数模板
- 对象创建错误的C++矢量
- 如何为Python Swigged C++对象创建和分配回调函数
- 在 C++ 中为 C 样式对象创建一个透明包装类
- 此类模板的对象创建如何工作?
- C++ 中的对象创建类型有什么区别?
- 未知大小的数组作为类成员,用于在运行时(对象创建时间)创建数组的对象
- 如何仅通过父类对象限制对象创建
- 在正确性或良好的代码结构方面,这种动态对象创建看起来如何
- 无法将类对象创建为另一个类的成员
- 如何从现有基类对象创建派生类对象
- 在 DTor 之前删除的静态对象创建的线程?
- C++:定义多个构造函数时的对象创建/销毁序列
- 从对象创建矢量包装器,该对象只允许使用索引访问向量
- 是否可以为CPP中的对象创建一组指针