Recently, I made a pygame game. I want to show it to my friends. But unfortunately, I cant make an executable file, only a .py file. I have tried to use tools such as py2exe which might not support Python 3.6 and pyinstaller. I think pyinstaller may be useful, and I can also make an exe successfully but it didn't work at all. It just showed it couldn't open the sound file which is already in the same file.
I have tried two ways to load files firstly, just load the path then the exe converted shows it can't open the file which is already in the same path with the exe.
Secondly, I use the os.path which the exe showed it cant open ...../temp/... which is a long path but my computer doesn't have this folder at all.
I am a new guy to learn python. I have searched for a day and can't make it work. Can you help me?
I'm just a scripting hack, and an idiot when it comes to command line tools. But I REALLY wanted to package up my python game into a Windows executable. I wrestled with pyinstaller for days, and read all of the threads of others who are also trying to figure it out, and I also read all the pyinstaller docs several times. No one solution worked for me, but after much trial and error I finally stumbled onto a recipe for success and want to share it in case there are other pygame developers out there banging their heads against this. The solution contains bits and pieces of several threads.
How to create a single file exe of a multi-file python pygame with several asset directories using pyinstaller on Windows:
First, install pyinstaller.
Open Windows Command Prompt, type:
pip install pyinstaller
Make a python game. Say the main game file is called main_game_script.py, located in
C:\Users\USERNAME\Documents\python\game_dir
Add this function to main_game_script.py. Make sure to import os and sys. (I never would have figured out on my own that I needed to add this function to my game, but it works, so thanks to whoever posted it in some other thread)
import sys
import os
def resource_path(relative_path):
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
To load images into game, call that function, like such:
asset_url = resource_path('assets/chars/hero.png')
hero_asset = pygame.image.load(asset_url)
When your game is ready to be wrapped in an EXE, open Windows Command Prompt. Go to the main game directory and type:
pyinstaller --onefile main_game_script.py --collect-data assets/chars --collect-data assets/tiles --collect-data assets/fonts
It'll look like this:
C:\Users\USERNAME\Documents\python\game_dir>pyinstaller --onefile main_game_script.py --collect-data assets/chars --collect-data assets/tiles --collect-data assets/fonts
This will create four important items:
- a main_game_script.spec file in the game_dir
- a 'build' dir in the game_dir
- a 'dist' directory in the game_dir
- a main_game_script.exe will be created in the 'dist' directory.
Running the command spits out a ton of warnings and logs. I don't know what it all means. But as long as the final output line says success, you're probably good.
If your exe is still not working: First, you must modify the .spec file (which now exists in the game_dir) to add the needed game asset paths to the exe:
Open the main_game_script.spec file in notepad or whatever.
Replace the empty datas[] list with asset directory paths like such (using tuples!):
datas=[('assets/chars/*','assets/chars'),('assets/tiles/*.png','assets/tiles'),('assets/fonts/*','assets/fonts')],
The first value of each tuple is the actual file names you want to import.
The second value is the relative path from you main_game_script.py
The syntax and paths must be perfect, or it won't work and may not throw an error
Save and close the 'main_game_script.spec' file. Return to your windows command prompt. Type:
pyinstaller main_game_script.spec
Like this:
C:\Users\USERNAME\Documents\python\game_dir>pyinstaller main_game_script.spec
This somehow embeds the asset dir paths into the exe that you've already built
After all this (which only takes a couple minutes after you've done it 100 times), you finally have a single file EXE of your python game that includes all of the game assets. If you've done everything right, double click on the EXE to play your python game.
Note: getting it right the first time took me a couple days. I started with a simple test_game_script.py with minimal code and iterated methodically, adding more asset paths and complexity with each iteration so I could isolate what was broken and why. If your game isn't converting to EXE properly, start with a simple 5 line game script with one asset and slowly build on it until you have a pipeline that works, THEN apply that functioning asset pipeline your ACTUAL game. Otherwise isolating the problem will be impossible.
1. Add --hidden-import pygame.
Something like:
python -m PyInstaller <options> xxx.py --hidden-import pygame
2. Hack the pygame stdout.
If you used the option -w, it will fail because of the (annoying) version output of pygame.
Workaround:
import contextlib
with contextlib.redirect_stdout(None):
import pygame
I too had the same problem and spent days looking through google. Today finally I realised what was the problem.
Before trying to convert it, remember to install Pygame via the Terminal as well. Just type in "pip install pygame"
This can be done with cx_freeze
pip install cx_freeze
You will need to create a setup.py file to help cx_freeze build the executable
import cx_Freeze
# base = "Win32GUI" allows your application to open without a console window
executables = [cx_Freeze.Executable('my_example_app.py', base = "Win32GUI")]
cx_Freeze.setup(
name = "My Example Exe App",
options = {"build_exe" :
{"packages" : ["pygame"], "include_files" : ['example_folder_with_files/', 'ExampleFont.ttf', 'example_text_file.txt']}},
executables = executables
)
Be sure to add your packages, fonts, or files to the script and any additional files that your app needs to the setup.
Finally you need to run your setup.py script
python setup.py build
or if you want cx_freeze to create an installer for you
python setup.py bdist_msi
Sentdex has a nice walkthrough on his website
pythonprogramming.net
#Blue Botic answer above works like a charm! Thank you!
I added the "--noconsole" parameter in the below command to get rid of the console and only show the game's main window:
pyinstaller --onefile --noconsole main_game_script.py
With PyInstaller it's possible without editing the .spech file, using the argument --collect-data NAME_ASSET_FOLDER
pyinstaller main_game_script.py --onefile --windowed --collect-data assets/chars --collect-data assets/tiles --collect-data assets/fonts
Related
I am working on a small gui using Tkinter when I set the path to the icon in the script it works fine but when I run it as a exe file it says it cant be found and the path it displays is AppData\Local\Temp. What am I doing wrong?
root.iconbitmap(os.path.dirname(os.path.realpath(__file__))+"\\Icon.ico")
for pyinstaller I am using this line:
pyinstaller "Filename" --onefile
I have ran into this problem before. Don't use os.path.dirname(os.path.realpath(__file__)) to get the path the file is currently running in, but rather use sys.argv[0].
See this answer for further explanation.
py file in which I am executing a .exe file created in C++ (is inside a "data" folder)
Python Code:
os.system("data\\time.exe")
When I use the pyinstaller with the --onefile attribute I can't find a way for my program to compile the .py file + the "data" with another .exe inside.
Does anyone know how to convert my entire program into a single .exe? in which I can run my python program and also my .exe from C++ inside?
(I have tried to test with the .spec and with the --add-data attribute but I can't find a way that is compatible with what I want to do)
I look forward to your response,
Thanks you very much <3
There is a program called auto-py-to-exe which creates an exe out of your program without requiring you to create a setup file. The interface is great and allows you to easily create and exe without creating a setup.py. This also allows you to package your app as a single exe, without any other files. Below is a screenshot:
You can install the program by typing into the command line:
python -m pip install auto-py-to-exe
You can run it by typing in:
auto-py-to-exe
To see more about auto-py-to-exe, please visit the PyPI page at https://pypi.org/project/auto-py-to-exe/.
I'm trying to run pyinstaller in python exe file in order to someone without python can use pyinstaller but no idea how to do it.
I tried import PyInstaller with other needed modules and convert this script to exe but I got error "The 'PyInstaller' distribution was not found and is required by the application". I also tried to pack PyInstaller exe file but didn't worked too. Python 3.6.5
Any ideas how to do it?
Unfortunately, what you're describing is not possible with PyInstaller. I submitted an issue on GitHub, and this is what one of the developers said:
Nope, this won't work.
PyInstaller internally uses a lot of sub-processes where it is assumed that sys.executable points to a python interpreter (e.g., here); this is not true in a frozen application, where it points to the frozen executable, which ends up in effectively endless recursion.
Even if this was not a problem, the frozen application includes only a subset of python environment, so it cannot be used to freeze an arbitrary script (not to mention the issue of 3rd party packages).
So whatever use case you have for this, it cannot be supported by PyInstaller.
check the requirements for the Pyinstaller from this link initially
https://pythonhosted.org/PyInstaller/requirements.html
Then install Pyinstaller by,
pip install pyinstaller
To create .exe file use this command for basically,
pyinstaller your_script.py
To run the created .exe
METHOD 1
Do double click the .exe file in your directory.
METHOD 2
In your cmd prompt load in to your current directory or project directory then do
: .\dist\your_script.exe
because the create .exe files are saved in dist folder inside to the project folder with the name of your script file names only.
I am having a tough time overcoming this error, I have searched everywhere for that error message and nothing seems relevant to my situation:
"failed to execute script new-app"
new-app is my python GUI program. When I run pyinstaller using this command:
pyinstaller.exe --onedir --hidden-import FileDialog --windowed --noupx new-app.py
It does work smoothly. In addition, when I execute the command line to run the gui program, it works perfectly and the GUI is generated using this command:
.\dist\new-app\new-app.exe
But when I go to that file hopefully to be able to click the app to get the GUI, it gives me the error said above. Why is that?
I am using python2.7 and the OS is Windows 7 Enterprise.
Any inputs will be appreciated and thanks a lot in advance.
Well I guess I have found the solution for my own question, here is how I did it:
Eventhough I was being able to successfully run the program using normal python command as well as successfully run pyinstaller and be able to execute the app "new_app.exe" using the command line mentioned in the question which in both cases display the GUI with no problem at all. However, only when I click the application it won't allow to display the GUI and no error is generated.
So, What I did is I added an extra parameter --debug in the pyinstaller command and removing the --windowed parameter so that I can see what is actually happening when the app is clicked and I found out there was an error which made a lot of sense when I trace it, it basically complained that "some_image.jpg" no such file or directory.
The reason why it complains and didn't complain when I ran the script from the first place or even using the command line "./" is because the file image existed in the same path as the script located but when pyinstaller created "dist" directory which has the app product it makes a perfect sense that the image file is not there and so I basically moved it to that dist directory where the clickable app is there!
So The Simple answer is to place all the media files or folders which were used by code in the directory where exe file is there.
Second method is to add "--add-data <path to file/folder>"(this can be used multiple times to add different files) option in pyinstaller command this will automatically put the given file or folder into the exe folder.
In my case i have a main.py that have dependencies with other files. After I build that app with py installer using this command:
pyinstaller --onefile --windowed main.py
I got the main.exe inside dist folder. I double clicked on this file, and I raised the error mentioned above.
To fix this, I just copy the main.exe from dist directory to previous directory, which is the root directory of my main.py and the dependency files, and I got no error after run the main.exe.
Add this function at the beginning of your script :
import sys, os
def resource_path(relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
Refer to your data files by calling the function resource_path(), like this:
resource_path('myimage.gif')
Then use this command:
pyinstaller --onefile --windowed --add-data todo.ico;. script.py
For more information visit this documentation page.
In case anyone doesn't get results from the other answers, I fixed a similar problem by:
adding --hidden-import flags as needed for any missing modules
cleaning up the associated folders and spec files:
rmdir /s /q dist
rmdir /s /q build
del /s /q my_service.spec
Running the commands for installation as Administrator
I was getting this error for a different reason than those listed here, and could not find the solution easily, so I figured I would post here.
Hopefully this is helpful to someone.
My issue was with referencing files in the program. It was not able to find the file listed, because when I was coding it I had the file I wanted to reference in the top level directory and just called
"my_file.png"
when I was calling the files.
pyinstaller did not like this, because even when I was running it from the same folder, it was expecting a full path:
"C:\Files\my_file.png"
Once I changed all of my paths, to the full version of their path, it fixed this issue.
I got the same error and figured out that i wrote my script using Anaconda but pyinstaller tries to pack script on pure python. So, modules not exist in pythons library folder cause this problem.
That error is due to missing of modules in pyinstaller. You can find the missing modules by running script in executable command line, i.e., by removing '-w' from the command. Once you created the command line executable file then in command line it will show the missing modules. By finding those missing modules you can add this to your command :
" --hidden-import = missingmodule "
I solved my problem through this.
I had a similar problem, this was due to the fact that I am using anaconda and not installing the dependencies in pip but in anaconda. What helped me was to install the dependencies in pip.
I found a similar issue but none of the answers up above helped. I found a solution to my problem activating the base environment. Trying once more what I was doing without base I got my GUI.exe executed.
As stated by #Shyrtle, given that once solved my initial problem I wanted to add a background image, I had to pass the entire path of the image even if the file.py and the image itself were in the same directory.
In my case (level noob) I forgot to install library "matplotlib". Program worked in Pycharm, but not when I tried open from terminal. After installed library in Main directory all was ok.
Recently, I made a pygame game. I want to show it to my friends. But unfortunately, I cant make an executable file, only a .py file. I have tried to use tools such as py2exe which might not support Python 3.6 and pyinstaller. I think pyinstaller may be useful, and I can also make an exe successfully but it didn't work at all. It just showed it couldn't open the sound file which is already in the same file.
I have tried two ways to load files firstly, just load the path then the exe converted shows it can't open the file which is already in the same path with the exe.
Secondly, I use the os.path which the exe showed it cant open ...../temp/... which is a long path but my computer doesn't have this folder at all.
I am a new guy to learn python. I have searched for a day and can't make it work. Can you help me?
I'm just a scripting hack, and an idiot when it comes to command line tools. But I REALLY wanted to package up my python game into a Windows executable. I wrestled with pyinstaller for days, and read all of the threads of others who are also trying to figure it out, and I also read all the pyinstaller docs several times. No one solution worked for me, but after much trial and error I finally stumbled onto a recipe for success and want to share it in case there are other pygame developers out there banging their heads against this. The solution contains bits and pieces of several threads.
How to create a single file exe of a multi-file python pygame with several asset directories using pyinstaller on Windows:
First, install pyinstaller.
Open Windows Command Prompt, type:
pip install pyinstaller
Make a python game. Say the main game file is called main_game_script.py, located in
C:\Users\USERNAME\Documents\python\game_dir
Add this function to main_game_script.py. Make sure to import os and sys. (I never would have figured out on my own that I needed to add this function to my game, but it works, so thanks to whoever posted it in some other thread)
import sys
import os
def resource_path(relative_path):
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
To load images into game, call that function, like such:
asset_url = resource_path('assets/chars/hero.png')
hero_asset = pygame.image.load(asset_url)
When your game is ready to be wrapped in an EXE, open Windows Command Prompt. Go to the main game directory and type:
pyinstaller --onefile main_game_script.py --collect-data assets/chars --collect-data assets/tiles --collect-data assets/fonts
It'll look like this:
C:\Users\USERNAME\Documents\python\game_dir>pyinstaller --onefile main_game_script.py --collect-data assets/chars --collect-data assets/tiles --collect-data assets/fonts
This will create four important items:
- a main_game_script.spec file in the game_dir
- a 'build' dir in the game_dir
- a 'dist' directory in the game_dir
- a main_game_script.exe will be created in the 'dist' directory.
Running the command spits out a ton of warnings and logs. I don't know what it all means. But as long as the final output line says success, you're probably good.
If your exe is still not working: First, you must modify the .spec file (which now exists in the game_dir) to add the needed game asset paths to the exe:
Open the main_game_script.spec file in notepad or whatever.
Replace the empty datas[] list with asset directory paths like such (using tuples!):
datas=[('assets/chars/*','assets/chars'),('assets/tiles/*.png','assets/tiles'),('assets/fonts/*','assets/fonts')],
The first value of each tuple is the actual file names you want to import.
The second value is the relative path from you main_game_script.py
The syntax and paths must be perfect, or it won't work and may not throw an error
Save and close the 'main_game_script.spec' file. Return to your windows command prompt. Type:
pyinstaller main_game_script.spec
Like this:
C:\Users\USERNAME\Documents\python\game_dir>pyinstaller main_game_script.spec
This somehow embeds the asset dir paths into the exe that you've already built
After all this (which only takes a couple minutes after you've done it 100 times), you finally have a single file EXE of your python game that includes all of the game assets. If you've done everything right, double click on the EXE to play your python game.
Note: getting it right the first time took me a couple days. I started with a simple test_game_script.py with minimal code and iterated methodically, adding more asset paths and complexity with each iteration so I could isolate what was broken and why. If your game isn't converting to EXE properly, start with a simple 5 line game script with one asset and slowly build on it until you have a pipeline that works, THEN apply that functioning asset pipeline your ACTUAL game. Otherwise isolating the problem will be impossible.
1. Add --hidden-import pygame.
Something like:
python -m PyInstaller <options> xxx.py --hidden-import pygame
2. Hack the pygame stdout.
If you used the option -w, it will fail because of the (annoying) version output of pygame.
Workaround:
import contextlib
with contextlib.redirect_stdout(None):
import pygame
I too had the same problem and spent days looking through google. Today finally I realised what was the problem.
Before trying to convert it, remember to install Pygame via the Terminal as well. Just type in "pip install pygame"
This can be done with cx_freeze
pip install cx_freeze
You will need to create a setup.py file to help cx_freeze build the executable
import cx_Freeze
# base = "Win32GUI" allows your application to open without a console window
executables = [cx_Freeze.Executable('my_example_app.py', base = "Win32GUI")]
cx_Freeze.setup(
name = "My Example Exe App",
options = {"build_exe" :
{"packages" : ["pygame"], "include_files" : ['example_folder_with_files/', 'ExampleFont.ttf', 'example_text_file.txt']}},
executables = executables
)
Be sure to add your packages, fonts, or files to the script and any additional files that your app needs to the setup.
Finally you need to run your setup.py script
python setup.py build
or if you want cx_freeze to create an installer for you
python setup.py bdist_msi
Sentdex has a nice walkthrough on his website
pythonprogramming.net
#Blue Botic answer above works like a charm! Thank you!
I added the "--noconsole" parameter in the below command to get rid of the console and only show the game's main window:
pyinstaller --onefile --noconsole main_game_script.py
With PyInstaller it's possible without editing the .spech file, using the argument --collect-data NAME_ASSET_FOLDER
pyinstaller main_game_script.py --onefile --windowed --collect-data assets/chars --collect-data assets/tiles --collect-data assets/fonts