【问题标题】:QProcess not executing a python scriptQProcess 不执行 python 脚本
【发布时间】:2013-10-04 15:27:06
【问题描述】:

我正在尝试在 Qt(在 Linux 中)中执行一个执行 python 脚本的进程,但我无法使其工作。这是代码:

QProcess process;
QString scriptFile = "../../scriptPath/script.py";

QString pyCommand = "\"python " + scriptFile + 
                    " -f " + parameter1 +
                    " -t parameter2" +
                    " -v parameter3" +
                    " -e " + parameter4 + "\"";

printf("PyCommand: %s\n", qStringToStdString(pyCommand).c_str());

process.start ("bash", QStringList () << "-c" << pyCommand);

parameter1parameter3 是我从文件对话框中获得的 QStrings(两个路径都正确),parameter2parameter4 是硬编码字符串(以防万一,这些字符串有字符“-”和“ 。“ 在他们中)。函数qStringToStdString 是我创建的一个函数,用于将QString 转换为std::string,它工作得很好(我已经使用过)。

PyCommand 打印在控制台中,看起来不错。事实上,如果我打开一个终端并尝试执行bash -c,然后执行我在 printf 指令中得到的内容,它就可以工作。但是当我执行 Qt 应用程序时它不起作用。

有人可以帮我吗?我错过了什么?

【问题讨论】:

    标签: python c++ qt qtcore qprocess


    【解决方案1】:

    您的代码忽略了 API 的设计方式。您应该使用下面介绍的任一替代方案。显式使用python 解释器取决于您是否在python 脚本中正确使用了shebang。我只是让它作为参考,但你可以很容易地摆脱它。这不是您的问题的重点。

    第一种选择(基于QStringList

    QProcess process;
    QString scriptFile =  QCoreApplication::applicationDirPath() + "../../scriptPath/script.py";
    
    QStringList pythonCommandArguments = QStringList() << scriptFile
        << "-f " << parameter1 << "-t" <<  parameter2 << "-v"
        <<  parameter3 << "-e" << parameter4;
    
    printf("PyCommand: %s\n", qStringToStdString(pythonCommandArguments.join(' ')).c_str());
    
    process.start ("python", pythonCommandArguments);
    

    第二种选择(基于QString

    QProcess process;
    QString scriptFile =  QCoreApplication::applicationDirPath() + "../../scriptPath/script.py";
    
    QString pythonCommand = "python " + scriptFile + 
                        " -f " + parameter1 +
                        " -t parameter2" +
                        " -v parameter3" +
                        " -e " + parameter4;
    
    printf("PyCommand: %s\n", qStringToStdString(pythonCommand).c_str());
    
    process.start (pythonCommand);
    

    在这里您可以找到两种方式的正确方法签名:

    • void QProcess::start(const QString &amp; program, const QStringList &amp; arguments, OpenMode mode = ReadWrite)

    http://doc.qt.io/qt-5/qprocess.html#start

    • void QProcess::start(const QString &amp; command, OpenMode mode = ReadWrite)

    http://doc.qt.io/qt-5/qprocess.html#start-3

    【讨论】:

      【解决方案2】:

      命令行参数需要使用QStringList()

      您的pyCommand 必须是QStringList

      类似这样的:

      QStringList pyCommand;
      pyCommand << "-f" << parameter1 <<
                      "-t" << parameter2 <<
                      "-v" << parameter3 <<
                      "-e" << parameter4;
      
      process.start(scriptFile, pyCommand);
      

      查看文档:http://doc.qt.io/qt-5/qprocess.html#start

      【讨论】:

        【解决方案3】:

        所以最后我得到了它的工作。正如 Laszlo 评论的那样,它应该执行的方式是使用python 启动一个进程,并将所有参数作为QStringList 传递。这就是我一开始尝试的方法,它根本不起作用。所以我在互联网上查找信息,我看到很多人正在执行一个bash 进程,然后他们使用 python 命令传递一个字符串,而不是像我一样执行它。我试图这样做,但它也没有工作......

        解决方案?好吧,在我在这里提问之前我已经做了我应该做的事情。我将过程中最重要的信号(开始、完成和错误)与一些编写输出的简单方法联系起来。最后我发现python返回2(没有这样的文件或目录)作为exitCode

        似乎应用程序没有将可执行路径作为根路径,因此我所指的路径 ("../../scriptPath/script.py") 不存在。为了获得正确的二进制路径,我现在使用QDir::currentPath() + "/scriptPath/script.py"

        【讨论】:

        • 呃,不,使用 QCoreApplication::applicationDirPath() 而不是 QDir::currentPath() 正如我在帖子中提到的那样。我建议重新审视我的答案。这可能不是接受的最佳答案,但我会把它留给你。