QProcess 执行 python3 脚本无法正常工作

Posted

技术标签:

【中文标题】QProcess 执行 python3 脚本无法正常工作【英文标题】:QProcess executing python3 script not working properly 【发布时间】:2018-04-20 08:09:53 【问题描述】:

我在从 QProcess 执行 python3 脚本时遇到了这个问题。 python 脚本从一秒到一秒地打印时间,从命令行运行良好。在 Qt 中,信号 readyReadStandardOutput() 连接到调用 readAllStandardOutput() 以从脚本读取标准输出的插槽。 问题是槽只被调用一次!它打印一次时间,然后不再打印。 QProcess 的状态保持在“运行” 状态。永远不会调用 readyReadStandardError() 和 error(QProcess::ProcessError) 信号。

为什么必须每秒调用一次插槽?谢谢

Python 脚本:

import time, threading
def foo():
    print(time.ctime())
    threading.Timer(1, foo).start()

foo()

Qt:

MClass::MClass(QObject* parent)

    m_process = new QProcess(this);
    connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(onTest()));
    connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(onTestErr()));
    connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(onTestErr()));
    connect(m_process, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(onTestState()));

    startProcess();


void MClass::startProcess()

        QString script= "../../python/test.py";

        QString pythonCommand = "python3 " + script;

        printf("PyCommand: %s\n", pythonCommand.toStdString().c_str());
        m_process->start(pythonCommand);

//        m_process->start("python3", QStringList()<<script);
    


void MClass::onTest()

    qDebug()<<"------------------ON TEST";
    while(m_process->canReadLine())
    
        qDebug()<<m_process->readAllStandardOutput();
    


void MClass::onTestErr()

    qDebug()<<"------------------ON ERR: " << m_process->errorString();


void MClass::onTestState()

    qDebug()<<"------------------ STATE CHANGED: " << m_process->state();

【问题讨论】:

我们可以看看你的python脚本吗?它是一个交互式脚本,即您是否从标准输入中读取?它可以解释为什么进程保持运行。 @jbh python脚本在qt代码上方 @S.Monteleone 它没有任何区别 在我看来,这种行为的原因是只有第一个打印在主线程中执行,其他线程在其他线程中执行。 【参考方案1】:

我认为问题在于标准输出的 python 处理。我试过这个脚本:

def foo():
    #print(time.ctime())
    sys.stdout.write(time.ctime()) 
    sys.stdout.write("\n")
    sys.stdout.flush()
    threading.Timer(1, foo).start()

我将 print 替换为 sys.stdout.write 并且它起作用了。我认为真正不同的是对flush 的调用。

换句话说,您的脚本将永远运行,因此标准输出永远不会被刷新。如果您尝试其他脚本,该脚本在五次迭代后结束:

def bar():    
    x = 0      
    while x < 5:
        print(time.ctime())
        time.sleep(1)
        x = x + 1

在 Qt 应用程序中,您将在 5 秒后看到整个输出。

【讨论】:

是的,这是一个冲洗问题。您的代码可以正常工作,但也可以在 true 上使用 flash 标志进行打印:print("msg: ", end='\n', file=sys.stdout, flush=True)

以上是关于QProcess 执行 python3 脚本无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

需要 virtenv 时如何运行 QProcess?

QProcess 执行一个 c++ 文件

QProcess 附加到从脚本运行的可执行文件

在 Python 3 和 PyQt 中使用 QProcess.finished()

Qt:QProcess调用终端+脚本

QProcess 无法执行简单的控制台程序