在Qt中启动单独的进程

Launch separate process in Qt

本文关键字:进程 单独 启动 Qt      更新时间:2023-10-16

我正在尝试从Qt应用程序运行python文件,但是我有两个问题。一个它似乎没有启动 python 工具。其次,当我尝试仅使用记事本作为示例进行简单测试时,我注意到当我关闭应用程序时记事本会关闭。我不确定为什么python工具没有启动,为什么这个过程没有真正独立于Qt应用程序。

else if(QFileInfo(path).isFile() && path.endsWith(".py", Qt::CaseInsensitive))
{
QProcess::startDetached("C:/python27/python.exe", QStringList() << "C:/Users/john/testing.py");
QProcess *proc = new QProcess();
proc->startDetached("notepad.exe");
}

更新#1:第二次尝试仍然失败.... 我研究了更多,甚至尝试了下面的代码,现在它给了我错误:

导入错误: 没有命名站点的模块

这让我感到困惑,因为我正在设置 env 路径。归根结底,我试图做的只是运行如下所示的shell命令,但从Qt。

"C:/python27/python.exe" "C:/Users/john/testing.py"

最新代码:

QString program( "C:\Python27\python.exe" );
QStringList args = QStringList() << "C:\Users\jmartini\Desktop\Trash\testing.py";
QProcess process;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("PYTHONHOME", "C:\Python27");
env.insert("PYTHONPATH", "C:\Python27\Lib");
process.setProcessEnvironment(env);
process.execute(program, args);

我将回顾各种评论中列出的详细信息,并为您的问题提供最终解决方案。

路径和反斜杠

QProcess API 使用 Win32 平台上的CreateProcess,因此必须根据操作系统约定(使用反斜杠而不是斜杠)提供路径。在您的示例中,"C:/python27/python.exe"必须转换为"C:\Python27\python.exe"。此处的双反斜杠是由于C++字符串文字转义造成的。

环境

正如您在更新中正确指出的那样,您需要设置一些环境变量以使 Python 解释器按预期工作。

您还指定要分离调用的 python 脚本,以便即使应用程序关闭,它也可以运行。

这在Qt <5.10中比较棘手,因为Qt5.10引入了完成此任务的适当API(请参阅Qt博客中的这篇文章)。

在Qt 5.10中,正确的代码是:

QProcess process;
// set the environment variables
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("PYTHONHOME", "C:\Python27");
env.insert("PYTHONPATH", "C:\Python27\Lib");
process.setProcessEnvironment(env);
// set program name and args
process.setProgram("C:\Python27\python.exe");
process.setArguments(args);
// start the detached process
process.startDetached();

您在更新的答案中的代码不起作用,因为它使用的是静态execute() 方法。您会看到,静态方法是类的一部分,这意味着您可以从该类的对象实例调用它,但是,由于它是静态的,因此它无法访问对象的成员。换句话说,execute() 无法知道你之前设置的 QProcessEnvironment 的任何信息。

出于同样的原因,调用接受两个参数的 startDetached() 重载也不起作用,因为它也是静态的。

Qt博客文章确切地解释了为什么创建这种新的非静态重载,这完全适合您的场景。

关闭我的应用程序会杀死 python 解释器。

如果您在调试中运行Qt应用程序,则情况确实如此。这是因为分离的进程(在本例中为 python 解释器)也附加到调试器,并且由于调试会话在关闭 Qt 应用程序时关闭,这也杀死了 python。

但是,如果运行已部署的应用(双击 exe,而不是从调试器),它应该按预期工作。