0

I've created a simple app in QT Creator 4.2.0, i.e., QT Widgets Application, used all defaults. Added one button. I've tried to mimic multiple posts I've found around web, but can not get a python script to launch correctly. I keep getting this message:

QProcess: Destroyed while process ("python.exe") is still running.

Python.exe is added to Path variable.

What I would like to happen is, when the button is pressed, launch the python script, and then wait some amount of time (but don't lock up the GUI), then terminate python script.

I apologize, I'm very new to c++/QT.

My QT code is below:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
#include <QDir>
#include <QCoreApplication>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{

    //define file paths..  make sure the paths work
    QDir dir1("C:/SFI/FastScan/Calibration/");
    QFile file1("C:/SFI/FastScan/Calibration/pytest.py");
    QString script1 = "C:/SFI/FastScan/Calibration/pytest.py";
    QFile file2(script1);

    qDebug() << dir1.exists() << file1.exists() << file2.exists();
    //  these all result in true, true true

    // latest method I tried
    QString command("python.exe");
    QStringList args;
    args << script1;
    QProcess *myProcess = new QProcess(this);
    myProcess->start(command,args);

}

The python script is below, python 2.7 ...

#!/usr/bin/env python

import time

while True:
    time.sleep(1)
    print time.time()

Edit: I kept at it, by replacing the last 5 lines of my QT code with these two lines I can launch my python script,

QProcess *myProcess = new QProcess();
myProcess->startDetached("python.exe C:/SFI/FastScan/Calibration/pytest.py" );

I've tried to use the myProcess.terminate(), but can not get the script to exit.

AAEM
  • 1,837
  • 2
  • 18
  • 26
hokiebird
  • 280
  • 1
  • 5
  • 15

1 Answers1

1

When you call start on QProcess it runs the script but does not wait for it to finish so your on_pushButton_clicked() function as it is in the question will exit after starting and there will be no way to kill the script.

startDetached is a static function that runs the process independently of the calling process so there is no way to kill it as the myProcess object does not keep a handle to the started process. For your application calling start is the better approach.

One way to do this would be like this:

myProcess->start(command, args);

//check that the process actually starts
if (!myProcess->waitForStarted()) {
    qDebug("Could not start process");
    return;
}


QTime time;
time.start();
//wait 4 seconds
while (time.elapsed() < 4000) {
    //keep the GUI working
    QApplication::processEvents();
}

myProcess->kill();
// wait for the process to actually stop
myProcess->waitForFinished();

delete myProcess;

After starting, the loop waits for 4 seconds before killing the process. The processEvents function keeps the GUI alive while waiting.

After calling kill, you need to call waitForFinished to wait for the process to actually finish otherwise you get the error you saw as the QProcess object is destroyed before the process has actually terminated.

The problem with the above approach is that the GUI continues to function, while in the on_pushButton_clicked() function. So if you called an "exit" function from the GUI while in the loop the application would exit with the script still running. So this approach is OK if all you want to do in the GUI is update a progress bar or other display widget. In that case you could pass QEventLoop::ExcludeUserInputEvents to processEvents.

If the user can do other things in the GUI then I would make the QProcess a class member and create a separate slot to kill the script. You could then use a QTimer to call this slot after a specified time interval.

AAEM
  • 1,837
  • 2
  • 18
  • 26
David Dibben
  • 18,460
  • 6
  • 41
  • 41
  • thanks for the response. Unfortunately, add your provided code did not fix my problem. The python script still does not launch. Interestingly I replaced 'python.exe' with 'notepad.exe', and notepad launches with my script in it, and closes after four seconds. It seems there is a particular problem with python.exe. – hokiebird Jan 15 '17 at 22:54
  • What are you expecting when the python script launches? Python is a console application so I would expect it to run in the background with no visible output. Did you check the task manager to see if python.exe is running? – David Dibben Jan 17 '17 at 03:29