Cannot redirect Pyinstaller single executable output while running it in subprocess

笑着哭i 提交于 2021-02-05 11:21:06

问题


I've been struggling with this for quite a while. I've managed to write a code that can capture STDOUT of .py files, however when I run the exact same code with executable generated from Pyinstaller (doesn't matter whether it's windowed or not) the readyReadStandardOutput signal doesn't ever come up.

From my tests it occurs that any signal at all is emitted only when the app crashes, however I need a live communication between the GUI and the executable.

Here's my code for reference:

  def start_process(self, program, args=None):
        if args is None:
            args = []

        process = QtCore.QProcess(self)
        process.readyReadStandardOutput.connect(partial(self.onReadyReadStandardOutput, self.number_process_running))

        process.start(program)

and the method that I've connected the signal to:

    def onReadyReadStandardOutput(self, i):
        print("called")
        process = self.sender()
        self.results[i] = process.readAllStandardOutput()
        self.resultsChanged.emit(self.results)

I'm working on a Windows machine


EDIT: Minimal reproducible example

Let's take a small script

import time

if __name__ == "__main__":
    num = 0
    while True:
        num = num + 1
        print(num)
        time.sleep(3)

Let's leave the PyQT processes for now and use simpler Popen. If we run the script in Popen, the stdout will be redirected to the calling process.

if __name__ == '__main__':
    p = Popen([r'python', 'test.py'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
    while p.poll() is None:
        out = p.stdout.readline()
        print(out)

However, if we take the first script and put through PyInstaller single executable generator, the Popen won't capture any output no more, it will just freeze

import os
import sys

import PyInstaller.__main__

file_location = os.path.dirname(os.path.realpath(__file__))

if sys.platform == "win32":
    PyInstaller.__main__.run([
        '--name=%s' % 'test',
        '--onefile',
        '--noconsole',
        '--distpath=%s' % os.path.join(file_location, 'dist'),
        '--workpath=%s' % os.path.join(file_location, 'build'),
        '--specpath=%s' % os.path.join(file_location),
        os.path.join(file_location, 'test.py'),
    ])

So again my question is - am I missing some important part in there? Or maybe it's just pyinstaller's fault.


回答1:


It seems that when you compile the script you should set the flush of the print to True, so just change it to:

import time

if __name__ == "__main__":
    num = 0
    while True:
        num = num + 1
        print(num, flush=True)
        time.sleep(3)


来源:https://stackoverflow.com/questions/62693079/cannot-redirect-pyinstaller-single-executable-output-while-running-it-in-subproc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!