問題描述
我已經為此苦苦掙扎了一段時間.我已經設法編寫了一個可以捕獲 .py
文件的 STDOUT 的代碼,但是當我使用從 Pyinstaller 生成的可執行文件運行完全相同的代碼時(不管它是否窗口化)readyReadStandardOutput
信號永遠不會出現.
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.
根據我的測試,只有在應用程序崩潰時才會發出任何信號,但是我需要 GUI 和可執行文件之間的實時通信.
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.
這是我的參考代碼:
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)
我正在使用 Windows 機器
I'm working on a Windows machine
最小的可重現示例
我們來寫一個小腳本
import time
if __name__ == "__main__":
num = 0
while True:
num = num + 1
print(num)
time.sleep(3)
讓我們暫時離開 PyQT 進程并使用更簡單的 Popen.如果我們在 Popen 中運行腳本,stdout 將被重定向到調用進程.
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)
但是,如果我們使用第一個腳本并通過 PyInstaller 單個可執行文件生成器,Popen 將不再捕獲任何輸出,它只會凍結
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'),
])
所以我的問題是 - 我錯過了其中的一些重要部分嗎?或者也許這只是 pyinstaller 的錯.
So again my question is - am I missing some important part in there? Or maybe it's just pyinstaller's fault.
推薦答案
看來你在編譯腳本的時候應該把print的flush設置為True,所以改成:
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)
這篇關于在子進程中運行 Pyinstaller 單個可執行輸出時無法重定向它的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!