python - 在 Qt 中启动单独的进程

标签 python c++ qt

我正在尝试从 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:第二次尝试仍然失败.... 我进行了更多研究,甚至尝试了下面的代码,但它现在给我错误:

ImportError: No module named site

这让我感到困惑,因为我正在设置环境路径。归根结底,我想做的就是运行如下所示的 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 引入了用于完成此任务的适当 API,这对于 Qt < 5.10 来说更棘手(请参阅 Qt 博客中的 this 帖子)。

对于 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();

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

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

Qt 博客文章准确解释了为什么要创建这个新的非静态重载,这非常适合您的场景。

关闭我的应用会终止 python 解释器。

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

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

关于python - 在 Qt 中启动单独的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49902533/

相关文章:

qt - Qt Quick QML 中的位图字体

python - 在twisted.web 中使用适配器比子类化/包装 session 有什么好处?

cout <<自动的C++格式

javascript - 从 JavaScript 调用 Qt 槽

c++ - 我的随机数生成器有什么问题?

c++ - 我如何区分这两个运算符重载?

qt - QQuickItem类的boundingRect从哪里获取它的值?

python - 在 Python 3 中创建 CodeType 时出现 TypeError

python - 如何使用kivy相机与opencv 4.0

python - Django Admin 显示来自 Imagefield 的图像