[英]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.