20

Does anybody know a way to embed an icon in a Python script such that when I create my standalone executable (using pyinstaller) I don't need to include the .ico file? I know this is possible with py2exe, but in my case I have to use Pyinstaller, as I was not successful using the former. I am using Tkinter.

I know about iconbitmap(iconName.ico) but that doesn't work if I wanna make a onefile executable.

3
  • Just to make it clearer: I want to change the icon of my application window (which by default has the Tk logo), not the icon of my file (which can be easily done with Pyinstaller) Commented Mar 30, 2012 at 13:12
  • Aha! After googling a bit more I found an answer on Stack Overflow here. Does that help? Commented Mar 30, 2012 at 14:26
  • Yeah I've seen that one before. It's exactly my same problem. I just don't understand what he does there. It does look like it's the correct solution, maybe I should dig a bit more. Thanks! Commented Mar 30, 2012 at 14:35

6 Answers 6

26

Actually the function iconbitmap can only receive a filename as argument, so there needs to be a file there. You can make a Base64 version of the icon (A string version) following the link, uploading the file and copying the result in your source file as a variable string. Extract it to a temporal file, finally passing that file to iconbitmap and deleting it. It's quite simple:

import base64
import os
from Tkinter import *
##The Base64 icon version as a string
icon = \
""" REPLACE THIS WITH YOUR BASE64 VERSION OF THE ICON
"""
icondata= base64.b64decode(icon)
## The temp file is icon.ico
tempFile= "icon.ico"
iconfile= open(tempFile,"wb")
## Extract the icon
iconfile.write(icondata)
iconfile.close()
root = Tk()
root.wm_iconbitmap(tempFile)
## Delete the tempfile
os.remove(tempFile)

Hope it helps!

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot, that worked beautifully! Do you by any chance know how to change the icon in a figure window created with Matplotlib? My application has got my icon now, but when I plot the graph, the new window still has the TK logo as icon. Many thinks for your help
Sorry, I don't know about Matplotlib, but if there is not a function for changing the icon, I don't think there is a way. Doesn't wm_iconbitmap work in Matplotlib?
14

You probably don't need this but somebody else might find this useful, I found you can do it without creating a file:

import Tkinter as tk

icon = """
    REPLACE THIS WITH YOUR BASE64 VERSION OF THE ICON
    """

root = tk.Tk()
img = tk.PhotoImage(data=icon)
root.tk.call('wm', 'iconphoto', root._w, img)

1 Comment

I actually wasn't able to get this method or Sam's method to work with an icon in Python 3.4.3 but Saulpila's method worked so I know there wasn't any error with the Base64 code.
5

Option 1: Embedding .ico into the binary (recommended)

Edit your .spec file like this:

a = Analysis(....)
pyz = PYZ(a.pure, ....)
exe = EXE(pyz,
          a.scripts,
          a.binaries + [('<name.ico>', '<full_path_to_your.ico>', 'DATA')], 
          a.zipfiles,
          a.datas, ....)

Add this right after root = Tk() in the main script:

root.iconbitmap(default=os.path.join(sys.prefix if hasattr(sys, "frozen") else os.path.dirname(__file__), "<name.ico>"))

Option 2: Adding .png as a BASE64 string (requires "base64" lib)

Import base64 and add this right after root = Tk() in the main script:

root.wm_iconphoto(True, PhotoImage(data=base64.b64decode("""<BASE64_of_your_png_icon>""")) )

My versions: python3.4, pyinstaller3.1.1

3 Comments

Im getting error: SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
For me, the solution was to use relative path for path_to_your.ico instead of absolute path and it's working like a charm.
@alienware13user Encode string with UTF8 encoding before you pass it to the function
2

This worked for me:

from tkinter import  PhotoImage
import base64
img = """
REPLACE THIS WITH YOUR BASE64 VERSION OF THE ICON
"""
img= base64.b64decode(img)

root = Tk()
img=PhotoImage(data=img) 
root.wm_iconphoto(True, img)

1 Comment

worked for .png but not for .ico for me. Python 3.11.1, Windows 10
1
import Tkinter as tk

icon = """
REPLACE THIS WITH YOUR BASE64 VERSION OF THE ICON
"""

root = tk.Tk() 
root.iconphoto(True, PhotoImage(data=icon))

Convert a .png file instead of an icon, also using utf-8 encoding with the same code above worked great for me!

Comments

1

There is a easier and more efficient way to solving this issue.

Since you have:

root.iconbitmap("icon.ico")

And since it is using the file from the same directory as the EXE file all you have to do is copy the file and put it in the same directory as the application.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.