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