Qt Creator中使用QEventLoop触发段错误的原因排查
Qt串口应用取消操作触发段错误问题
我开发了一个Qt应用,用于通过串口收发数据:向设备发送数据后会收到响应。串口类PortSerial运行在后台线程中监听设备,核心代码如下:
#include "portserial.h" ///! //! \brief PortSerial::PortSerial //! \param port the port number or address //! \param dev connected seprately for each device //! PortSerial::PortSerial(QString port, int dev) { printErrors("PortSerial","start fn"); devid=dev; if(!openport(port)) { printErrors("PortSerial","Port:"+port+" can not open."); } moveToThread(&t); connect(&t,SIGNAL(started()),this,SLOT(readserialport())); t.start(); } //! //! \brief PortSerial::writeData with qbyte array //! \param ba //! void PortSerial::writeData(QByteArray ba) { printErrors("writeData","start fn"); serialport.write(ba); } //! //! \brief PortSerial::readserialport //! void PortSerial::readserialport() { printErrors("readserialport","start fn"); while (1) { if(serialport.waitForReadyRead(100)) { printErrors("readserialport","the queue is clean"); printErrors("readserialport","wait for read data from sensor"); QByteArray responseData=serialport.readAll(); while (serialport.waitForReadyRead(100)) { responseData+=serialport.readAll(); } printErrors("readserialport","read:"+responseData.toHex()+"\n devid : "+devid); emit readyread(responseData,devid); } } }
当设备返回数据时,会触发readyread信号,填充FP类中的队列。FP类作为UI(QML)与串口类的中间层,当UI发送指令到FP类后,指令会转发给串口类。此时需要等待设备响应,因此实现了WaitProccessorForResult函数,通过QEventLoop等待fullQueue信号、CancelUIOperationChanged信号或超时信号来退出循环。但用户点击取消按钮触发CancelUIOperationChanged信号时,会出现段错误;若不点击取消则运行正常。此前使用QCoreApplication::processEvents也存在同样的段错误问题,改用QEventLoop后问题未解决。相关代码如下:
int FP::WaitProccessorForResult(int milisecond) { //ui_interface()->cancelUIOperation() => if true means cancel button pressed printErrors("WaitProccessorForResult","in waiting....."); int rv=0;int i=0; //ui_interface()->setCancelUIOperation(false); QEventLoop loop; QTimer timer; //timer.setSingleShot(true); //if device answer quit the loop connect( this,SIGNAL(fullQueue()), &loop,SLOT(quit()) ); //if user cancel quit the loop connect(ui_interface(),SIGNAL(CancelUIOperationChanged()),&loop,SLOT(quit())); //if timer finished quit the loop connect( &timer, SIGNAL(timeout()), &loop, SLOT(quit()) ); timer.start(milisecond); loop.exec(); if(timer.isActive()) qDebug("===============QEventLoop================encrypted"); else qDebug("+++++++++++++++QEventLoop++++++++++++++++timeout"); // for( i=0;i<milisecond;) // { // i=i+1000; // QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); // qDebug()<<i; // if(myque.length()>0 || ui_interface()->cancelUIOperation()) // { // i=milisecond; // break; // } // } if(ui_interface()->cancelUIOperation()) { myque.clear(); printErrors("WaitProccessorForResult"," in CancelUIOperation:"+ui_interface()->cancelUIOperation()); ui_interface()->setCancelUIOperation(false); rv=cancelByUser; //FPCancel(); } return rv; }
内容的提问来源于stack exchange,提问作者H.Ghassami
相关产品推荐
相关产品推荐

