You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:31:03