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