Python tkinter errors setting icon, TclError linux - python

I am fairly new to python and very new to GUI's so please let me know if I have made an obvious mistake.
This is also my first post so please let me know if I need to edit my question in some way.
I don't understand why I am getting errors when trying to set an icon to a tkinter GUI.
I have already tried the following posts:
tkinter TclError: error reading bitmap file
https://www.delftstack.com/howto/python-tkinter/how-to-set-window-icon-in-tkinter/
There are other stack exhange posts on this topic but they are for windows and/or their OP's normally can get the icon to apear once then it doesn't work. This isn't my situation the programs fail to run. Though I have tried some of their suggestions as well.
I have tried three different ways of coding this:
Method 1:
from tkinter import *
import os
class MainWindow:
def __init__(self, master):
self.master = master
master.title('TD')
#self.iconbitmap(default = 'fist.ico')
root = Tk()
root.iconphoto(True, PhotoImage(os.path.join(os.getcwd(),'favicon-3.png')))
my_gui = MainWindow(root)
root.mainloop()
Result:
runfile('~./envs/thermTD_project/thermTD/untitled2.py', wdir='~./envs/thermTD_project/thermTD')
Traceback (most recent call last):
File "~./envs/thermTD_project/thermTD/untitled2.py", line 23, in <module>
root.iconphoto(True, PhotoImage(os.path.join(os.getcwd(),'favicon-3.png')))
File "/usr/lib/python3.8/tkinter/__init__.py", line 2116, in wm_iconphoto
self.tk.call('wm', 'iconphoto', self._w, "-default", *args)
TclError: can't use "~./envs/thermTD_project/thermTD/favicon-3.png" as iconphoto: not a photo image
File existence check:
In [42]: os.path.exists(os.path.join(os.getcwd(),'favicon-3.png'))
Out[42]: True
Method 2:
from tkinter import *
import os
class MainWindow:
def __init__(self, master):
self.master = master
master.title('TD')
#self.iconbitmap(default = 'fist.ico')
root = Tk()
root.iconbitmap(os.path.join(os.getcwd(),'favicon-3.ico'))
my_gui = MainWindow(root)
root.mainloop()
Result:
In [43]: runfile('~./envs/thermTD_project/thermTD/untitled2.py', wdir='~./envs/thermTD_project/thermTD')
Traceback (most recent call last):
File "~./envs/thermTD_project/thermTD/untitled2.py", line 22, in <module>
root.iconbitmap(os.path.join(os.getcwd(),'favicon-3.ico'))
File "/usr/lib/python3.8/tkinter/__init__.py", line 2071, in wm_iconbitmap
return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
TclError: bitmap "~./envs/thermTD_project/thermTD/favicon-3.ico" not defined
File existence check:
In [44]: os.path.exists(os.path.join(os.getcwd(),'favicon-3.ico'))
Out[44]: True
Method 3:
from tkinter import *
import os
class MainWindow:
def __init__(self, master):
self.master = master
master.title('TD')
#self.iconbitmap(default = 'fist.ico')
root = Tk()
img = PhotoImage(os.path.join(os.getcwd(),'favicon-3.ico'))
root.tk.call('wm','iconphoto', root._w, img)
my_gui = MainWindow(root)
root.mainloop()
Result:
In [45]: runfile('~./envs/thermTD_project/thermTD/untitled2.py', wdir='~./envs/thermTD_project/thermTD')
Traceback (most recent call last):
File "~./envs/thermTD_project/thermTD/untitled2.py", line 21, in <module>
root.tk.call('wm','iconphoto', root._w, img)
TclError: can't use "~./envs/thermTD_project/thermTD/favicon-3.ico" as iconphoto: not a photo image
File existence check:
See method 1
The code without any of the icon setting lines works as expected.
I have tried to gif, png and ico on each method. I am trying other file types now.
NB: While the filename is favicon actually they are ico, gif, png files of 64x64 pixles. Even the favicon ico only has 1 type of icon in it (if thats the right phrase). Its just I got them from a favicon which I converted to different formats using mogrify.
OS: Ubuntu 20.04.1 LTS
python 3.8.2
IDE: spyder 4.1.5
P.S. I would be gratefull to know what the syntax for including this in my init function. I am trying to do object orientated GUI's I am very much still learning.

Related

Tkinter saying pyimage1 doesn't exist even though it does when trying to put it on a label

When running the code, I receive this error:
[(<memory at 0x000001ADB67D2040>,)]
1
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=592x1052 at 0x1ADB67FF280>
=-----------------------------------=
pyimage1
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Player 1\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "c:\Users\Player 1\OneDrive\Documents\Year 13\Computer Science\NEA\Code\windows.py", line 373, in <lambda>
images_button = tkinter.Button(self, text="View {} Images".format(listingname), font=('calibre', 20, 'bold'), command=lambda: self.create_command_for_Nav_Buttons("Pictures", condition=listing_id)).grid(column=0, row=0, rowspan=7)
File "c:\Users\Player 1\OneDrive\Documents\Year 13\Computer Science\NEA\Code\windows.py", line 77, in create_command_for_Nav_Buttons
start_window.create_page(condition)
File "c:\Users\Player 1\OneDrive\Documents\Year 13\Computer Science\NEA\Code\windows.py", line 412, in create_page
images = tkinter.Label(master=self, image=photo, width=300, height=300)
File "C:\Users\Player 1\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 3148, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Users\Player 1\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 2572, in __init__
self.tk.call(
_tkinter.TclError: image "pyimage1" doesn't exist
This is the part of the code that doesn't work.
class picture_page(Window):
def __init__(self, current_window="Pictures!") -> None:
super().__init__(current_window)
def create_page(self, listing_id):
imagesMView_list = dbm.getImagesForListing(listing_id)
print(imagesMView_list)
print(len(imagesMView_list))
if len(imagesMView_list) == 0:
self.create_Label("There are no images!", ('calibre', 20, 'bold'), 0, 0)
else:
processedImage_list = []
for i in range(len(imagesMView_list[0])):
processedImage_list.append(bytes(imagesMView_list[0][i]))
# for i in range(len(processedImage_list)):
# img = Image.open(io.BytesIO(processedImage_list[i]))
# photo = ImageTk.PhotoImage(img)
# print(img)
# print(photo)
# tkinter.Label(master=self, image=photo).pack()
for i in range(len(processedImage_list)):
img = Image.open(io.BytesIO(processedImage_list[i]))
print(img)
print("=-----------------------------------=")
photo = ImageTk.PhotoImage(img)
print(photo)
images = tkinter.Label(master=self, image=photo, width=300, height=300)
images.grid(column=i, row=0)
The commented part that looks like code was another fix I tried.
I also looked through these other stackoverflow questions (Tkinter OOP "PyImage1" doesn't exist, error and Tkinter create image function error (pyimage1 does not exist))
Thank you in advance!
EDIT: I have tried to put Global photo into my code to keep it as a reference, however that still causes the same issue to occur. I also wanted to say that this photo_page subclass inherits from the Windows Class and the Windows class inherits from Tk. This hasn't caused me any issues other than with putting an image in the label. The image comes from a database and in the database is stored as a byte Array and I convert it back into bytes and then into JPEG form (which I know is successful because I printed out the variables I assigned it to and they look fine).
The way I fixed my error was changing what my main class inherited. Initially, it was Windows(Tk): , however I changed it to Windows(Toplevel) and it fixed the issue.
have you by chance accidentally created two or more root windows? Objects in one root window cant see or interact with things
in the second root window

How do I bundle my tkinter based application with my custom icon?

I have a tkinter based application structured as follows:
import tkinter as tk
class App(tk.Frame):
def __init__(self, master):
self.master = master
tk.Frame.__init__(self, self.master)
self.configure_gui()
self.create_widgets()
def configure_gui(self):
self.master.iconbitmap("my_logo.ico")
self.master.title("Example")
self.master.minsize(250, 50)
def create_widgets(self):
self.label = tk.Label(self.master, text="hello world")
self.label.pack()
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()
When I run the .py file from the command line, my logo replaces the default tkinter feather logo in the applications main window as expected. I am even able to freeze and bundle my application with pyinstaller using the following command:
pyinstaller -i my_logo.ico my_application.py
Unfortunately, when I attempt to run the .exe file generated by this process I am met with the following error:
Traceback (most recent call last):
File "my_application.py", line 22, in <module>
File "my_application.py", line 7, in __init__
File "my_application.py", line 11, in configure_gui
File "tkinter\__init__.py", line 1865, in wm_iconbitmap
_tkinter.TclError: bitmap "my_logo.ico" not defined
[5200] Failed to execute script my_application
I have scoured this site and others in search of a solution that works in my case and have found none. Any direction would be greatly appreciated!
I've found it easier for me just to store the image as a .py module, then PyInstaller handles it like any other module and the basic command line command to make the exe work without anything special:
Script to make image.py file:
import base64
with open("my_logo.ico", "rb") as image:
b = base64.b64encode(image.read())
with open("image.py", "w") as write_file:
write_file.write("def icon(): return (" + str(b) + ")"
Then import the module as the image:
import tkinter as tk
import image
class App(tk.Frame):
def __init__(self, master):
self.master = master
tk.Frame.__init__(self, self.master)
self.configure_gui()
self.create_widgets()
def configure_gui(self):
self.master.tk.call('wm', 'iconphoto', self.master._w, tk.PhotoImage(data=image.icon()))
self.master.title("Example")
self.master.minsize(250, 50)
def create_widgets(self):
self.label = tk.Label(self.master, text="hello world")
self.label.pack()
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()
Otherwise you basically have to call out adding the .ico file in the build command, then in your script need to add lines to determine where the unpacked pyinstaller-packed script's directory is, then adjust your path to the packed .ico file.
Discussed here: Bundling data files with PyInstaller (--onefile)
But I find my way easier.

Python 3 Tkinter Program not launching without IDLE

I'm currently trying to create a Python3 Tkinter program which I can launch by double clicking or opening from other python scripts, instead of going through idle.
So far I've had little luck, as when I attempt to launch the script the console opens for a moment and then crashes.
EDIT: Removing the logo segment of code allows the program to run. Any ideas why and how to fix it? Also I have not had to run a program via the console before so little luck there.
from tkinter import *
from tkinter import ttk
root = Tk()
root.title("Kinematics")
Logo_frame = LabelFrame(root, bg = "white")
Logo_frame.grid(row=0, column=12, sticky = "NSEW")
#Logo
Logo = Image(file="Logo-S.gif")
image_label = ttk.Label(Logo_frame, image=Logo)
image_label.grid(row=0, column=0, rowspan = 3)
root.mainloop()
The error from your present code is:
Exception ignored in: <bound method Image.__del__ of <tkinter.Image object at 0x7f1aa91df2e8>>
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 3357, in __del__
if self.name:
AttributeError: 'Image' object has no attribute 'name'
Traceback (most recent call last):
File "/home/sunbear/Coding/python35/tkinter/stackoverflow_questions/test52.py", line 22, in <module>
Logo = Image(file="Logo-S.gif")
TypeError: __init__() missing 1 required positional argument: 'imgtype'
There is a typo in your command in line 22(your original code before edit). You need the following correction to overcome this error, i.e.:
#Logo
#Logo = Image(file="Logo-S.gif")
Logo = PhotoImage(file="Logo-S.gif") #you should change to this.
You can read more about when to use PhotoImage and Image using this link I gave you.
I just attempted to run the program with a random gif I found online, all seemed to work to plan. I'm running windows 10 pro... maybe try re-saving/downloading the gif.

_tkinter.TclError: encountered an unsupported criticial chunk type "exIf"

So I am trying to put some pictures into my window and whenever I run the program it gives me this error:
_tkinter.TclError: encountered an unsupported criticial chunk type "exIf"
I tried putting it into other formats, such as .jpg, .png and .gif, but they don't work. Can you please help me?
This is my code:
from tkinter import *
from tkinter import ttk
class Window:
def __init__(self, master):
self.master = master
master.iconbitmap('ta.ico')
master.title('Tamagochi')
master.minsize(width=480, height=240)
master.maxsize(width=480, height=240)
self.pic1 = PhotoImage(file='pic1.png')
self.pic2 = PhotoImage(file='pic2.png')
self.pic3 = PhotoImage(file='pic3.png')
self.pic4 = PhotoImage(file='pic4.png')
self.smFrame = ttk.Frame(master)
self.smButton1 = ttk.Button(self.smFrame, text='Start', command=self.start)
self.smButton2 = ttk.Button(self.smFrame, text='Options', command=self.options)
self.smButton3 = ttk.Button(self.smFrame, text='Quit', command=self.quit)
self.smPhoto1 = ttk.Label(self.smFrame, image=self.pic1)
self.smFrame.pack()
self.smPhoto1.grid()
self.smButton1.grid(pady=40, padx=200)
self.smButton2.grid(pady=0, padx=200)
self.smButton3.grid(pady=40, padx=200)
def start(self):
pass
def options(self):
pass
def quit(self):
exit()
root = Tk()
Window(root)
root.mainloop()
This is the full error:
Traceback (most recent call last):
File "C:/Users/NemPl/Desktop/ProLan/Python/Python programi/Tamagochi/Tamagochi.py", line 35, in <module>
Window(root)
File "C:/Users/NemPl/Desktop/ProLan/Python/Python programi/Tamagochi/Tamagochi.py", line 14, in __init__
self.pic3 = PhotoImage(file='pic3.png')
File "C:\Users\NemPl\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 3539, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Users\NemPl\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 3495, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: encountered an unsupported criticial chunk type "exIf"
PhotoImage is a tkinter class which, unfortunately, can not deal with .png files.
The solution is to rely on the Python Imaging Library1 which offers support to several image formats and transforms them to image objects that can be "understood" by tkinter:
from PIL import Image, ImageTk
self.img1 = Image.open("pic1.png")
self.pic1 = ImageTk.PhotoImage(self.img1)
1. You can install PIL as described here.
Just wanted to share a solution that solved for me!
I figured out that other '.png' images were working with the same code, so the problem was happening with the image file.
What solved my problem was simply modifying the image (just saved it from a image editor).

Python PIL ImageTk.PhotoImage() is giving me a bus error?

So I am running python 2.6 on a macbook pro and trying to write the code in python to display an image from a file in a label on a tkinter gui. The image is called image.png. The program runs without errors when I use this code
i = Image.open("image.png")
but when I do this code (I add one line):
i = Image.open("image.png")
photo = ImageTk.PhotoImage(i)
The program will crash and say "Bus error" in the command line. I don't even know what that means. I would think that PIL is installed correctly, since Image works, but the fact that ImageTk does not work puzzles me. Can anybody tell me what might be causing this Bus error?
EDIT:
Well I made a new program to test the error further. Here is the exact script I ran:
import Image
import ImageTk
i = Image.open("image.png")
photo = ImageTk.PhotoImage(i)
Now instead of getting "Bus error", this is my traceback.
Traceback (most recent call last):
File "imageTest.py", line 5, in <module>
photo = ImageTk.PhotoImage(i)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/PIL/ImageTk.py", line 113, in __init__
self.__photo = apply(Tkinter.PhotoImage, (), kw)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk/Tkinter.py", line 3285, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk/Tkinter.py", line 3226, in __init__
raise RuntimeError, 'Too early to create image'
RuntimeError: Too early to create image
Exception AttributeError: "PhotoImage instance has no attribute '_PhotoImage__photo'" in <bound method PhotoImage.__del__ of <ImageTk.PhotoImage instance at 0x3c7a30>> ignored
I don't know about the Bus Error, but you need to create a Tk window before you can call PhotoImage. This script works for me-
import Image
import ImageTk
from Tkinter import Tk
window = Tk()
i = Image.open("image.png")
photo = ImageTk.PhotoImage(i)
ImageTk.PhotoImage has a garbage collection (ref count) bug in it. You must place a reference to the PhotoImage object in either a global variable of a class instance variable (e.g., self.myphoto = ImageTk.PhotoImage(i)).
See this warning:
http://infohost.nmt.edu/tcc/help/pubs/pil/image-tk.html
Even thought you do need to call a Tk window you also need to set the directory so that it can find the image.png.
import os
import Image
import ImageTk
from Tkinter import Tk
os.chdir('C:/../../') # put file path for the image.
window = Tk()
i = Image.open("image.png")
photo = ImageTk.PhotoImage(i)
window.mainloop()

Categories

Resources