簡體   English   中英

如何從QT Creator 4.2.0中創建的QT GUI應用程序啟動和終止python腳本

[英]How to launch and terminate a python script from a QT GUI app created in QT Creator 4.2.0

我在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() ,但是無法退出腳本。

當您在QProcess上調用start時,它將運行腳本,但不等待其完成,因此問題中的on_pushButton_clicked()函數將在啟動后退出,並且將無法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對象時看到的錯誤。

上述方法的問題在於,GUI在on_pushButton_clicked()函數中繼續運行。 因此,如果您在循環中從GUI調用“退出”功能,則應用程序將退出,並且腳本仍在運行。 因此,如果您要在GUI中做的只是更新進度條或其他顯示小部件,則此方法是OK 在這種情況下,您可以將QEventLoop::ExcludeUserInputEvents傳遞給processEvents

如果用戶可以在GUI中做其他事情,那么我將使QProcess成為類成員,並創建一個單獨的插槽來殺死腳本。 然后,您可以在指定的時間間隔后使用QTimer調用此插槽。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM