Qt之:QProcess使用总结

本文详细介绍了如何在Qt中使用QProcess进行进程管理和交互,包括初始化、启动、获取输出和返回值等关键操作,并对比了start和startDetached的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、主程序:初始化及设定信号槽

    process = new QProcess();

    connect(process,SIGNAL(started()),SLOT(started()));

    connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),SLOT(finished()));

    connect(process,SIGNAL(stateChanged(QProcess::ProcessState)),SLOT(stateChanged()));

2、主程序:启动process

//    QStringList list;
//    list.append("hello_1");
//    list.append("world_2");
//    list.append("ok_3");
    QStringList list;
    list<<"hello_1"<<"world_2"<<"ok_3";

    QString program = "E:\\hit-qt\\build-TestCallTo-Desktop_Qt_5_8_0_MinGW_32bit-Debug\\debug\\TestCallTo.exe";

    process->start(program,list);

3、主程序:注意start和startDetached的区别

    process->startDetached(QString("E:\\hit-qt\\build-TestCallTo-Desktop_Qt_5_8_0_MinGW_32bit-Debug\\debug\\TestCallTo.exe"),list);

start是一体式的:外部程序启动后,将随主程序的退出而退出;

startDetached是分离式的:外部程序启动后,不会随主程序的退出而退出。

重要区别:如果是start则回调都可以正常接收到信息;如果是startDetached则回调无法正常接收到信息。

4、主程序:只有在外部程序退出之后才能获取到返回数据

经测试,只有在外部程序返回之后才能获取到不管是main的返回值,还是打印输出数据。

使用标准输出,任何时候都可以获得返回:

std::cout<<"it's from cout"<<std::endl;

 

5、主程序:获取main返回值

 

建立连接:

    connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),SLOT(finished(int,QProcess::ExitStatus)));

回调:

void Widget::finished(int exitCode,QProcess::ExitStatus exitStatus)
{
    qDebug()<<"finished";

    qDebug()<<exitCode;// 被调用程序的main返回的int
    qDebug()<<exitStatus;// QProcess::ExitStatus(NormalExit)
    qDebug() <<"finished-output-readAll:";
    qDebug()<<QString::fromLocal8Bit(process->readAll());
    qDebug()<<"finished-output-readAllStandardOutput:";
    qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());

}

6、主程序:获取返回输出流

建立连接:

    connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),SLOT(finished(int,QProcess::ExitStatus)));

    connect(process,SIGNAL(readyRead()),this,SLOT(readyRead()));

    connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readyReadStandardOutput()));

回调:

void Widget::finished(int exitCode,QProcess::ExitStatus exitStatus)
{
    qDebug()<<"finished";

    qDebug()<<exitCode;// 被调用程序的main返回的int
    qDebug()<<exitStatus;// QProcess::ExitStatus(NormalExit)
    qDebug() <<"finished-output-readAll:";
    qDebug()<<QString::fromLocal8Bit(process->readAll());// ""
    qDebug()<<"finished-output-readAllStandardOutput:";
    qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());// ""
}
void Widget::readyRead()
{
    qDebug()<<"readyRead-readAll:";
    qDebug()<<QString::fromLocal8Bit(process->readAll());// "hello it is ok!"
    qDebug()<<"readyRead-readAllStandardOutput:";
    qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());// ""
}
void Widget::readyReadStandardOutput()
{
    qDebug()<<"readyReadStandardOutput-readAll:";
    qDebug()<<QString::fromLocal8Bit(process->readAll());// ""
    qDebug()<<"readyReadStandardOutput-readAllStandardOutput:";
    qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());// ""
}

经测试发现,只有在readyRead回调下面使用readAll来读取,才可以读取到数据。

 

4、外部程序:获取main接收参数

    // 在这里打印参数
    QString str1 = QString("These are the %1 arguments passed  to main:").arg(argc);
    for(int i=1;i<argc;i++)
    {
        QString strN = QString("%1:%2,").arg(i).arg(argv[i]);
        str1+=strN;
    }

    w.SetText(str1);

 

5、外部程序:返回main参数

 

自定义返回的参数。程序会在a.exec()阻塞并在程序结束后才会执行return。

    a.exec();// 会在这里阻塞

    return 101;

6、外部程序:返回数据

一句话即可。

要用这个:

std::cout<<"it's from cout"<<std::endl;

不要用这个:

    printf("hello it is ok!");

7、process其他:stateChanged的各种状态

    connect(process,SIGNAL(stateChanged(QProcess::ProcessState)),SLOT(stateChanged(QProcess::ProcessState)));

回调:

void Widget::stateChanged(QProcess::ProcessState state)
{
    qDebug()<<"show state:";
    switch(state)
    {
     case QProcess::NotRunning:
        qDebug()<<"Not Running";
        break;
    case QProcess::Starting:
        qDebug()<<"Starting";
        break;
    case QProcess::Running:
        qDebug()<<"Running";
        break;
    default:
        qDebug()<<"otherState";
        break;
    }
}

8、process其他:调用命令行

void Widget::testPing()
{
    QStringList arguments;
    arguments<<"/c"<<"ping www.baidu.com";//

    QProcess process1(this);
    process1.start("cmd.exe",arguments);
    process1.waitForStarted();
    process1.waitForFinished();
    QString strResult = QString::fromLocal8Bit(process1.readAllStandardOutput());

    QMessageBox msgBox(this);
    msgBox.setText(strResult);
    msgBox.exec();
}

9、判断启动成功或失败

    process = new QProcess(parent);

    process->start("TestCallTo.exe",NULL);

    if(!process->waitForStarted())
    {
        qDebug()<<"failure!";
    }else
    {
        qDebug()<<"succ!";
    }

10、用指针还是引用

(1)引用

使用过程中,发现用引用,则会出问题,比如:

    QProcess processCreatePdf;

    QStringList list;
    list<<"-l"<<"chi_sim"<<path<<CommonTools::getPathWithoutSuffix(path)<<"pdf";

    connect(&processCreatePdf,SIGNAL(started()),SLOT(onProPdfStarted()));

    connect(&processCreatePdf,SIGNAL(finished(int)),SLOT(onProPdfFinished()));

    processCreatePdf.start("tesseract",list);

这样做会报错:

pdf-started.
QProcess: Destroyed while process ("tesseract") is still running.
pdf-finished.

started和finished是我做的调试输出,中间那一行是报错。

pdf-started.
pdf-finished.
code ending.

用引用类型,他会自动回收,当start执行完毕之后,程序认为QProcess已经完成使命了,自动回收,但是此时程序正在执行中,这样回收会导致强行退出,出错。

所以,如果用引用类型来做的话,必须加一个等待结束,然后才自动回收:

    QProcess processCreatePdf;

    QStringList list;
    list<<"-l"<<"chi_sim"<<path<<CommonTools::getPathWithoutSuffix(path)<<"pdf";

    connect(&processCreatePdf,SIGNAL(started()),SLOT(onProPdfStarted()));

    connect(&processCreatePdf,SIGNAL(finished(int)),SLOT(onProPdfFinished()));

    processCreatePdf.start("tesseract",list);

    processCreatePdf.waitForFinished();

    qDebug()<<"code ending.";

 

加了最后这句话之后,他就会阻塞在那里直到回收,注意,代码在这里是阻塞的,而且是先收到finish的消息,然后这个代码才往下走:

pdf-started.
pdf-finished.
code ending.

 

(2)指针

指针不会自动回收,那么我们可以不用waitForfinished.

回收的时候可以在finish的回调里面设置:

    processCreatePdf->deleteLater();

    processCreatePdf = NULL;

11、execute

此函数与start类似,他相当于start+waitForFinished。

此函数处于阻塞状态,与waiForFinished是一样的。

 

 

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值