首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >QProcess.readAllStandardOutput()似乎没有读取任何内容- PyQt

QProcess.readAllStandardOutput()似乎没有读取任何内容- PyQt
EN

Stack Overflow用户
提问于 2012-08-30 01:45:50
回答 1查看 2.9K关注 0票数 0

以下是代码示例:

代码语言:javascript
运行
复制
class RunGui (QtGui.QMainWindow)

    def __init__(self, parent=None):

        ...
        QtCore.Qobject.connect(self.ui.actionNew, QtCore.SIGNAL("triggered()"), self.new_select)
        ...


    def normal_output_written(self, qprocess):
        self.ui.text_edit.append("caught outputReady signal") #works
        self.ui.text_edit.append(str(qprocess.readAllStandardOutput())) # doesn't work


    def new_select(self):
        ...
        dialog_np = NewProjectDialog()
        dialog_np.exec_()
        if dialog_np.is_OK:
            section = dialog_np.get_section()
            project = dialog_np.get_project()
            ...
            np = NewProject()
            np.outputReady.connect(lambda: self.normal_output_written(np.qprocess))
            np.errorReady.connect(lambda: self.error_output_written(np.qprocess))
            np.inputNeeded.connect(lambda: self.input_from_line_edit(np.qprocess))
            np.params = partial(np.create_new_project, section, project, otherargs)
            np.start()

class NewProject(QtCore.QThread):

    outputReady = QtCore.pyqtSignal(object)
    errorReady = QtCore.pyqtSignal(object)
    inputNeeded = QtCore.pyqtSignal(object)
    params = None
    message = ""

    def __init__(self):
        super(NewProject, self).__init__()
        self.qprocess = QtCore.QProcess()
        self.qprocess.moveToThread(self)
        self._inputQueue = Queue()

    def run(self):
        self.params()

    def create_new_project(self, section, project, otherargs):
        ...
        # PyDev for some reason skips the breakpoints inside the thread
        self.qprocess.start(command)
        self.qprocess.waitForReadyRead()
        self.outputReady.emit(self.qprocess) # works - I'm getting signal in RunGui.normal_output_written()
        print(str(self.qprocess.readAllStandardOutput())) # prints empty line
        .... # other actions inside the method requiring "command" to finish properly.

这个想法彻底失败了--让GUI运行脚本并与进程通信。这个特定示例中的挑战是,在QProcess as命令中启动的脚本运行一个应用程序,在此过程中需要用户输入(确认)。因此,我必须能够启动脚本,获得所有输出并解析它,等待问题出现在输出中,然后传回答案,让它完成,然后才能在create_new_project()中继续执行其他操作。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-31 04:47:33

我不知道这是否能解决你的整体问题,但我在这里看到了一些设计问题。

  1. 您正在线程之间传递qprocess,而不是仅使用qprocess
  2. 的结果发出自定义信号您正在使用的类级属性可能是instance attributes

从技术上讲,你甚至不需要QProcess,因为你在你的线程中运行它,并积极地使用阻塞调用。无论如何,它很容易成为一个subprocess.Popen...but,我可能会建议这样的更改:

代码语言:javascript
运行
复制
class RunGui (QtGui.QMainWindow)
    
    ...

    def normal_output_written(self, msg):
        self.ui.text_edit.append(msg) 

    def new_select(self):
        ...
            np = NewProject()
            np.outputReady.connect(self.normal_output_written)
            np.params = partial(np.create_new_project, section, project, otherargs)
            np.start()

class NewProject(QtCore.QThread):

    outputReady = QtCore.pyqtSignal(object)
    errorReady = QtCore.pyqtSignal(object)
    inputNeeded = QtCore.pyqtSignal(object)

    def __init__(self):
        super(NewProject, self).__init__()

        self._inputQueue = Queue()
        self.params = None

    def run(self):
        self.params()

    def create_new_project(self, section, project, otherargs):
        ...
        qprocess = QtCore.QProcess()
        qprocess.start(command)
        if not qprocess.waitForStarted():
            # handle a failed command here
            return

        if not qprocess.waitForReadyRead():
            # handle a timeout or error here
            return

        msg = str(self.qprocess.readAllStandardOutput())
        self.outputReady.emit(msg) 

不要传递QProcess。只需发送数据即可。并从线程方法中创建它,以便它自动归该线程所有。您的外部类实际上不应该对该QProcess对象有任何了解。它甚至不需要是成员属性,因为它只在操作过程中需要。

还要确保正确检查命令是否已成功启动,以及是否正在运行和输出数据。

更新

为了澄清您可能遇到的一些问题(根据评论),我想建议,如果您需要对需要定期用户输入的进程进行交互控制,则QProcess可能不是最佳选择。它应该为运行脚本找到工作,这些脚本从头到尾只产生输出,尽管实际上使用子进程会容易得多。对于需要用户长期输入的脚本,最好的选择可能是使用pexpect。它允许您生成一个进程,然后观察各种模式,您知道这些模式将指示需要输入:

foo.py

代码语言:javascript
运行
复制
import time

i = raw_input("Please enter something: ")
print "Output:", i
time.sleep(.1)
print "Another line"
time.sleep(.1)
print "Done"

test.py

代码语言:javascript
运行
复制
import pexpect
import time

child = pexpect.spawn("python foo.py")
child.setecho(False)

ret = -1
while ret < 0:
    time.sleep(.05)
    ret = child.expect("Please enter something: ")

child.sendline('FOO')
while True:
    line = child.readline()
    if not line:
        break
    print line.strip()

# Output: FOO
# Another line
# Done
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12183615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档