如何使用cx_Freeze冻结双模式(GUI和控制台)应用程序?

7 投票
2 回答
4194 浏览
提问于 2025-04-15 22:59

我开发了一个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中做的。)

撰写回答