运行 在子进程中无法重定向 Pyinstaller 单个可执行文件输出

Cannot redirect Pyinstaller single executable output while running it in subprocess

我已经为此苦苦挣扎了一段时间。我已经设法编写了一个可以捕获 .py 文件的 STDOUT 的代码,但是当我 运行 与从 Pyinstaller 生成的可执行文件完全相同的代码时(不管它是否有窗口) readyReadStandardOutput信号永远不会出现。

根据我的测试,只有当应用程序崩溃时才会发出任何信号,但是我需要 GUI 和可执行文件之间的实时通信。

这是我的代码供参考:

  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)

以及我将信号连接到的方法:

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

我正在 Windows 机器上工作


编辑:最小可重现示例

来个小脚本

import time

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

让我们暂时离开 PyQT 进程,使用更简单的 Popen。 如果我们 运行 Popen 中的脚本,stdout 将被重定向到调用进程。

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)

但是,如果我们使用第一个脚本并通过 PyInstaller 单个可执行生成器,Popen 将不再捕获任何输出,它只会冻结

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'),
    ])

所以我的问题又是 - 我是否遗漏了一些重要的部分?或者这可能只是 pyinstaller 的错。

好像编译脚本的时候要把print的flush设置为True,改成:

import time

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