如何从 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 应用程序,使用所有默认值。添加了一个按钮。我试图模仿我在网上找到的多个帖子,但无法让 python 脚本正确启动。我不断收到此消息:
QProcess: Destroyed while process ("python.exe") is still running.
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()
函数将在启动后退出并且不会有杀死脚本的方法。
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 调用 "exit" 函数,应用程序将退出,脚本仍为 运行。因此,如果您只想在 GUI 中更新进度条或其他显示小部件,则此方法是 OK
。在这种情况下,您可以将 QEventLoop::ExcludeUserInputEvents
传递给 processEvents
.
如果用户可以在 GUI 中做其他事情,那么我会让 QProcess
成为 class 成员并创建一个单独的插槽来终止脚本。然后,您可以使用 QTimer
在指定的时间间隔后调用此插槽。
我在 QT Creator 4.2.0 中创建了一个简单的应用程序,即 QT Widgets 应用程序,使用所有默认值。添加了一个按钮。我试图模仿我在网上找到的多个帖子,但无法让 python 脚本正确启动。我不断收到此消息:
QProcess: Destroyed while process ("python.exe") is still running.
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()
函数将在启动后退出并且不会有杀死脚本的方法。
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 调用 "exit" 函数,应用程序将退出,脚本仍为 运行。因此,如果您只想在 GUI 中更新进度条或其他显示小部件,则此方法是 OK
。在这种情况下,您可以将 QEventLoop::ExcludeUserInputEvents
传递给 processEvents
.
如果用户可以在 GUI 中做其他事情,那么我会让 QProcess
成为 class 成员并创建一个单独的插槽来终止脚本。然后,您可以使用 QTimer
在指定的时间间隔后调用此插槽。