V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
youthfire
V2EX  ›  Python

在 Mac 上运行 Python tkinter 的图形界面时,有什么办法可以隐藏或最小化同步运行的 terminal 窗口?

  •  
  •   youthfire · 2021-01-24 17:20:58 +08:00 · 2447 次点击
    这是一个创建于 1180 天前的主题,其中的信息可能已经有所发展或是发生改变。

    只想通过 tkinter 上的按钮执行设计好的命令,不想出现黑色的终端窗口,求教

    第 1 条附言  ·  2021-01-25 12:02:58 +08:00
    找到方法,并且试验成功
    参考来源:
    https://stackoverflow.com/questions/36864537/how-to-run-a-python-3-tkinter-app-without-opening-any-terminal-windows-in-mac-os

    利用 Mac 自带的脚本编辑器(Script Editor)
    新建脚本后输入如下:(替换掉自己的 py 文件路径即可)
    do shell script "export LC_ALL=en_US.UTF-8; export LANG=en_US.UTF-8; /usr/local/bin/python3 '/Users/USER/FOLDER/SCRIPT.py' &> /dev/null &"

    脚本编辑器编辑后,另存为程序,且注意存放路径(默认存储在脚本文件夹下,可以指定桌面等其他位置)

    之前遇到过其中一段代码不执行,检查后发现,applescript 对路径的要求比 terminal(console)更高,找不到就直接不执行了,我的一个 sqlite lite 就是没指定路径(平时默认在 user 下,terminal 会直接找到,但这里脚本却不行)
    参考来源:
    https://developer.apple.com/library/archive/technotes/tn2065/_index.html#//apple_ref/doc/uid/DTS10003093-CH1-TNTAG1-MY_COMMAND_WORKS_FINE_IN_TERMINAL__BUT_WHEN_I_TRY_TO_USE_IT_IN_DO_SHELL_SCRIPT__I_GET_AN_ERROR_ABOUT____COMMAND_NOT_FOUND______WHAT___S_GOING_ON_

    这样可以成功输出独立 app,且完全没有终端窗口影响.希望对遇到一样问题的朋友有帮助.
    23 条回复    2021-01-25 12:16:24 +08:00
    LeeReamond
        1
    LeeReamond  
       2021-01-24 17:40:12 +08:00 via Android
    pyinstaller 打包,选择隐藏命令行模式
    ClericPy
        2
    ClericPy  
       2021-01-24 17:50:30 +08:00
    windows 上使用 pyw 扩展名或者说使用 pythonw 来执行脚本, 不知道 mac 上有没有
    youthfire
        3
    youthfire  
    OP
       2021-01-24 18:53:38 +08:00 via iPhone
    @ClericPy #2 谢谢回复,特意去看了 mac 主程序目录里似乎没有 pythonw,目前我是直接改后缀为 command,支持双击运行但存在 terminal 同步运行
    youthfire
        4
    youthfire  
    OP
       2021-01-24 18:54:30 +08:00 via iPhone
    @LeeReamond #1 感谢提供思路,回头我看看,但这样体积要剧增了吧
    LeeReamond
        5
    LeeReamond  
       2021-01-24 19:12:37 +08:00
    @youthfire 不光体积剧增,还慢。但是总之我不知道除了打包以外还有隐藏 cli 的方法。可以尝试其他打包方式
    youthfire
        6
    youthfire  
    OP
       2021-01-24 19:21:55 +08:00
    @LeeReamond 试过了,确实顺利完成了打包,且运行时没有终端窗口了.但 tkinter 的窗口是顺利加载了,但点击按钮后程序却没有正常运行.用的命令就是 pyinstaller --noconsole xxx.py,选用的是 dist 文件夹下的同名程序
    BingoXuan
        7
    BingoXuan  
       2021-01-24 19:30:24 +08:00 via Android
    py2app 试一下?
    yucongo
        8
    yucongo  
       2021-01-24 22:58:30 +08:00 via Android
    win.withdraw() 或许是你想要的
    no1xsyzy
        9
    no1xsyzy  
       2021-01-24 23:10:44 +08:00
    1. nohup
    2. 不清楚 fork & exit 行不行。在 if __name__=='__main__': 的逻辑下面 if os.fork() != 0: sys.exit() 咯
    ysc3839
        10
    ysc3839  
       2021-01-25 01:04:17 +08:00   ❤️ 1
    @ClericPy @youthfire
    macOS 自带的 Python2 是有 pythonw 的。
    不过改文件名为 .pyw 并不能解决问题,因为这里的问题是 .pyw 没有关联任何打开方式,同时会出现终端窗口也是因为 .command 的打开方式是终端。

    正确解决方法是让 Finder 直接把脚本作为可执行文件执行。但是即使把文件的扩展名去掉再加上执行权限,双击还是会打开终端。最终方案只有打包成 app 。

    假设脚本文件名为 pygui.py ,在终端执行以下命令即可:
    chmod +x ./pygui.py
    mkdir -p pygui.app/Contents/MacOS
    mv ./pygui.py pygui.app/Contents/MacOS/pygui

    @no1xsyzy
    fork 的方法不可行,macOS 下 fork 后不 exec 的话不能使用 CoreFoundation 。加了 fork 后会提示:
    The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
    Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
    youthfire
        11
    youthfire  
    OP
       2021-01-25 01:51:09 +08:00
    @ysc3839 感谢回复,试过了.打包完运行,显示“You can’t open the application “pygui” because this application is not supported on this Mac.” - 不清楚原因,目前用的是 Big Sur 11.1
    youthfire
        12
    youthfire  
    OP
       2021-01-25 01:52:08 +08:00
    @yucongo 这个不是,这个隐藏了 tkinter 的 root(window),我是需要隐藏 terminal
    ysc3839
        13
    ysc3839  
       2021-01-25 01:58:18 +08:00
    @youthfire 确定脚本开头加了 #!/usr/bin/env python3 吗?
    youthfire
        14
    youthfire  
    OP
       2021-01-25 02:10:00 +08:00
    @ysc3839 原来确实没加.现在加上不报这个错误了,直接双击运行,app 毫无反应
    youthfire
        15
    youthfire  
    OP
       2021-01-25 02:17:06 +08:00
    @BingoXuan 谢谢推荐,也试过了.pyinstaller 的能加载出 gui,但不能执行命令.这个打包后 gui 都加载不出
    ysc3839
        16
    ysc3839  
       2021-01-25 02:23:05 +08:00
    @youthfire 那用终端 cd 进去然后执行 ./pygui 呢?
    youthfire
        17
    youthfire  
    OP
       2021-01-25 02:52:10 +08:00
    @ysc3839 zsh: no such file or directory: ./pygui
    ysc3839
        18
    ysc3839  
       2021-01-25 04:58:05 +08:00 via Android
    @youthfire 是 cd 到 pygui.app /Contents/MacOS 下面。
    no1xsyzy
        19
    no1xsyzy  
       2021-01-25 11:01:28 +08:00
    那 exec 一下?
    os.execvp("python3", sys.argv)
    (不对,那样就死循环了)

    不是很依赖封包的话可以用 nohup 启动的。
    no1xsyzy
        20
    no1xsyzy  
       2021-01-25 11:13:43 +08:00   ❤️ 1
    1.
    #!/usr/bin/nohup python3
    (用 nohup 替换 env )
    (估计是会闪烁一下黑窗口)
    不过不能给 python3 添加更多参数了

    2.
    还有就是 https://stackoverflow.com/a/1810580/6202760
    实质 fork && exit || exec

    3.
    看到说 macos 上需要用 spawn
    那就用 magic number (通过 argv 或者 环境变量传递)如果没有 magic number 就添加 magic number 并 spawn & exit
    youthfire
        21
    youthfire  
    OP
       2021-01-25 12:00:03 +08:00
    找到方法,并且试验成功
    参考来源:
    https://stackoverflow.com/questions/36864537/how-to-run-a-python-3-tkinter-app-without-opening-any-terminal-windows-in-mac-os

    利用 Mac 自带的脚本编辑器(Script Editor)
    新建脚本后输入如下:(替换掉自己的 py 文件路径即可)
    do shell script "export LC_ALL=en_US.UTF-8; export LANG=en_US.UTF-8; /usr/local/bin/python3 '/Users/USER/FOLDER/SCRIPT.py' &> /dev/null &"

    之前遇到过其中一段代码不执行,检查后发现,applescript 对路径的要求比 terminal(console)更高,找不到就直接不执行了,我的一个 sqlite lite 就是没指定路径(平时默认在 user 下,terminal 会直接找到,但这里脚本却不行)
    参考来源:
    https://developer.apple.com/library/archive/technotes/tn2065/_index.html#//apple_ref/doc/uid/DTS10003093-CH1-TNTAG1-MY_COMMAND_WORKS_FINE_IN_TERMINAL__BUT_WHEN_I_TRY_TO_USE_IT_IN_DO_SHELL_SCRIPT__I_GET_AN_ERROR_ABOUT____COMMAND_NOT_FOUND______WHAT___S_GOING_ON_

    这样可以成功输出独立 app,且完全没有终端窗口影响.希望对遇到一样问题的朋友有帮助.
    youthfire
        22
    youthfire  
    OP
       2021-01-25 12:01:46 +08:00
    补充一句,脚本编辑器编辑后,另存为程序,且注意存放路径(默认存储在脚本文件夹下,可以指定桌面等其他位置)
    youthfire
        23
    youthfire  
    OP
       2021-01-25 12:16:24 +08:00
    @no1xsyzy 感谢建议,试了 1,结果是程序没有跑起来(包括 tkinter 的 gui 也没有加载),改回 env 就正常了.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1046 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 22:39 · PVG 06:39 · LAX 15:39 · JFK 18:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.