Execute additional programs and scripts in qt programs

 1. The simplest, we can directly start an application or script through the system: (but call #include <stdlib.h>)
system("./helloworld"); //You can directly run the executable file
system(" ./hello.sh"); //You can also run the script directly

Tip: The system function parameter is char* and returns 0 if correct.

2. The operation is simple, but we can clearly see the drawbacks: although a process is successfully picked up to execute another application, we cannot get anything of this new process, and we lose control of this process. right. So we can try to leverage QProcess:

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

In this way, the output of the third-party executable program can be read through the slot function (but the premise is that the workPacePath is set globally)

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

With the proc pointer in hand, we can do whatever we want. Friends who do embedded application programming may often be troubled by environment variables, and wonder why they can't find this library. So we can refine it a bit more:

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

 What if the script we want to execute needs to pass parameters? It is necessary for us to complete the parameter list:

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

In the project, we often encounter such a situation: module 1 works fine alone, and module 2 works fine alone, but when integrated together, there are such problems in a specific environment. Take an example of starting an application: Inter-process communication is prone to errors. Process A sends a message to start helloworld to process B, and process B starts helloworld upon receiving the message. Process A only sends a message once, but process B receives two sending tasks and starts two helloworlds in a row. This error is fatal, especially in a memory-constrained environment, but it is not easy to troubleshoot. Therefore, in order to avoid tragedy, even if we cannot accurately locate the source of the error in inter-process communication, smart programmers can still solve this problem:

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

If you are not yet familiar with scripting languages, then I will be happy to explain: ps to view system process information, grep to retrieve helloworld-related processes, and then exclude grep itself. If there is already a helloworld, then do not go in and execute, if not If helloworld exists, start a helloworld. That is, the single-start protection processing is completed.

If you need to ensure that a new helloworld is started, there is still a good way to kill the possible helloworld first, and then start it again, silently:

system("killall helloworld"); 

If we are not sure that the application name is helloworld, we just need to replace the command with:

 

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

It should be reminded that according to the output of ps, find the pid column, if it is in the first column, change it to print $1, there may be differences in Busybox, so pay attention

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325231820&siteId=291194637