zoukankan      html  css  js  c++  java
  • qt 程序中执行额外程序和脚本

     1.最简单的,我们可以通过system直接启动一个应用程序或者脚本:(但是要调用  #include <stdlib.h>)
    system("./helloworld");  //可以直接运行可执行文件
    system("./hello.sh");  //也可以直接运行脚本

    技巧: system 函数参数是char* 如果正确返回0。

    2.  操作简单,但是我们可以很清晰的看到弊端:虽然很顺利的匹出一个进程去执行另外一个应用,但是我们拿不到这个新进程的任何东西,也就失去了对这个进程的控制权。所以我们可以尝试利用QProcess:

    QProcess *workPacePath  = new QProcess();
    workPacePath->start("pwd");
    connect(workPacePath,SIGNAL(readyReadStandardOutput()) ,this, SLOT(workPacePathSlot()) );

    这样就能通过槽函数读取第三方可执行程序的输出了(但是前提 workPacePath设置全局的)

    void MainWindow::workPacePathSlot()
    {
        QString workPacePathTemp  = workPacePath->readAll();
        Singleton::workPacePathGlobal =workPacePathTemp.mid(0,workPacePathTemp.length()-8);  // /home/alvin/code/keysiQt/
        qDebug() << "工作空间:"  <<  Singleton::workPacePathGlobal << endl;
    }

    拿到proc指针,我们可以做一些我们想做的事情。做嵌入式应用编程的朋友可能时常会受到环境变量的困扰,很纳闷为什么总是找不到这库那库。所以我们可以再完善一下:

    QProcess *proc = new QProcess();
    proc->setEnvironment(proc->environment());
    proc->start(str);
    proc->waitForStarted();

     如果我们想要执行的脚本需要传参呢?我们有必要完善一下参数列表:

    QString program = "./hello.sh";
    QStringList arguments;
    arguments << str;
    QProcess *myProcess = new QProcess();
    myProcess->start(program, arguments);

    项目中,我们经常遇到这样的情况:模块一单独工作正常,模块二单独工作也正常,但是整合到一起,在特定的环境下就出这样那样的问题。举一个启动应用程序的例子:进程间通信很容易出错,进程A发送启动helloworld的消息给进程B,进程B接到消息就启动helloworld。进程A只发送一次消息,但是进程B却接到2个发送任务,连续启动2个helloworld,这种错误很致命,尤其是在内存紧张的环境下,但是的确不容易排查。所以,为了避免悲剧的发生,哪怕我们不能准确的定位进程间通信的错误根源,聪明的程序员依旧可以解决这个问题:

    system("ps | grep helloworld |grep -v grep || ./helloworld &"); 

    如果你还不熟悉脚本语言,那么我很乐意解释一下:ps查看系统进程信息,grep检索一下helloworld相关的进程,然后排除掉grep本身这个进程,如果已经存在一个helloworld,那么不进去执行,如果没有存在helloworld,就启动一个helloworld。即完成了单一启动保护处理。

    如果你需要必须保证启动一个新的helloworld,那么依旧有好办法,先杀掉可能存在的helloworld,然后再启动,无声无息:

    system("killall helloworld"); 

    如果不确定应用名字就是helloworld,我们只需要把命令替换成:

    ps aux | grep helloworld | grep -v grep |awk '{print $2}' | xargs kill 2&> /dev/null 

    需要提醒的是,根据ps的输出,找到pid那一列,如果在第一列,则改成print $1 ,Busybox可能会存在差异所以要注意

  • 相关阅读:
    Linux Enterprise Cluster NOtes Ch4 同步:ssh和rsync
    e805上不安装中文外挂支持中文,很简单而且实用
    ARM的一些概念性问题
    C#调用WORD处理的小项目 转
    ASP.NET面试题
    .net清除cookie代码|.net为什么不能清除cookie|.net cookie 过期代码
    c#字符串转数字的函数|c#字符串转数字的无错函数|c#字符串转数字的最好函数
    Wiki简介
    new 和override 重写区别
    禁用IE的后退按钮|显示网页已过期|几种语言的实现方法|c#|javascript|html
  • 原文地址:https://www.cnblogs.com/wanghuixi/p/8983711.html
Copyright © 2011-2022 走看看