问题
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