QT解决因QEventLoop退出失败导致的程序崩溃问题

前言:为了通过cmd输入adb命令来执行某些操作,在确保执行完之后再把运行cmd的进程关闭。

为了实现这个功能,我选择通过使用connect绑定lambda表达式进行后台数据的获取,代码如下。

//检测权限是否编辑成功
        proExecuteADB->write("echo $?\n");
        QString chmoddata;
        QStringList chmodqstrl;
        QEventLoop chmodloop;	//创建一个事件循环,等待进程调用完毕
        //绑定进程可以读取通道内容信号,当有可以读取的内容时,readyReadStandardOutput信号被发出
        connect(proExecuteADB,&QProcess::readyReadStandardOutput,this,[&chmodloop,&chmoddata,&chmodqstrl,&proExecuteADB,&IfDownloadSuccess]()
        {
            //读取通道内所有内容
            QString slToStr;
            chmoddata=QString::fromLocal8Bit(proExecuteADB->readAllStandardOutput());
            chmodqstrl<<chmoddata;
            slToStr=chmodqstrl.join("");
            //判断读取到的内容是否包含特定字符串
            if(slToStr.contains("connect failed"))
            {
                IfDownloadSuccess=false;
                proExecuteADB->kill();
                chmodloop.quit();	//退出事件循环
            }
            if(slToStr.count("echo $?", Qt::CaseInsensitive)==1)
            {
                QString str1=slToStr.mid(slToStr.indexOf("echo $?")+10,1);
                if("0"==str1)
                {
                    IfDownloadSuccess=true;
                    proExecuteADB->kill();
                    chmodloop.quit();	//退出事件循环
                }
            }
            if(slToStr.count("echo $?", Qt::CaseInsensitive)==2)
            {
                QString str1=slToStr.mid(slToStr.indexOf("echo $?")+10,1);
                QString str2=slToStr.mid(slToStr.indexOf("echo $?",slToStr.indexOf("echo $?")+10)+10,1);
                if((str1!="0")&&("0"==str2))
                {
                    IfDownloadSuccess=true;
                    proExecuteADB->kill();
                    chmodloop.quit();	//退出事件循环
                }
            }
        });
        chmodloop.exec();

connect的作用是在进程已经准备好了读取标准输出时,执行lambda表达式中的代码,首先通过readAllStandardOutput()函数获取读取到的字符串,再加入到字符串队列中,以便整合。

当函数判断获得到的输出结构中有相应的返回值,则杀掉进程并退出loop循环。

一般来说调用完quit()函数之后,程序应该可以执行exec后面的代码,但出于某种我未分析出的原因,程序会再进一次lambda表达式,此时如果执行:chmoddata=QString::fromLocal8Bit(proExecuteADB->readAllStandardOutput());

此时进程已经被清除了,读取通道已关闭,再调用readAllStandardOutput()函数会造成无法读取,导致程序崩溃。之前尝试加了个bool变量来判断是否已经执行过quit()函数,不过在最后一次进入lambda表达式时,bool变量的数值会变得非1非0,而是40之类奇怪的数值。

//给chmoddata赋值会报错,提示无法正常读取
chmoddata=QString::fromLocal8Bit(proExecuteADB->readAllStandardOutput());
chmodqstrl<<chmoddata;
slToStr=chmodqstrl.join("");

解决方法就是在读取信息前加一个判断,判断进程是否存在。不能以进程读输出是否准备就绪为条件:&QProcess::readyReadStandardOutput;因为程序会检测到是可以读取的,但是读不到东西。

//检测权限是否编辑成功
        proExecuteADB->write("echo $?\n");
        QString chmoddata;
        QStringList chmodqstrl;
        QEventLoop chmodloop;	//创建一个事件循环,等待进程调用完毕
        //绑定进程可以读取通道内容信号,当有可以读取的内容时,readyReadStandardOutput信号被发出
        connect(proExecuteADB,&QProcess::readyReadStandardOutput,this,[&chmodloop,&chmoddata,&chmodqstrl,&proExecuteADB,&IfDownloadSuccess]()
        {
            //读取通道内所有内容
            QString slToStr;
            //增加进程是否存在的判断,如果存在则读取,不存在则继续执行,避免了因为无法读取造成的             程序崩溃问题
            if(proExecuteADB!=NULL)
            {
                chmoddata=QString::fromLocal8Bit(proExecuteADB->readAllStandardOutput());
                chmodqstrl<<chmoddata;
                slToStr=chmodqstrl.join("");
            }
            //判断读取到的内容是否包含特定字符串
            if(slToStr.contains("connect failed"))
            {
                IfDownloadSuccess=false;
                proExecuteADB->kill();
                chmodloop.quit();	//退出事件循环
            }
            if(slToStr.count("echo $?", Qt::CaseInsensitive)==1)
            {
                QString str1=slToStr.mid(slToStr.indexOf("echo $?")+10,1);
                if("0"==str1)
                {
                    IfDownloadSuccess=true;
                    proExecuteADB->kill();
                    chmodloop.quit();	//退出事件循环
                }
            }
            if(slToStr.count("echo $?", Qt::CaseInsensitive)==2)
            {
                QString str1=slToStr.mid(slToStr.indexOf("echo $?")+10,1);
                QString str2=slToStr.mid(slToStr.indexOf("echo $?",slToStr.indexOf("echo $?")+10)+10,1);
                if((str1!="0")&&("0"==str2))
                {
                    IfDownloadSuccess=true;
                    proExecuteADB->kill();
                    chmodloop.quit();	//退出事件循环
                }
            }
        });
        chmodloop.exec();

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值