Embed icon in python script
Asked Answered
A

6

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.

Areopagite answered 29/3, 2012 at 16:27 Comment(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)Areopagite
Aha! After googling a bit more I found an answer on Stack Overflow here. Does that help?Peasecod
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!Areopagite
H
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!

Homework answered 15/4, 2012 at 19:46 Comment(2)
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 helpAreopagite
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?Amari
U
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)
Upkeep answered 12/5, 2014 at 18:37 Comment(1)
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.Kiri
C
5

Follow these steps:

  1. Edit your .spec file like this:
a = Analysis(....)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          a.binaries + [('your.ico', 'path_to_your.ico', 'DATA')], 
          a.zipfiles,
          a.datas, 
          name=....
       )
  1. Add this to your script:
datafile = "your.ico" 
if not hasattr(sys, "frozen"):
    datafile = os.path.join(os.path.dirname(__file__), datafile) 
else:  
    datafile = os.path.join(sys.prefix, datafile)
  1. Use it this way:
root = tk.Tk()
root.iconbitmap(default=datafile)

Because this wont work after You compile your script with Pyinstaller:

root = tk.Tk()
root.iconbitmap(default="path/to/your.ico")

My Info: python3.4, pyinstaller3.1.1

Childhood answered 18/1, 2017 at 15:53 Comment(2)
Im getting error: SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escapeGreenway
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.Jennajenne
P
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)
Pule answered 26/11, 2018 at 13:58 Comment(1)
worked for .png but not for .ico for me. Python 3.11.1, Windows 10Palm
R
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!

Rolf answered 18/4, 2022 at 1:53 Comment(0)
P
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.

Pyrogenic answered 30/12, 2023 at 2:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.