写关于串口通信的代码,自定义类 CCommModel 继承自 QThread
重写的 void CCommModel::run()中
m_pSerialPort->write(arrtx);
之后出现错误:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0x1bd1c938), parent's thread is QThread(0x1bd1c3c8), current thread is CCommModel(0x424060)
原因:在主线程中创建了QSerialPort对象在子线程中调用,run()为子线程,QSerialPort的对象m_pSerialPort在类的构造函数中创建即为主线程对象。

解决方法1:不推荐

派生类外部定义QSerialPort指针,在run函数中再定义对象(new),并且数据的读、写都在run函数中进行。

上述方法可以解决报错,但是针对不仅仅具有读串口数据需求、还需要向串口写数据的情况,显然这样的方法会让run函数变得十分臃肿,代码的维护十分麻烦。

解决方法2:推荐使用

运用继承QObject,结合MoveToThread()的方式:
自定义CCommModel类,继承自QObject,增加成员 QThread *m_pThread,QSerialPort *m_pSerialPort,
在类的构造函数中:定义串口对象 m_pSerialPort = new QSerialPort,使用QObject的MoveToThread()将派生类自己移入 m_pThread线程中 this->moveToThread(m_pThread),关联执行线程的信号和槽,关联关闭串口的信号和槽。
在打开串口方法中:如果串口对象 m_pSerialPort 为空,则重新定义串口对象,然后进行串口参数设置,将串口对象移入m_pThread线程中 m_pSerialPort->moveToThread(m_pThread),然后启动线程 m_pThread->start(),发射信号来执行线程。

这样派生类中的槽函数以及QSerialPort中的信号与槽函数都将在 m_pThread线程执行。

需要注意的是,QSerialPort对象在执行关闭串口时,也需要在 m_pThread线程中执行,可以使用槽函数来执行关闭串口。

在关闭串口方法中:发射关闭串口的信号。在关闭串口的槽函数中执行关闭串口 m_pSerialPort->close(),删除对象 m_pSerialPort->deleteLater();m_pSerialPort = nullptr。

执行线程的槽函数:一般包含一个循环,使用变量作为循环结束的标志,在循环中执行串口发送,串口接收。

另外,connect()函数的第五个参数,Qt::Direcconnection,Qt::Queuenconnection以及其他的,不同的连接方式,会影响槽数执行所在的线程,参考https://blog.csdn.net/qq_16952303/article/details/51585577

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

返回
顶部