Qt QProcess使用总结

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

1     process = new QProcess();
2  
3     connect(process,SIGNAL(started()),SLOT(started()));
4  
5     connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),SLOT(finished()));
6  
7     connect(process,SIGNAL(stateChanged(QProcess::ProcessState)),SLOT(stateChanged()));

2、主程序:启动process

 1 //    QStringList list;
 2 //    list.append("hello_1");
 3 //    list.append("world_2");
 4 //    list.append("ok_3");
 5     QStringList list;
 6     list<<"hello_1"<<"world_2"<<"ok_3";
 7  
 8     QString program = "E:\\hit-qt\\build-TestCallTo-Desktop_Qt_5_8_0_MinGW_32bit-Debug\\debug\\TestCallTo.exe";
 9  
10     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返回值

建立连接:

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

回调:

 1 void Widget::finished(int exitCode,QProcess::ExitStatus exitStatus)
 2 {
 3     qDebug()<<"finished";
 4  
 5     qDebug()<<exitCode;// 被调用程序的main返回的int
 6     qDebug()<<exitStatus;// QProcess::ExitStatus(NormalExit)
 7     qDebug() <<"finished-output-readAll:";
 8     qDebug()<<QString::fromLocal8Bit(process->readAll());
 9     qDebug()<<"finished-output-readAllStandardOutput:";
10     qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());
11 }

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

建立连接:

1     connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),SLOT(finished(int,QProcess::ExitStatus)));
2  
3     connect(process,SIGNAL(readyRead()),this,SLOT(readyRead()));
4  
5     connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readyReadStandardOutput()));

回调:

 1 void Widget::finished(int exitCode,QProcess::ExitStatus exitStatus)
 2 {
 3     qDebug()<<"finished";
 4  
 5     qDebug()<<exitCode;// 被调用程序的main返回的int
 6     qDebug()<<exitStatus;// QProcess::ExitStatus(NormalExit)
 7     qDebug() <<"finished-output-readAll:";
 8     qDebug()<<QString::fromLocal8Bit(process->readAll());// ""
 9     qDebug()<<"finished-output-readAllStandardOutput:";
10     qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());// ""
11 }
12 void Widget::readyRead()
13 {
14     qDebug()<<"readyRead-readAll:";
15     qDebug()<<QString::fromLocal8Bit(process->readAll());// "hello it is ok!"
16     qDebug()<<"readyRead-readAllStandardOutput:";
17     qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());// ""
18 }
19 void Widget::readyReadStandardOutput()
20 {
21     qDebug()<<"readyReadStandardOutput-readAll:";
22     qDebug()<<QString::fromLocal8Bit(process->readAll());// ""
23     qDebug()<<"readyReadStandardOutput-readAllStandardOutput:";
24     qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());// ""
25 }

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

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

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

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

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

1     a.exec();// 会在这里阻塞
2  
3     return 101;

9、外部程序:返回数据

一句话即可。

要用这个:

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

不要用这个:

printf("hello it is ok!");

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

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

回调:

 1 void Widget::stateChanged(QProcess::ProcessState state)
 2 {
 3     qDebug()<<"show state:";
 4     switch(state)
 5     {
 6      case QProcess::NotRunning:
 7         qDebug()<<"Not Running";
 8         break;
 9     case QProcess::Starting:
10         qDebug()<<"Starting";
11         break;
12     case QProcess::Running:
13         qDebug()<<"Running";
14         break;
15     default:
16         qDebug()<<"otherState";
17         break;
18     }
19 }

11、process其他:调用命令行

 1 void Widget::testPing()
 2 {
 3     QStringList arguments;
 4     arguments<<"/c"<<"ping www.baidu.com";//
 5  
 6     QProcess process1(this);
 7     process1.start("cmd.exe",arguments);
 8     process1.waitForStarted();
 9     process1.waitForFinished();
10     QString strResult = QString::fromLocal8Bit(process1.readAllStandardOutput());
11  
12     QMessageBox msgBox(this);
13     msgBox.setText(strResult);
14     msgBox.exec();
15 }

12、判断启动成功或失败

 1     process = new QProcess(parent);
 2  
 3     process->start("TestCallTo.exe",NULL);
 4  
 5     if(!process->waitForStarted())
 6     {
 7         qDebug()<<"failure!";
 8     }else
 9     {
10         qDebug()<<"succ!";
11     }

13、用指针还是引用

(1)引用

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

 1     QProcess processCreatePdf;
 2  
 3     QStringList list;
 4     list<<"-l"<<"chi_sim"<<path<<CommonTools::getPathWithoutSuffix(path)<<"pdf";
 5  
 6     connect(&processCreatePdf,SIGNAL(started()),SLOT(onProPdfStarted()));
 7  
 8     connect(&processCreatePdf,SIGNAL(finished(int)),SLOT(onProPdfFinished()));
 9  
10     processCreatePdf.start("tesseract",list);

这样做会报错:

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

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

1 pdf-started.
2 pdf-finished.
3 code ending.

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

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

 1     QProcess processCreatePdf;
 2  
 3     QStringList list;
 4     list<<"-l"<<"chi_sim"<<path<<CommonTools::getPathWithoutSuffix(path)<<"pdf";
 5  
 6     connect(&processCreatePdf,SIGNAL(started()),SLOT(onProPdfStarted()));
 7  
 8     connect(&processCreatePdf,SIGNAL(finished(int)),SLOT(onProPdfFinished()));
 9  
10     processCreatePdf.start("tesseract",list);
11  
12     processCreatePdf.waitForFinished();
13  
14     qDebug()<<"code ending.";

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

1 pdf-started.
2 pdf-finished.
3 code ending.

(2)指针

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

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

1     processCreatePdf->deleteLater();
2  
3     processCreatePdf = NULL;

14、execute

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

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

原文地址:https://www.cnblogs.com/ybqjymy/p/15770172.html