0

I'm considering to use QProcess to call a command line app (gpio) multiple times. Every time user clicks a button then a command is issued.

And the app output will be monitored and redirected to screeen. The code looks like the following.

void Gpio::command(QString argument)
{
//    if(process)
//        delete process;
    process = new QProcess(this);
    connect(process, SIGNAL(started()), this, SLOT(onStart()));
    connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinish(int,QProcess::ExitStatus)));
    connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(readGpio()));
    QString program("gpio");
    QStringList list = argument.split(" ");
    process->start(program, list);
}

Question: Should I delete process? Doing so I got:

QProcess: Destroyed while process is still running.

Monitoring exitCode and exitStatus I see they are always 0.

This question concerns more about the proper use of QProcess while "QProcess and shell : Destroyed while process is still running" focus on the specific error.

Community
  • 1
  • 1
KcFnMi
  • 5,516
  • 10
  • 62
  • 136
  • 4
    Possible duplicate of [QProcess and shell : Destroyed while process is still running](http://stackoverflow.com/questions/14504201/qprocess-and-shell-destroyed-while-process-is-still-running) – demonplus Nov 27 '15 at 10:57
  • do you need to run multiple processes i.e., is user allowed to click the button multiple times? or, a single process but different args every time? – ramtheconqueror Nov 27 '15 at 11:01
  • Different args every time. – KcFnMi Nov 27 '15 at 11:03

3 Answers3

1

as you don't want to run multiple processes concurrently (as per the comments), you don't need to create / delete the QProcess multiple times.

gpio.h

QProcess*   m_gpioProcess;

gpio.cpp file

Gpio::Gpio(.....),
   .....(),
   m_gpioProcess(new QProcess(this))
{
   m_gpioProcess->setProgram("gpio");

   connect(m_gpioProcess, SIGNAL(started()), this, SLOT(onStart()));
   connect(m_gpioProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinish(int,QProcess::ExitStatus)));
   connect(m_gpioProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readGpio()));
}

void Gpio::command(const QString& args)
{
  if (m_gpioProcess->state() != QProcess::NotRunning) {
    qDebug() << "Process already running, ignoring the request";
    return;
  }

  m_gpioProcess->setArguments(args.split(" "));
  m_gpioProcess->start();
  if (m_gpioProcess->waitForStarted()) {
    qDebug() << "Process started with arguments:" << m_gpioProcess->arguments();
  }
}

if you want to prevent user clicking the button multiple times, consider enabling / disabling the button as per m_gpioProcess state.


for Qt 4.8, just remove this line

m_gpioProcess->setProgram("gpio");

and this line

m_gpioProcess->setArguments(args.split(" "));

and change this line

m_gpioProcess->start();

to

m_gpioProcess->start("gpio", args.split(" "));
ramtheconqueror
  • 1,907
  • 1
  • 22
  • 35
  • I think this is directed to Qt5, I'm on Qt4. Can't see `setProgram` and `setArguments` in Qt4. Is there any way around? – KcFnMi Nov 27 '15 at 13:41
  • So I got `QProcess::start: Process is already running`. I don't want to ignore the request. How long should I wait to shoot a new command (each command returns almost immediately)? – KcFnMi Nov 27 '15 at 14:22
  • you have the `finished(int,QProcess::ExitStatus)` signal to monitor this. You should be able to create new command right after this. – ramtheconqueror Nov 27 '15 at 14:31
  • You mean after `exitCode=0` and `exitStatus=0` I should be able to call `start` again (with different args)? I'm doing that and getting `QProcess::start: Process is already running`. Perhaps something must be done between this two steps? – KcFnMi Nov 27 '15 at 14:45
  • May ask what happens after finished is emitted that prevents the object to be deleted? I guess the same thing that prevents me to start again also prevents me to delete the object. – KcFnMi Nov 27 '15 at 14:48
  • remember, `process->waitForFinished()` will freeze your app until it returns. make sure that your command is actually finishing quite fast. – ramtheconqueror Nov 27 '15 at 15:06
0

Well, It seems I was forgetting process->waitForFinished(); after the call to start. This seems to solve the problem.

KcFnMi
  • 5,516
  • 10
  • 62
  • 136
-1

add following code maybe helpful:

process->close();
  • Could you add more of an explanation? What does this code do? Where do you add this line of code? – Tyler2P Jun 20 '21 at 13:25