2017-01-14 12 views
0

Я создал простое приложение в QT Creator 4.2.0, то есть приложение QT Widgets, использовало все значения по умолчанию. Добавлена ​​одна кнопка. Я попытался имитировать несколько сообщений, которые я нашел в Интернете, но не могу запустить скрипт python правильно. Я продолжаю получать это сообщение «QProcess: Destroyed while process (« python.exe ») все еще работает». Python.exe добавляется в переменную Path.Как запустить и завершить скрипт python из приложения QT GUI, созданного в QT Creator 4.2.0

Что бы я хотел сказать, когда кнопка нажата, запустите скрипт python, а затем подождите некоторое время (но не блокируйте GUI), а затем завершите скрипт python.

Прошу прощения, я очень новичок в C++/QT.

Спасибо, Джон

Мой QT код ниже ...

#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); 

} 

Скрипт питон ниже, питон 2,7 ...

#!/usr/bin/env python 

import time 

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

Edit: Я все на нем, заменив последние 5 строк моего кода QT этими двумя строками, я могу запустить свой скрипт python,

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

Я попытался использовать myProcess.terminate(), но не могу заставить скрипт выйти. Любая помощь будет рассмотрена! Благодаря!

ответ

1

Когда вы вызываете start на QProcess, он запускает скрипт, но не дождался его завершения, поэтому ваша функция on_pushButton_clicked(), поскольку она находится в вопросе, выйдет после запуска, и не будет никакого способа убить скрипт.

startDetached - статическая функция, которая запускает процесс независимо от вызывающего процесса, поэтому нет возможности его убить, поскольку объект myProcess не сохраняет дескриптор начального процесса. Для вашего приложения лучший способ - запуск вызова.

Один из способов сделать это было бы, как этот

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; 

После запуска, по истечении которого цикл в течение 4 секунд, прежде чем убить процесс. Функция processEvents сохраняет GUI в ожидании.

После вызова kill необходимо вызвать waitForFinished, чтобы дождаться завершения процесса, иначе вы получите сообщение об ошибке, которое вы видели, когда объект QProcess был уничтожен до того, как процесс фактически завершился.

Проблема с вышеуказанным подходом заключается в том, что графический интерфейс продолжает функционировать, а в функции on_pushButton_clicked(). Поэтому, если вы вызвали функцию «выхода» из графического интерфейса, в то время как в цикле приложение завершило работу с еще запущенным скриптом. Таким образом, этот подход в порядке, если все, что вы хотите сделать в графическом интерфейсе, - это обновление индикатора выполнения или другого виджета. В этом случае вы можете передать QEventLoop :: ExcludeUserInputEvents для обработкиEvents.

Если пользователь может делать другие вещи в графическом интерфейсе, я бы сделал QProcess членом класса и создаю отдельный слот, чтобы убить скрипт. Затем вы можете использовать QTimer для вызова этого слота через определенный промежуток времени.

+0

благодарит за ответ. К сожалению, добавьте свой код, который не исправил мою проблему. Сценарий python все еще не запускается. Интересно, что я заменил «python.exe» на «блокнот».exe ', и блокнот запускается с моим скриптом в нем и закрывается через четыре секунды. Кажется, что есть проблема с python.exe. – hokiebird

+0

Что вы ожидаете, когда запускается скрипт python? Python - это консольное приложение, поэтому я ожидаю, что он будет работать в фоновом режиме без видимого вывода. Вы проверили диспетчер задач, работает ли python.exe? –