我应该如何在不丑陋的情况下在 Windows 上启动便携式 Python Tkinter 应用程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4652356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:57:16  来源:igfitidea点击:

How should I launch a Portable Python Tkinter application on Windows without ugliness?

pythonwindowstkinterrelative-pathportable-executable

提问by Andrew

I've written a simple GUI program in python using Tkinter. Let's call this program 'gui.py'. My users run 'gui.py' on Windows machines from a USB key using Portable Python; installing anything on the host machine is undesirable.

我使用 Tkinter 在 python 中编写了一个简单的 GUI 程序。我们称这个程序为“gui.py”。我的用户使用便携式 Python从 USB 密钥在 Windows 机器上运行“gui.py” ;在主机上安装任何东西都是不可取的。

I'd like my users to run 'gui.py' by double-clicking an icon at the root of the USB key. My users don't care what python is, and they don't want to use a command prompt if they don't have to. I don't want them to have to care what drive letter the USB key is assigned. I'd like this to work on XP, Vista, and 7.

我希望我的用户通过双击 USB 密钥根目录下的图标来运行“gui.py”。我的用户不关心 python 是什么,如果他们不需要,他们不想使用命令提示符。我不想让他们关心分配给 USB 密钥的驱动器号。我希望它适用于 XP、Vista 和 7。

My first ugly solution was to create a shortcut in the root directory of the USB key, and set the "Target" property of the shortcut to something like "(root)\App\pythonw.exe (root)\App\gui.py", but I couldn't figure out how to do a relative path in a windows shortcut, and using an absolute path like "E:" seems fragile.

我的第一个丑陋的解决方案是在 U 盘的根目录中创建一个快捷方式,并将快捷方式的“目标”属性设置为类似“(root)\App\pythonw.exe (root)\App\gui.py ”,但我不知道如何在 Windows 快捷方式中创建相对路径,并且使用像“E:”这样的绝对路径似乎很脆弱。

My next solution was to create a .bat script in the root directory of the USB key, something like this:

我的下一个解决方案是在 U 盘的根目录中创建一个 .bat 脚本,如下所示:

@echo off
set basepath=%~dp0
"%basepath%App\pythonw.exe" "%basepath%\App\gui.py"

This doesn't seem to care what drive letter the USB key is assigned, but it does leave a DOS window open while my program runs. Functional, but ugly.

这似乎并不关心分配给 USB 密钥的驱动器号,但它确实在我的程序运行时打开了一个 DOS 窗口。实用,但丑陋。

Next I tried a .bat script like this:

接下来我尝试了这样的 .bat 脚本:

@echo off
set basepath=%~dp0
start "" "%basepath%App\pythonw.exe" "%basepath%\App\gui.py"

(See herefor an explanation of the funny quoting)

(有关有趣引用的解释,请参见此处

Now, the DOS window briefly flashes on screen before my GUI opens. Less ugly! Still ugly.

现在,在我的 GUI 打开之前,DOS 窗口会在屏幕上短暂闪烁。少丑!还是丑。

How do real men deal with this problem? What's the least ugly way to start a python Tkinter GUI on a Windows machine from a USB stick?

真正的男人是如何解决这个问题的?从 USB 记忆棒在 Windows 机器上启动 python Tkinter GUI 的最不丑陋的方法是什么?

EDIT: All the answers below were very good (py2exe, pyinstaller, small .exe, .wsf script.) The .wsf solution was the simplest, so I'm using it for now. I'll probably end up switching to one of the other three solutions if I want a prettier icon and the standard .exe extension. Thanks, everyone!

编辑:下面的所有答案都非常好(py2exe、pyinstaller、小 .exe、.wsf 脚本。).wsf 解决方案是最简单的,所以我现在正在使用它。如果我想要一个更漂亮的图标和标准的 .exe 扩展名,我可能最终会切换到其他三个解决方案之一。谢谢大家!

采纳答案by cgohlke

This Windows Scripting Host script (file extension .wsf) can be used instead of the batch file:

可以使用此 Windows 脚本宿主脚本(文件扩展名 .wsf)代替批处理文件:

<job>
<script language="VBScript">
set WshShell = WScript.CreateObject("WScript.Shell")
CMDFile = "App\pythonw.exe App\gui.py"
WshShell.Run CMDFile, 1
</script>
</job> 

Update: Alternatively compile this C program and link an icon resource:

更新:或者编译这个 C 程序并链接一个图标资源:

#include <windows.h>
#include <process.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                   LPSTR lpCmdLine, int nCmdShow)
{
    return _spawnl(_P_NOWAIT, "App/pythonw.exe", " App/gui.py", lpCmdLine, NULL);
}

Update 2: To build an App.exe with icon, save the C code to app.c, create an Windows icon file app.ico, and save the following line to app.rc:

更新 2:要构建带有图标的 App.exe,请将 C 代码保存到 app.c,创建 Windows 图标文件 app.ico,并将以下行保存到 app.rc:

appicon ICON "app.ico"

Using Visual Studio 2008 Express, run these commands:

使用 Visual Studio 2008 Express,运行以下命令:

"C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
rc.exe app.rc
cl.exe app.c /FeApp.exe /link app.res

Alternatively use "Visual Studio 2010 Express" or "Microsoft Windows SDK v7.0 for Windows 7 and .NET Framework 3.5 Service Pack 1" and adjust the commands accordingly.

或者,使用“Visual Studio 2010 Express”或“Microsoft Windows SDK v7.0 for Windows 7 and .NET Framework 3.5 Service Pack 1”并相应地调整命令。

Note that the icon will only be used for the App.exe starter program, not your Python program.

请注意,该图标将仅用于 App.exe 启动程序,而不是您的 Python 程序。

回答by ChristopheD

Use pyinstallerto zip up your distribution (the advantage over py2exe is that it knowsdifferent third-party libraries and is generally more up-to-date).

使用pyinstaller压缩您的发行版(与 py2exe 相比的优势在于它knows与第三方库不同并且通常是最新的)。

You can then create a .exe for your users to click upon to start your application. If you just copy the results of the pyinstaller build onto your USB drive you should be fine.

然后,您可以为您的用户创建一个 .exe,点击即可启动您的应用程序。如果您只是将 pyinstaller 构建的结果复制到您的 USB 驱动器上,您应该没问题。

回答by Anders

Make it to a single executable using py2exe.

使用py2exe使其成为单个可执行文件。

回答by orlp

You could do this in a hacky manner by writing you're own little C application that calls system('start "" "%basepath%App\pythonw.exe" "%basepath%\App\gui.py"'). Next you compile it without console and use it as a "shortcut".

您可以通过编写自己的小 C 应用程序来调用system('start "" "%basepath%App\pythonw.exe" "%basepath%\App\gui.py"'). 接下来,在没有控制台的情况下编译它并将其用作“快捷方式”。

回答by Karim Bahgat

The Short Answer:

简短的回答:

This question was asked a few years ago, but I recently found a solution for a program I was working on that may still be useful for others. With this method, you will be able to create a standalone exe program launcher that can be placed anywhere and refer to a file in its same folder or subdirectory, while having a pretty icon of your choice and no DOS screen popping up. In other words, a true good-looking relative-path transportable shortcut file :)

这个问题是几年前提出的,但我最近为我正在开发的一个程序找到了一个解决方案,它可能对其他人仍然有用。使用此方法,您将能够创建一个独立的 exe 程序启动器,该启动器可以放置在任何位置并引用同一文件夹或子目录中的文件,同时拥有您选择的漂亮图标并且不会弹出 DOS 屏幕。换句话说,一个真正好看的相对路径可传输快捷方式文件:)

The solution should be easy to follow and do even for non-programmers and goes as follows:

该解决方案应该易于遵循,即使对于非程序员也是如此,如下所示:

  1. open notepad
  2. write: %windir%\system32\cmd.exe /c start "" "%CD%\optional subfolder\mainpy2exeGUI.exe"
  3. save as "whatever.bat"
  4. convert the bat-file to an exe file using a program called "BAT to EXE converter" while checking the "invisible application" option, and selection the icon file you want under the "versioninformations" tab. You can name the output exe file to whatever you want. Link to the converter program can be found at http://www.freewaregenius.com/how-to-create-shortcuts-with-a-relative-path-for-use-on-usb-drives/The converter program download contains a 32 and 64-bit version, use the 32-bit version to make the shortcut usable by both older and newer PCs.
  1. 打开记事本
  2. 写入:%windir%\system32\cmd.exe /c start "" "%CD%\optional subfolder\mainpy2exeGUI.exe"
  3. 另存为“whatever.bat”
  4. 使用名为“BAT 到 EXE 转换器”的程序将 bat 文件转换为 exe 文件,同时选中“隐形应用程序”选项,然后在“版本信息”选项卡下选择所需的图标文件。您可以将输出的 exe 文件命名为您想要的任何名称。转换器程序的链接可以在http://www.freewaregenius.com/how-to-create-shortcuts-with-a-relative-path-for-use-on-usb-drives/找到 转换器程序下载包含32 位和 64 位版本,使用 32 位版本使快捷方式可用于较旧和较新的 PC。

(note, this solutions is almost the same as suggested at http://www.freewaregenius.com/how-to-create-shortcuts-with-a-relative-path-for-use-on-usb-drives/. However the current solution is different in terms of the code it uses in step2 which allows the launcher progam to be placed anywhere on a computer and not just on the top directory of a USB-stick, and is new to emphasize that the invisible option should be checked. Those differences are crucial.)

(请注意,此解决方案与http://www.freewaregenius.com/how-to-create-shortcuts-with-a-relative-path-for-use-on-usb-drives/ 中建议的几乎相同。但是当前的解决方案在它在 step2 中使用的代码方面有所不同,它允许将启动程序放置在计算机上的任何位置,而不仅仅是放在 U 盘的顶级目录中,并且是新的,以强调不可见选项应该是检查。这些差异至关重要。)

More Details (optional):

更多详情(可选):

The original question was: "What's the least ugly way to start a python Tkinter GUI on a Windows machine from a USB stick?"

最初的问题是:“从 USB 记忆棒在 Windows 机器上启动 python Tkinter GUI 的最不丑陋的方法是什么?”

What was needed can be broken down to four things: 1. An exe program launcher. 2. That works on any computer and in any directory (i.e. it supports relative paths). 3. That has an icon. 4. That does not open an "ugly" DOS window.

需要的东西可以分为四件事: 1. 一个 exe 程序启动器。2. 它适用于任何计算机和任何目录(即它支持相对路径)。3. 那有一个图标。4. 这不会打开一个“丑陋”的 DOS 窗口。

There were several possible solutions suggested but none so far that satisfies all criteria. The original poster went for the ".wsf" option which allowed for relative paths and no ugly DOS window, but did not allow a custom icon or the recognizable exe file.

提出了几种可能的解决方案,但目前没有一个能满足所有标准。原始海报选择了“.wsf”选项,该选项允许使用相对路径且没有丑陋的 DOS 窗口,但不允许自定义图标或可识别的 exe 文件。

Part of the problem with the previously suggested solutions include:

先前建议的解决方案的部分问题包括:

  1. you do not have C/VB programming skills or software.
  2. you want an icon to your launcher program. Using a shortcut file that executes "cmd" and uses it to open your GUI file will allow you to set an icon file, BUT the icon file reference is absolute and will fail on any other computer than the one you created the shortcut file on.
  3. you do not want the "ugly" DOS window flash. The cmd shortcut solution mentioned in the previous point creates a DOS window that flashes before opening your GUI.
  4. Making the py2exe main executable file as the program launcher would almost be a perfect solution because it satisfies all criteria, but a backdraw with it is that the py2exe ececutable would require an ugly "tlc" folder to be placed in the same top-directory. It is therefore better to hide the main py2exe launcher in a nicely named subfolder. Also, there are many cases where one would like to keep the program launcher and the program itself as separate exe files, for instance if you are only using your main py2exe program to function as a python-runner that can launch open-ended editable python scripts that you can edit on the go without having to create a new py2exe file for each time you make a change to one of your scripts.
  1. 您没有 C/VB 编程技能或软件。
  2. 你想要一个启动程序的图标。使用执行“cmd”并使用它打开您的 GUI 文件的快捷方式文件将允许您设置图标文件,但图标文件引用是绝对的,并且在您创建快捷方式文件的计算机之外的任何其他计算机上都会失败。
  3. 您不希望“丑陋”的 DOS 窗口闪烁。上一点中提到的 cmd 快捷方式解决方案会创建一个 DOS 窗口,该窗口会在打开 GUI 之前闪烁。
  4. 将 py2exe 主要可执行文件作为程序启动器几乎是一个完美的解决方案,因为它满足所有标准,但它的倒退是 py2exe ececutable 需要将一个丑陋的“tlc”文件夹放置在同一个顶级目录中。因此,最好将主 py2exe 启动器隐藏在一个命名良好的子文件夹中。此外,在很多情况下,人们希望将程序启动器和程序本身保留为单独的 exe 文件,例如,如果您仅使用主 py2exe 程序作为可以启动开放式可编辑 python 的 python-runner您可以在旅途中编辑的脚本,而无需每次更改脚本时都创建新的 py2exe 文件。

回答by Perica Zivkovic

You can also fork Portable Python sources on GitHuband create shortcut in the same way other Portable Python shortcuts are created.

您还可以在 GitHub 上fork可移植 Python 源代码并以创建其他可移植 Python 快捷方式的相同方式创建快捷方式。

This gives you nice way to start app, icon, you can set custom registry/env variables if you need to, etc etc.

这为您提供了启动应用程序、图标的好方法,如果需要,您可以设置自定义注册表/环境变量等。

As an example you can take e.g. IDLE shortcut from Portable Pythonsources.

例如,您可以从便携式 Python源中获取例如 IDLE 快捷方式。

回答by SzieberthAdam

I've made a batch script (PyRunEXE) which compiles a simple Assembly Language code to make an EXE launcher for you:

我制作了一个批处理脚本 (PyRunEXE),它编译一个简单的汇编语言代码来为你制作一个 EXE 启动器:

https://github.com/SzieberthAdam/pyrunexe

https://github.com/SzieberthAdam/pyrunexe