如何从QT Creator 4.2.0中创建的QT GUI应用程序启动和终止python脚本

问题描述 投票:0回答:1

我在QT Creator 4.2.0中创建了一个简单的应用程序,即QT Widgets Application,它使用了所有默认值。添加了一个按钮。我试图模仿我在网络上发现的多个帖子,但无法正确启动python脚本。我一直收到这条消息:

QProcess:进程(“python.exe”)仍在运行时被销毁。

Python.exe被添加到Path变量中。

我想要发生的是,当按下按钮时,启动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);

}

python脚本如下,python 2.7 ...

#!/usr/bin/env python

import time

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

编辑:我坚持下去,通过用这两行替换我的QT代码的最后5行我可以启动我的python脚本,

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

我试图使用myProcess.terminate(),但无法让脚本退出。

python qt qprocess
1个回答
1
投票

当您在QProcess上调用start时,它会运行脚本,但不会等待它完成,因此您的on_pushButton_clicked()函数将在启动后退出,并且将无法终止该脚本。

startDetached是一个静态函数,它独立于调用进程运行进程,因此没有办法杀死它,因为myProcess对象没有保持启动进程的句柄。对于您的应用程序,调用start是更好的方法。

一种方法是这样的:

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对象被销毁了。

上述方法的问题在于GUI继续运行,而在on_pushButton_clicked()函数中。因此,如果您在循环中从GUI调用“退出”功能,则应用程序将在脚本仍在运行时退出。所以这种方法是OK,如果你想在GUI中做的就是更新进度条或其他显示小部件。在这种情况下,你可以将QEventLoop::ExcludeUserInputEvents传递给processEvents

如果用户可以在GUI中执行其他操作,那么我会将QProcess作为类成员并创建一个单独的插槽来杀死脚本。然后,您可以使用QTimer在指定的时间间隔后调用此插槽。

© www.soinside.com 2019 - 2024. All rights reserved.