zoukankan      html  css  js  c++  java
  • 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是一样的。

  • 相关阅读:
    zipkin启动报错(Caused by: java.lang.ClassNotFoundException: zipkin.Component)的解决方法
    Java中的long与double的区别
    redis使用笔记
    解决node编程频繁修改代码,需要重启服务器问题
    远程连接mysql要点 虚拟主机定义与分类
    详析静态网站与动态网站区别(服务器ip dns 端口)
    JavaEE-实验四 HTML与JSP基础编程
    JavaEE-实验三 Java数据库高级编程
    JavaEE-实验二 Java集合框架实验
    mysql中文乱码 常见编码问题解决方法分享
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/15770172.html
Copyright © 2011-2022 走看看