如何解决使用 PyInstaller noconsole 显示标准输出
如何使用 PyInstaller 创建一个也提供 CLI 而无需弹出 shell 的 GUI 应用程序?
例如,如果我使用 pyinstaller argparse_gui.py --noconsole
创建以下应用程序,shell 中不会显示标准输出:
C:\projects\argparse_gui\dist\argparse_gui>argparse_gui.exe -V
C:\projects\argparse_gui\dist\argparse_gui>
我可以使用 argparse_gui.exe -V > log.txt 2>&1
将 stdout/stderr 重定向到一个文件,但这并不完全是用户友好的。如果在没有 --noconsole
的情况下构建,我可以看到 stdout,但随后会出现一个烦人的单独 shell 窗口。
# argparse_gui.py
import sys
import argparse
from PyQt5 import QtCore,QtWidgets,QtGui
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.init_widgets()
self.init_layout()
def init_widgets(self):
self.label = QtWidgets.QLabel('Hello,world!')
def init_layout(self):
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.label)
centralWidget = QtWidgets.QWidget()
centralWidget.setLayout(layout)
self.setCentralWidget(centralWidget)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("-V","--version",help="display application information",action='store_true')
args = parser.parse_args()
if args.version:
print('Version 123',flush=True)
else:
app = QtWidgets.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
解决方法
编辑:我找到了一种迂回的方法来做到这一点,但控制台窗口会一直出现,直到 GUI 加载完毕。我将以下代码放在主脚本的顶部,并在没有 --windowed 的情况下运行 Pyinstaller。如果脚本不是从现有控制台运行,这将隐藏控制台窗口。
import ctypes
kernel32 = ctypes.WinDLL('kernel32',use_last_error=True)
process_array = (ctypes.c_uint8 * 1)()
num_processes = kernel32.GetConsoleProcessList(process_array,1)
if num_processes < 3: ctypes.WinDLL('user32').ShowWindow(kernel32.GetConsoleWindow(),0)
否则,我将得出结论,没有办法使用 PyInstaller。如果 --noconsole/--windowed,则 EXE 与 pythonw
捆绑在一起。 PythonW 没有附加控制台,即使从控制台启动也是如此。
然而,命令行参数仍然被传递。您仍然可以使用 sys.argv 或 argparser 来访问它们。
在 --noconsole
中运行时,sys.stdout
是一个 NullWriter
对象,而 sys.__stdout__
是 None
。在 1 上使用 open()
会引发异常,CON 和 CONOUT$ 无法执行任何操作。将控制台重定向到 >&1 会引发错误。
注意:在某些条件下,stdin、stdout 和 stderr 以及 stdin、stdout 和 stderr 的原始值可以是 None。它 > 通常是未连接到 Windows GUI 应用程序的情况 控制台和 Python 应用程序以 pythonw 开头。 https://docs.python.org/3/library/sys.html#sys.__stderr__
如果 EXE 是使用 --noconsole 构建的,Pyinstaller 会明确使用 PythonW.exe。我无法找到解决此问题的方法,例如如果从 cli 调用则加载控制台引导加载程序,否则加载 pythonw。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。