Why isn't .ico file defined when setting window's icon?
Asked Answered
S

14

63

When I tried to change the window icon in the top left corner from the ugly red "TK" to my own favicon using the code below, Python threw an error:

from tkinter import *
root = Tk()

#some buttons, widgets, a lot of stuff

root.iconbitmap('favicon.ico')

This should set the icon to 'favicon.ico' (according to a lot of forum posts all over the web). But unfortunately, all this line does is throw the following error:

Traceback (most recent call last):
  File "d:\ladvclient\mainapp.py", line 85, in <module>
    root.iconbitmap(bitmap='favicon.ico')
  File "C:\Python33\lib\tkinter\__init__.py", line 1637, in wm_iconbitmap
    return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
_tkinter.TclError: bitmap "favicon.ico" not defined

What I already did:

  • I checked the path - everything is 100% correct
  • I tried other file formats like .png or .bmp - none worked
  • I looked this problem up on many websites

And for the third point, effbot.org, my favorite site about Tkinter, told me that Windows ignores the iconbitmap function. But this doesn't explain why it throws an error!

There are some "hackish" ways to avoid that issue, but none of them are Written for Python 3.x.

So my final question is: Is there a way to get a custom icon using Python 3.x and Tkinter?

Also, don't tell me I should use another GUI Library. I want my program to work on every platform. I also want a coded version, not a py2exe or sth solution.

Straightforward answered 30/8, 2013 at 16:51 Comment(2)
Is favicon.ico in the folder where you are running the script? Other wise you have to provide the full path. Also, when other thing you can do is change the format to a .gif, I think thats the only format tkinter accepts.Proceeding
@enginefree - No. Tkinter accepts .ico as well.Tractate
T
63

You need to have favicon.ico in the same folder or dictionary as your script because python only searches in the current dictionary or you could put in the full pathname. For example, this works:

from tkinter import *
root = Tk()

root.iconbitmap(r'c:\Python32\DLLs\py.ico')
root.mainloop()

But this blows up with your same error:

from tkinter import *
root = Tk()

root.iconbitmap('py.ico')
root.mainloop()
Tractate answered 30/8, 2013 at 17:27 Comment(9)
Dude, you are great (or I am just a bit stupid). There is only one question left? is there an easy possibility of dynamically loading the path instead of having a fixed one? because this would give me more freedom at some point :)Straightforward
@Straightforward - What you did wasn't stupid. In fact, it should have worked if favicon.ico was on the path. Anyways, I suppose you could build something dynamic using the os module to walk certain directories looking for .ico files. However, this might cause you to load the wrong image, which would be embarrassing. My advice would be to pick the icon you want and then keep it with the script.Tractate
there is just one thing left that I need to know - which path does Python think is meant when I don't specify a path? Like where on my Computer did Python search for 'favicon.ico' before I told it where to search?Straightforward
@Straightforward - I believe it only checks the directory that the script is in. If it can't find it, it blows up.Tractate
Note that if you want to be sure, you can get the directory of your script by doing os.path.dirname(os.path.abspath(file)) (thats underscore underscore file underscore underscore)Shadowy
I've used os.path and functions contained therein to get the full path to the .ico icon file (which definitely exists), but it still gives me that traceback for an error: _tkinter.TclError: bitmap "/usr/local/src/py/project/media/Question-Shield.ico" not definedSlayton
Depending on who or what is calling or launching your script, you might need to use sys.path[0] instead of os.path to make it "portable". This works for me, when another tool (Scribus) is calling my scripts.Puzzler
Ok dudes, here is the thing: My icon is right next to the script and I'm also running the script in the same folder. The icon file is readable by the user and I'm using python3. Still the same error. Using the full path dosen't work either.Stereotyped
The dynamic path option works for me. I'm using Python 3.4.3. I wonder if you could bypass that bug by importing the OS module and using "root.iconbitmap(os.path.abspath('py.ico'))"?Barrelchested
M
23

No way what is suggested here works - the error "bitmap xxx not defined" is ever present. And yes, I set the correct path to it.

What it did work is this:

imgicon = PhotoImage(file=os.path.join(sp,'myicon.gif'))
root.tk.call('wm', 'iconphoto', root._w, imgicon)  

where sp is the script path, and root the Tk root window.

It's hard to understand how it does work (I shamelessly copied it from fedoraforums) but it works

Marked answered 24/4, 2017 at 12:18 Comment(7)
This works on FreeBSD. From that I would guess that it works on all Xorg/X11 based systems. It does not set the icon on Native Tk under OS X. I have not tested it on Windows.Utimer
What is your variable sp?Androsphinx
sorry, a quick cut&paste of code... sp is simply my script path, where the icon livesMarked
@Marked this worked for me! did you ever figure out how it works?Ortrud
@Ortrud no, I didnt investigate it further. Looking back to it, I didnt notice that the original question mentioned python3: at the time of my answer I still used python2.7. But I transitioned to python3 now, and it still worksMarked
@Marked yes it's working on python3. This is what I've been using. I don't know the exact details either, but it's doing what's intended.Ortrud
Works for me on python 3 on UbuntuEwold
V
10

This works for me with Python3 on Linux:

import tkinter as tk

# Create Tk window
root = tk.Tk()

# Add icon from GIF file where my GIF is called 'icon.gif' and
# is in the same directory as this .py file
root.tk.call('wm', 'iconphoto', root._w, tk.PhotoImage(file='icon.gif'))
Valve answered 21/7, 2018 at 13:53 Comment(2)
what does wm do ?Underneath
wm communicates with the window manager about attributes of toplevel windows. See: wiki.tcl-lang.org/page/wmValve
C
2

Got stuck on that too...

Finally managed to set the icon i wanted using the following code:

from tkinter import *
root.tk.call('wm', 'iconphoto', root._w, PhotoImage(file='resources/icon.png'))
Cano answered 30/3, 2019 at 14:3 Comment(0)
P
1
#!/usr/bin/env python
import tkinter as tk

class AppName(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.grid()
        self.createWidgets()

    def createWidgets(self):
        self.quitButton = tk.Button(self, text='Quit', command=self.quit)
        self.quitButton.grid()

app = AppName()
app.master.title('Title here ...!')
app.master.iconbitmap('icon.ico')
app.mainloop()

it should work like this !

Pish answered 13/1, 2016 at 8:45 Comment(1)
Yes it does the job. ThanksGemmell
G
1

Make sure the .ico file isn't corrupted as well. I got the same error which went away when I tried a different .ico file.

Gemmell answered 3/11, 2016 at 21:56 Comment(0)
H
1

Both codes are working fine with me on python 3.7..... hope will work for u as well

import tkinter as tk
m=tk.Tk()
m.iconbitmap("myfavicon.ico")
m.title("SALAH Tutorials")
m.mainloop()

and do not forget to keep "myfavicon.ico" in the same folder where your project script file is present

Another method

from tkinter import *
m=Tk()
m.iconbitmap("myfavicon.ico")
m.title("SALAH Tutorials")
m.mainloop()

[*NOTE:- python version-3 works with tkinter and below version-3 i.e version-2 works with Tkinter]

Hienhieracosphinx answered 25/7, 2018 at 9:16 Comment(0)
K
1

I had the same problem too, but I found a solution.

root.mainloop()

from tkinter import *
    
# must add
root = Tk()
root.title("Calculator")
root.iconbitmap(r"image/icon.ico")
    
root.mainloop()

In the example, what python needed is an icon file, so when you dowload an icon as .png it won't work cause it needs an .ico file. So you need to find converters to convert your icon from png to ico.

Kastroprauxel answered 25/4, 2020 at 10:41 Comment(0)
Z
1

Try this:

from tkinter import *
import os
import sys

root = Tk()
root.iconbitmap(os.path.join(sys.path[0], '<your-ico-file>'))

root.mainloop()

Note: replace <your-ico-file> with the name of the ico file you are using otherwise it won't work.

I have tried this in Python 3. It worked.

Zoolatry answered 5/6, 2020 at 19:25 Comment(0)
K
0

So it looks like root.iconbitmap() only supports a fixed directory.
sys.argv[0] returns the directory that the file was read from so a simple code would work to create a fixed directory.

import sys
def get_dir(src):
    dir = sys.argv[0]
    dir = dir.split('/')
    dir.pop(-1)
    dir = '/'.join(dir)
    dir = dir+'/'+src
    return dir

This is the output

>>> get_dir('test.txt')
'C:/Users/Josua/Desktop/test.txt'

EDIT:
The only issue is that this method dosn't work on linux

josua@raspberrypi:~ $ python
Python 2.7.9 (default, Sep 17 2016, 20:26:04) [GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.argv[0]
''
>>>
Kleptomania answered 24/12, 2017 at 5:44 Comment(2)
This is a really horrible and platform dependent and still slightly broken way to operate on paths instead of using the functions from os.path.Denyse
Yes, you are right. It is kind of broken, just tested it on my raspberry pi and it dosn't work.Kleptomania
L
0
from tkinter import *
from PIL import ImageTk, Image

Tk.call('wm', 'iconphoto', Tk._w, ImageTk.PhotoImage(Image.open('./resources/favicon.ico')))

The above worked for me.

Lenlena answered 11/4, 2019 at 22:55 Comment(0)
L
0

I recently ran into this problem and didn't find any of the answers very relevant so I decided to make a SO account for this.

Solution 1: Convert your .ico File online there are a lot of site out there

Solution 2: Convert .ico File in photoshop

If you or your Editor just renamed your image file to *.ico then it is not going to work.
If you see the image icon from your Windows/OS folder then it is working

Laryngitis answered 14/9, 2020 at 7:49 Comment(2)
Actually, Photoshop doesn't support .ico fileRoden
I can confirm, for photoshop to save ico you will need a external plugin.Disputatious
G
0

I'm using Visual Studio Code. To make "favicon.ico" work, you need to specify in which folder you are working.

  • You press ctrl + shift + p to open the terminal cmd+shift+p on OSX.
  • In the terminal, you type: cd + the path where you are working. For example: cd C:\User\Desktop\MyProject
Gmt answered 15/1, 2021 at 15:10 Comment(1)
I use "ctrl" + "ñ" to open the terminal on windows.Gmt
L
0

CONVERT YOUR IMAGE FILE INTO A PHOTO IMAGE FIRST

img = PhotoImage(file='your-icon')

Landy answered 19/2, 2022 at 0:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.