Python 脚本不能完全从 Qt 运行
Posted
技术标签:
【中文标题】Python 脚本不能完全从 Qt 运行【英文标题】:Python script doesn't fully run from Qt 【发布时间】:2018-05-12 20:42:39 【问题描述】:我想从 Qt 运行一个 python 脚本。我可以用QProcess
调用它并让qDebug()
打印python 脚本打印的内容。但由于某种原因,在代码中的某个点之后,我无法 Qt 读取任何 python 脚本的打印。
有人知道如何解决这个问题吗?非常感谢你。这是我在这里的第一个问题,如果我做错了什么,我很抱歉。
我的 widget.cpp 文件和 python 脚本如下。 (python 脚本在 Qt 程序的目录中。)
我的 widget.cpp 文件:
#include "widget.h"
#include "ui_widget.h"
#include "QDebug"
#include <QTimer>
#include <QProcess>
#include <QDir>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
ui->setupUi(this);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(checkTexts()));
timer->start(5000);
Widget::~Widget()
delete ui;
void Widget::checkTexts()
//QProcess process; //I also tried this way with the same results
QProcess *process = new QProcess(this);
QStringList arguments QCoreApplication::applicationDirPath() + "/../../../../../Folder/Qt Desktop Application/ApplicationFiles/PullText.py";
process->start("python", arguments);
process->waitForFinished(-1);
QString output = process->readAll();
process->close();
qDebug() << output;
我的 Python 脚本 (PullText.py) 应该向我的 Qt 应用程序发送一行文本文件:
newMessageSplitter = "***\n"
#print "1" #this prints in the qDebug() << output
file = open("texts.txt","r")
#print “2” #this doesn't print
texts = file.read()
x = texts.find(newMessageSplitter) + len(newMessageSplitter)
singleLine = texts[:x-len(newMessageSplitter)]
file.close()
file = open("texts.txt","w")
file.write(texts[x:])
file.close()
#print singleLine #this is what I want to send to the output but it doesn't get sent to Qt
【问题讨论】:
如果手动运行python脚本,是否有效?如果在第二次打印之前出错,您将看不到该输出file.close
或 file.close()
?
python 脚本在我单独运行时可以正常运行。抱歉,file.close 是我的问题中的一个错字。
@Johnny 这是唯一的印刷错误?我想这种类型的错误不会再出现了,因为它们会导致无聊,而且我们不愿意帮助您,您可以指出项目路线、构建文件夹和 .py 文件之间的关系
【参考方案1】:
我认为你的问题在这里:
process->waitForFinished(-1);
如果您的子进程产生的输出多于少量输出,则调用waitForFinished()
会出现问题,因为如果您的子进程的stdout
输出缓冲区已满,您就会遇到死锁情况:子进程/Python 进程现在被阻塞等待使缓冲区耗尽,以便它可以向其中写入更多输出;同时,你的 Qt/父进程也被阻塞,等待子进程退出。
由于两个进程都无能为力,因此子进程永远不会退出,因此waitForFinished()
永远不会返回,您的程序将永远卡住。
(另一种可能性是子进程被设置为在其stdout
缓冲区填满时简单地丢弃任何额外的输出文本;在这种情况下,子进程将退出并且waitForFinished()
将返回,但您的process->readAll()
调用将只返回能够放入输出缓冲区的初始输出文本;剩余的文本被丢弃,因此您的 Qt 进程永远无法看到它)
在任何一种情况下,解决方案都不是在waitForFinished()
内部等待,而是直接调用readAll()
来收集其输出而不等待。您可能需要循环调用它,直到子进程退出,可能还需要使用waitForReadyRead()
来避免忙循环。
【讨论】:
我试过这个process->start("python", arguments); while(true) process->waitForFinished(); QString output = process->readAll(); if(output != "") qDebug() << output;
,它只打印一次“1\n”,然后什么也没有。它获得了第一个输出,但似乎一旦file = open("texts.txt","r")
运行,python 脚本就无法将其输出发送到 Qt。当我单独运行 python 脚本时,我得到了所有的打印语句。
尝试将“texts.txt”替换为完整路径名(例如“/Users/Johnny/Documents/texts.txt”或该文件的任何名称),看看是否效果更好。如果是这样,那么问题是您的 Qt 应用程序的当前目录与 texts.txt 所在的目录不同,因此 open() 命令失败。
用完整路径名替换“texts.txt”修复了它!非常感谢。以上是关于Python 脚本不能完全从 Qt 运行的主要内容,如果未能解决你的问题,请参考以下文章
PySide Qt 脚本不能从 Spyder 启动,但可以从 shell 运行
C#代码不能在visual studio中运行完整的python脚本