Pyinstaller exe not working when I change the icon - python

I was making a GUI with python Tkinter. It also uses numpy and matplotlib also. So, I used pyinstaller and make a exe out of the python script. It runs flawlessly and did all what i wanted.
Then I tried to change the tk icon from the gui window (i am using windows 10) with this line
master.iconbitmap(default='image.ico')
other than this line i change nothing of the main program. Then using pyinstaller and I made the exe without any error. But when I tried to run the exe it shows "Fatal Error! file.exe returned -1"
What am i missing? How to fix this problem?
Also I have an additional problem, the 1st exe i build (without changing the icon) is running on Windows-10 and Windows-8 but not in Windows-7. In windows-7 it shows the same error "Fatal Error! file.exe returned -1"

For those still experiencing this issue, I found that pointing the iconbitmap line to the full path will resolve the issue. I was originally having the same problem as the original poster until I entered the full path to my .ico file.
Example:
wm_iconbitmap('E:\icon_name.ico')

try setting datas like:
a.datas += [('C:\\Users\\KoushikNaskar\\Desktop\\Python\\image.ico', 'image.ico')]
from:
http://pythonhosted.org/PyInstaller/spec-files.html#adding-data-files
datas is a list of tuples: (source, dest)

Your problem (most likely) is that you are not bundling the icon's image when using pyinstaller to compile your program to a .exe.
You'll see something like this in your .spec file:
a = Analysis(['your_script.py'],
pathex=['your_path'],
binaries=None,
datas=['file_1_path', ....], # Here
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
Or you could do something like
a.datas += [item1, item2, ...]

Related

Why is Pyinstaller executable returning error '[19544] Failed to execute script due to unhandled exception!'

I have a Plotly dashboard that I am trying to turn into a executable for distribution. Pyinstaller runs without error but when I try and run the exe I get the following errors (in cmd).
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Andres\\OneDrive\\Documents\\Automation\\dashboard_tool_v2.0\\dist\\run_dashboard\\dash\\dcc\\package-info.json'
[19544] Failed to execute script 'run_dashboard' due to unhandled exception!
I use the anaconda environment so I've added the following to the spec file to assure it finds all the correct modules. I have also added numpy to the hiddenimports because in the warn-run file it says it is missing a ton of basic numpy functions. you may also see os because I have a second .py file it needs to run and I thought maybe it wasn't reading the imports on that dependency.
a = Analysis(['run_dashboard.py'],
pathex=[('C:\\Users\\Andres\\OneDrive\\Documents\\Automation\\dashboard_tool_v2.0'),
('C:\\users\\Andres\\anaconda3\\lib\\site-packages')],
binaries=[],
datas=added_data,
hiddenimports=['numpy','os'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
Any idea why it still wont run? it will simply open the python terminal and then close down after a few seconds. Also it might be noteworthy to say I tried to install with --onefile as I have a few .csv files that I want packaged together but then read that this might be an issue so I switched over to --onedir to no avail.

How to package python and kivy application for Raspbian Buster

I am currently writing an application for a raspberry pi 3 using python3.7 and kivy1.11.1. I am trying to package a test application to ensure that it will work. I have created a simple grid with 6 buttons. When you click on a button it prints "button pressed" to the screen. I am using a separate kv file to lay this out as this will be more practical as the application develops. So I have two files, "test.py" and "Test.kv".
I have been using pyinstaller to package my app but it is not working. It runs and creates the executable file just fine with no errors. I then drag my executable file out to my main folder from the "dist" folder as recommended in this video.
My command is:
pyinstaller --onefile --add-data "Test.kv:." test.py
I have also tried:
pyinstaller --onedir --add-data "Test.kv:." test.py
which does the same: blank window no widgets, no errors.
When I try to execute it nothing happens. I don't know what is wrong because I'm not getting any errors when I try to execute it from the terminal. When I do the exact same process on windows it works so its not the code. On occasion, I think it does eventually run but I just get a blank screen and again no error. This would leave me to believe it's an issue with reading the .kv file.
Perhaps this process doesn't work with kivy and I need to use some other method to package my application. However I have also tried this kind of approach but it has left me with errors. I much prefer the pyinstaller method however I don't know if it is going to work as it doesn't seem to pick up the .kv file.
Any help/advice on this issue would be greatly appreciated?
My test.spec file:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['test.py'],
pathex=['/home/pi/Desktop/WinTest'],
binaries=[],
datas=[('Test.kv', '.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='test',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False )
The following picture is my program folder (sorry for the poor quality). My library files are in venv/Lib/site-packages. This is where my kivy/kivy_deps folders are. Could the issue be that the program can't find my library files? But surely if that was the issue it would throw a "file not found" error? And as previously stated, I am not receiving any errors.
Found this in my warn-text.txt file
missing module named kivy.lib.vidcore_lite.egl - imported by kivy.lib.vidcore_lite (top-level), kivy.core.window.window_egl_rpi (top-level)
missing module named kivy.lib.vidcore_lite.bcm - imported by kivy.lib.vidcore_lite (top-level), kivy.core.window.window_egl_rpi (top-level)

How do I resolve a missing utility module preventing my executable from running when I already installed the parent module?

I've written a few Python scripts to create a tkinter GUI for a machine learning algorithm process. I originally coded everything in PyCharm, but I'd really like to put everything together into a stand-alone executable. I've moved my main script and its .py dependencies into their own directory and tested it out using the Command Prompt, and it works great. However, when I run pyinstaller, the executable is created but fails on startup.
The program is made up of three files, with GUI.py being the main script. As mentioned above, I moved the dependent files into a new directory and tested GUI.py in the Command Prompt, and it worked great. Executable is created (albeit with a lot of warnings about missing 'api-ms-win-crt' files) but can't be run.
I created the executable using the command:
pyinstaller --onefile GUI.py
When the executable is run from the command line after creation, I get a big long traceback ending in the following:
File "site-packages\sklearn\metrics\pairwise.py", line 32, in <module>
File "sklearn\metrics\pairwise_fast.pyx", line 1, in init
sklearn.metrics.pairwise_fast
ModuleNotFoundError: No module named 'sklearn.utils._cython_blas'
[3372] Failed to execute script GUI
I know I've already explicitly imported sklearn through the command prompt, but from the traceback, it seems I'm missing a utility module somewhere. I tried to import the missing module specifically, but I got an error that no distributed module was available.
I don't have much experience with pyinstaller, and I have no idea where to go from here. I'm using Windows 10 and Python 3.7.3.
It seems that Pyinstaller can't resolve sklearn import. So one easy way is to just bring the whole module directory which located in <path_to_python>/Lib/site-packages/sklearn/ with executable output. So use below spec file to generate your executable:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['test.py'],
pathex=['<path to root of your project>'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
a.datas += Tree('<path_to_sklearn_in_python_dir>', prefix='sklearn')
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='test',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
runtime_tmpdir=None,
console=True )
Finally generate your executable with
pyinstaller test.spec
This should resolve import errors for sklearn but if you face other NotFound imports add them like above to spec file.
Building up on M.R.'s answer, you can directly include the path to sklearn in your original pyinstaller command:
pyinstaller --onefile GUI.py --add-data "<path-to-python>\Lib\site-packages\sklearn;sklearn"
which results in the following line of code being added inside a = Analysis() in the automatically-generated GUI.spec file:
datas=[('<path-to-python>\\Lib\\site-packages\\sklearn', 'sklearn')]
Note that the --onefile option will result in an executable that is slower to start up than the default one-folder bundle (based on both the pyinstaller documentation and my own experience bundling up sklearn):
pyinstaller GUI.py --add-data "<path-to-python>\Lib\site-packages\sklearn;sklearn"

Python executable created with PyInstaller doesn't run

I have a simple script in order to plot a ROC curve (using sklearn and matplotlib). I used PyInstaller to create an executable from this script. The script itself runs and works perfectly but the executable gives me this error:
No module named 'tkinter'
What I tried:
1) Re-create the executable without the --onefile flag (in case any .dll was missing) (FAILED)
2) Manually import tkinter inside my script (FAILED)
Actually when I added import tkinter the error changed to (in case it matters):
No module named 'tkinter.filedialog'
I am confused. I used PyInstaller many times but it's the first time I encounter this kind of error.
Edit the .spec file and put the path to the module inside 'pathex' (on Analysis). You can discover the correct module path using module.__file__.
In your case:
>>> import tkinter.filedialog
>>> tkinter.filedialog.__file__
'/usr/lib/python3.5/tkinter/filedialog.py'
On .spec file:
a = Analysis(['main.py'],
pathex=['/usr/lib/python3.5/tkinter/'],
binaries=None,
datas=None,
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)

Pygame.image.load() not working with PyInstaller

img_l = pygame.image.load("img.png")
screen.blit(img_l)
With Python Interpreter it works fine, image loads and main.py runs without problems, but when I make it into one file .exe with Pyinstaller, .exe crashes.
I've tried few .spec modifications, but few I've managed to find don't seem to help.
Any ideas sincerely appreciated.
EDIT: got it working with:
img_l = pygame.image.load(os.path.join('img.png'))
screen.blit(img_l, (0, 0))
Now it works as it should after going through PyInstaller :)
For anyone else who is having the same problem and has tried #Esa's answer, you may notice that it sometimes does not work when run outside the directory. This is caused by Pyinstaller still trying to find the relative path and not using the included files instead. This can be fixed by finding the correct path inside your code before loading files:
if getattr(sys, 'frozen', False):
Path = sys._MEIPASS #This is for when the program is frozen
else:
Path = os.path.dirname(__file__) #This is when the program normally runs
This finds the actual path of your file and must be done for every file, e.g:
pygame.image.load(os.path.join(Path, 'Path\\to_file\\from_root'))
sys._MEIPASS is the key as it will find the path when the program is frozen as when a program is frozen, it's files are stored somewhere else.
When you generate the .exe file a .spec file will also be created with the root directory. In there you will need to edit this as follows:
You should see a file structure similar to the one below
Notice how datas is equal to None. You will have to edit this.
This is the .spec file in the root directory currently:
# -*- mode: python -*-
block_cipher = None
#you will have to add things here later
a = Analysis(['file.py'],
pathex=['C:\\path\\to\\root\\folder'],
binaries=None,
datas=None,
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='game_file',
debug=False,
strip=False,
upx=True,
console=True , icon='icon_file.ico')
Now what we do is we add all our files: Place this added_files below block_cipher but above Analysis(), e.g:
added_files = [
('file1.png', '.') #The '.' represents root folder
('file2.png', '\\folder') #loads file2.png from root\folder
]
Now inside of Analysis() we change the None after datas to added_files. You will also notice that there are the main different options for your final file. You can edit these here if you want but you cannot change the "onefile" option, this is made when the .spec file is created.
Finally to make this new exe file, go to your root folder in cmd and type this:
pyinstaller "PY_FILE_NAME.spec"
The final exe, whether in a folder or not should be in root\dist\Executable_name.exe or root\dist\Executable_name\Executable_name.exe
I ran into this same problem. For some reason the working directory is not set properly for the --onefile packaged executable. I managed to resolve it by using the following piece of code at the beginning of my program.
This is similar to the above proposed solutions but I find it slightly more elegant :)
It basically forces the working directory to the temporary extracted directory in case we are running as a single executable.
import sys
import os
if getattr(sys, 'frozen', False):
os.chdir(sys._MEIPASS)
got it working with:
img_l = pygame.image.load(os.path.join('img.png'))
screen.blit(img_l, (0, 0))
Now it works as it should after going through PyInstaller :)
Sorry, I'm very very new to programming.
I'm getting a similar (the same?) error when I try to run my .exe
It says:
pygame.error: Couldn't open walkr1.png
I tried the fix that you used, but then got the error:
pygame.error: Can't seek in this data source
The image files are in a folder in the folder with the main .py file. I've tried moving the files to the same folder but that didn't work. I've also tried adding the data files to the .spec file, but that doesn't seem to work either...
Was wondering if you could help?
Sorry, I know these are probably all very dumb questions.

Categories

Resources