从Python setuptools创建可启动的GUI脚本(无控制台窗口!) [英] Create launchable GUI script from Python setuptools (without console window!)

查看:194
本文介绍了从Python setuptools创建可启动的GUI脚本(无控制台窗口!)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前为基于Python的GUI添加可执行文件的方式是:

The way I currently add an executable for my Python-based GUI is this:

setup(
      # ...
      entry_points = {"gui_scripts" : ['frontend = myfrontendmodule.launcher:main']},
      # ...
      )

在Windows上,这将在Python的scripts文件夹(使用Python 2.6)中创建 frontend.exe和 frontend-script.pyw。当我执行EXE文件时,会显示一个控制台窗口,但PYW文件可以正常工作而不显示一个。

On Windows, this will create "frontend.exe" and "frontend-script.pyw" in Python's scripts folder (using Python 2.6). When I execute the EXE file, a console window is shown but the PYW file works correctly without showing one.

所以我的问题是:如何使EXE文件执行没有控制台窗口的程序?该解决方案也应在Linux上运行(不要建议py2exe;)。

So my question is: How can I make the EXE file execute the program without the console window? The solution should work on Linux, too (don't suggest py2exe ;).

推荐答案

好的,我在setuptools源代码,都归结为setuptools(easy_install.py)中的错误:

Alright, I investigated a bit in the setuptools source code and it all boils down to a bug in setuptools (easy_install.py):

# On Windows/wininst, add a .py extension and an .exe launcher
if group=='gui_scripts':
    ext, launcher = '-script.pyw', 'gui.exe'
    old = ['.pyw']
    new_header = re.sub('(?i)python.exe','pythonw.exe',header)
else:
    ext, launcher = '-script.py', 'cli.exe'
    old = ['.py','.pyc','.pyo']
    new_header = re.sub('(?i)pythonw.exe','python.exe',header)

if os.path.exists(new_header[2:-1]) or sys.platform!='win32':
    hdr = new_header
else:
    hdr = header

最后一个 if 语句决定是否将pythonw.exe或python.exe的路径写入 frontend-script.pyw的shebang中。由于此shebang由创建的EXE文件评估,因此有必要不执行 else 语句。问题是在我的情况下, new_header [2:-1] 是 C:\Program Files(x86)\Python26\pythonw.exe。 (带引号!),因此 os.path.exists 表示由于引号不存在。

The last if statement decides whether pythonw.exe's or python.exe's path is written into the shebang of "frontend-script.pyw". As this shebang is evaluated by the created EXE file, it is necessary that the else statement is not executed. The problem is that new_header[2:-1] in my case was "C:\Program Files (x86)\Python26\pythonw.exe" (with the quotes!), so os.path.exists said it does not exist because of the quotes.

我会尝试使setuptools开发人员更正此问题。剩下的问题将是pythonw.exe的绝对路径。如果我创建Windows安装程序/ MSI安装程序,则该工具栏将包含我的pythonw.exe路径( C:\Program Files(x86)\Python26\pythonw.exe),但用户可能已在 ; C: Python26。在报告了此问题后,我将报告最终的解决方案。

I will try to get this corrected by the setuptools developers. The remaining problem will be the absolute pythonw.exe path. If I create a Windows setup/MSI installer, the shebang will contain my pythonw.exe path ("C:\Program Files (x86)\Python26\pythonw.exe") but the user might have installed Python in "C:\Python26". I'll report the final solution after I've reported this problem.

我在两年前发布了此报告,对不起,我还没有提供我的解决方案。不确定是否还有其他更现代的解决方案(可能分发提供东西),但是这是我当时使用的东西(复制粘贴):

I posted this over two years back, sorry that I didn't yet offer my solution. Not sure if there is any more modern solution (probably distribute offers something), but here's what I used back then (copy-pasted):

#!pythonw.exe

# This script will be executed by the primary Python version that is installed, which might as well be Python 3. But
# we want to execute it with the Python version that belongs to this script's path. So let's do a major hack:

import os
import sys
import subprocess

if sys.argv[-1] == "magic":
    from dogsync_frontend.launcher import main
    main()
else:
    # The CPython folder hierarchy is assumed here (<installation>\pythonw.exe, <installation>\Scripts\<thisscript>)
    subprocess.Popen([os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "pythonw.exe")),
                      __file__,
                      "magic"])


文件 dogsync-frontend.exe


自动从< python安装> \lib\site-包\setuptools\gui.exe (请参见下文)。如果我没有记错的话,此文件将自动执行脚本< EXE名称> -script.py [w]

File dogsync-frontend.exe

Automatically copied from <python installation>\lib\site-packages\setuptools\gui.exe (see below). This file will automatically execute the script <name of EXE>-script.py[w] if I remember correctly.

from setuptools import __file__ as setupToolsFilename

if os.name == "nt":
    # Use a customized (major hack) start script instead of the one that gets automatically created by setuptools
    # when the "gui_scripts" parameter is used. This way, we don't need setuptools installed in order to run DogSync.
    shutil.copy2(os.path.join(os.path.dirname(setupToolsFilename), "gui.exe"),
                 "build-environment/windows-scripts/dogsync-frontend.exe")
    startScripts = dict(scripts = ["build-environment/windows-scripts/dogsync-frontend-script.pyw",
                                   "build-environment/windows-scripts/dogsync-frontend.exe"])
else:
    # For Linux, I don't have a solution to remove the runtime dependency on setuptools (yet)
    startScripts = dict(entry_points = {"gui_scripts" : ['dogsync-frontend = dogsync_frontend.launcher:main']})

setup(<other options>,
      **startScripts)

使用此设置,将exe / pyw文件复制到< python安装> \脚本(在Windows)并启动 dogsync-frontend.exe 将在没有控制台的情况下运行pyw脚本。由于setuptools多年来没有任何更新,因此该解决方案仍然有效。

With this setup, the exe/pyw files are copied to <python installation>\Scripts (on Windows) and starting dogsync-frontend.exe will run the pyw script without a console. Since setuptools did not get any updates for years, this solution is still working.

这篇关于从Python setuptools创建可启动的GUI脚本(无控制台窗口!)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆