QProcess

QProcess常用三个函数:
QProcess::execute():
以阻塞方式打开外部程序,只有当外部程序执行完后才继续往后执行现程序。其中,外部程序的标准输出、标准错误都是重定向到现程序的标准输出和标准错误。

QProcess::start():
以子进程的方式打开外部程序,外部进程和现进程执行互不干扰,但外部进程的父进程是现进程。

QProcess::startDetached():

以分离方式打开外部程序,外部进程和现进程执行互不干扰,外部进程的父进程是系统的init进程。

其中start()函数为普通成员函数,execute()和startDetached()为静态成员函数


 
 
  1. process = new QProcess();
  2. connect(process,SIGNAL(started()),SLOT(started()));
  3. connect(process,SIGNAL(finished( int,QProcess::ExitStatus)),SLOT(finished()));
  4. 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. QString program = "E:\\hit-qt\\build-TestCallTo-Desktop_Qt_5_8_0_MinGW_32bit-Debug\\debug\\TestCallTo.exe";
  8. 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返回值

 

建立连接:

    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. qDebug()<<exitCode; // 被调用程序的main返回的int
  5. qDebug()<<exitStatus; // QProcess::ExitStatus(NormalExit)
  6. qDebug() << "finished-output-readAll:";
  7. qDebug()<<QString::fromLocal8Bit(process->readAll());
  8. qDebug()<< "finished-output-readAllStandardOutput:";
  9. qDebug()<<QString::fromLocal8Bit(process->readAllStandardOutput());
  10. }

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

建立连接:


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

回调:


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

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

 

4、外部程序:获取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. w.SetText(str1);

 

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

 

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


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

6、外部程序:返回数据

一句话即可。

要用这个:

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

不要用这个:

    printf("hello it is ok!");
 
 

7、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. }

8、process其他:调用命令行


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

9、判断启动成功或失败


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

10、用指针还是引用

(1)引用

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


 
 
  1. QProcess processCreatePdf;
  2. QStringList list;
  3. list<<"-l"<<"chi_sim"<<path<<CommonTools::getPathWithoutSuffix(path)<<"pdf";
  4. connect(&processCreatePdf,SIGNAL(started()),SLOT(onProPdfStarted()));
  5. connect(&processCreatePdf,SIGNAL(finished( int)),SLOT(onProPdfFinished()));
  6. 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. QStringList list;
  3. list<<"-l"<<"chi_sim"<<path<<CommonTools::getPathWithoutSuffix(path)<<"pdf";
  4. connect(&processCreatePdf,SIGNAL(started()),SLOT(onProPdfStarted()));
  5. connect(&processCreatePdf,SIGNAL(finished( int)),SLOT(onProPdfFinished()));
  6. processCreatePdf.start("tesseract", list);
  7. processCreatePdf.waitForFinished();
  8. qDebug()<<"code ending.";

 

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


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

 

(2)指针

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

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


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

11、execute

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

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

 

 

 

`QProcess`是Qt框架中用于启动外部程序和管理子进程的类。如果你发现`QProcess`实例瞬间结束,可能是因为启动的外部程序或命令执行完毕后立即退出,或者是存在某些错误导致进程提前终止。 要处理这个问题,你可以尝试以下几个步骤来诊断和解决问题: 1. 检查启动的外部程序是否正常运行。可以通过日志文件、控制台输出等途径来确认程序是否按预期执行。 2. 使用`QProcess::startDetached`方法代替`QProcess::start`方法。`startDetached`会启动一个外部程序,并立即返回,不会等待程序结束。这样可以确保`QProcess`对象不会因为外部程序的结束而结束。 3. 监听`QProcess`的信号。`QProcess`提供了几个信号,如`readyReadStandardOutput`、`readyReadStandardError`和`finished`,可以用来监控子进程的状态和输出。特别是`finished`信号,当进程结束时会发出,可以用来捕获进程退出状态和退出代码。 4. 确保没有调用`QProcess::kill`或`QProcess::terminate`方法强制结束进程。 5. 查看是否有错误信息输出,`QProcess::errorOccurred`信号可以用来获取错误信息。 以下是一个简单的例子,展示如何使用`QProcess`并连接其信号: ```cpp QProcess *process = new QProcess(this); connect(process, &QProcess::readyReadStandardOutput, this, &YourClass::readOutput); connect(process, &QProcess::readyReadStandardError, this, &YourClass::readError); connect(process, &QProcess::finished, this, &YourClass::processFinished); process->start("your_command", QStringList() << "arg1" << "arg2"); ``` 在上述代码中,`readOutput`和`readError`是你定义的方法,用来读取标准输出和标准错误,`processFinished`是用来处理进程结束的槽函数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值