5

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.

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.

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.

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

@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.

Next I tried a .bat script like this:

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

(See here for an explanation of the funny quoting)

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

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?

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!

Community
  • 1
  • 1
Andrew
  • 2,842
  • 5
  • 31
  • 49

7 Answers7

4

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

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.

ChristopheD
  • 112,638
  • 29
  • 165
  • 179
  • I can just speak for myself here, but I have never had any issues with py2exe, pyinstaller on the other hand, never got it to work. And besides, up-to-date, does it even support Python 2.6 yet? – Anders Jan 10 '11 at 22:53
  • @Anders: I've used it with Python 2.6 (and Python 2.7) so I don't know where you read that (about not supporting 2.6)? It may be a matter of personal preference maybe, and this is anecdotal evidence but I've personally had a larger share of problems with py2exe (especially when needing to ship multiple third-party libraries)... Pyinstaller's 64 bit support was also a plus last time I checked. – ChristopheD Jan 10 '11 at 23:00
  • Ah yes, there is support now. And also, py2exe works with 64bit. – Anders Jan 10 '11 at 23:05
  • Well pyinstaller is cross-platform (that's a feature py2exe does not have) ;-) I wouldn't call py2exe up-to-date with its latest release dating from 2008-11. Rumour has it that it's development is discontinued (or at least very slow paced). – ChristopheD Jan 10 '11 at 23:10
  • Thank you for the helpful suggestion. I will try pyinstaller, and report back. – Andrew Jan 10 '11 at 23:11
  • Yeah, these guys put a lot of work into quality, so they rarely make stable releases (as you can see), however, you can just check out the latest development out of subversion, it's excellent stuff. http://sourceforge.net/projects/py2exe/develop and by judging from the log, it does seem to be progressing quite fine. – Anders Jan 10 '11 at 23:14
  • @Anders: Then the rumours were false ;-). If they'll release another version I might give it another try. Found pyinstaller a lot easier to ship PyQt apps with, though. – ChristopheD Jan 10 '11 at 23:17
4

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

<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:

#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:

appicon ICON "app.ico"

Using Visual Studio 2008 Express, run these commands:

"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.

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

cgohlke
  • 9,142
  • 2
  • 33
  • 36
  • Wow, I'd never heard of that. Thanks! Works on XP, testing 7 now. – Andrew Jan 14 '11 at 21:27
  • Works on 7. Very simple. I guess the only real drawback is the unusual extension and the icon. – Andrew Jan 14 '11 at 21:33
  • 1
    Didn't know about the icon requirement. Otherwise would have suggested to compile a exe program (as in answer by nightcracker). – cgohlke Jan 14 '11 at 22:40
  • Good addition, and +1 for including code. What compiler should I use in Windows? How does one link an icon resource? Sorry to ask such basic questions, but I've only used C from Linux. – Andrew Jan 15 '11 at 19:37
3

Make it to a single executable using py2exe.

Anders
  • 6,188
  • 4
  • 26
  • 31
2

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 :)

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.

(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.)

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?"

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.

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.

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.
Karim Bahgat
  • 2,781
  • 3
  • 21
  • 27
2

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".

orlp
  • 112,504
  • 36
  • 218
  • 315
1

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

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 Python sources.

Perica Zivkovic
  • 2,610
  • 24
  • 32
0

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

https://github.com/SzieberthAdam/pyrunexe

SzieberthAdam
  • 3,999
  • 2
  • 23
  • 31