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