如何使用cx_Freeze冻结双模式(GUI和控制台)应用程序?
我开发了一个Python应用程序,它可以在图形界面模式和控制台模式下运行。如果指定了任何参数,它就会在控制台模式下运行,否则就会在图形界面模式下运行。
我用cx_Freeze把这个程序打包成可执行文件。之前我遇到了一些问题,就是用wxPython时,黑色的控制台窗口会弹出来,所以我修改了我的setup.py
脚本,像这样:
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup(
name = "simple_PyQt4",
version = "0.1",
description = "Sample cx_Freeze PyQt4 script",
executables = [Executable("PyQt4app.py", base = base)])
这样做是有效的,但现在当我尝试在控制台中打开并运行这个可执行文件时,它没有任何输出。我没有收到任何错误或消息,所以看起来cx_Freeze把输出重定向到别的地方了。
有没有办法让它在两种模式下都能正常工作?类似的情况在任何地方都没有文档说明。 :(
提前感谢。
Mridang
2 个回答
2
Raymond Chen 在这方面写过一些内容。简单来说,在Windows系统下直接实现这个功能是不可能的,但有一些变通的方法。
我建议你可以提供两个可执行文件,一个是命令行界面(CLI),另一个是图形用户界面(GUI)。
14
我在这个页面上发现了一些内容:
对于没有控制台的版本,有个小提示:如果你尝试打印任何东西,你会看到一个很糟糕的错误窗口,因为标准输出和错误输出都不存在(而且cx_freeze的Win32gui.exe会显示一个错误窗口)。这在你想让程序同时支持图形界面模式和命令行模式时会很麻烦。为了安全地禁用控制台输出,可以在程序开始时这样做:
try:
sys.stdout.write("\n")
sys.stdout.flush()
except IOError:
class dummyStream:
''' dummyStream behaves like a stream but does nothing. '''
def __init__(self): pass
def write(self,data): pass
def read(self,data): pass
def flush(self): pass
def close(self): pass
# and now redirect all default streams to this dummyStream:
sys.stdout = dummyStream()
sys.stderr = dummyStream()
sys.stdin = dummyStream()
sys.__stdout__ = dummyStream()
sys.__stderr__ = dummyStream()
sys.__stdin__ = dummyStream()
这样,如果程序以没有控制台的模式启动,即使代码里有打印语句,它也能正常工作。而如果在命令行模式下运行,它会像往常一样打印输出。(这基本上也是我在webGobbler中做的。)