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是一样的。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM