How do I use PIL with Tkinter? - python

I'm missing something at a very basic level when it comes to loading an image using PIL and displaying it in a window created by Tkinter. The simplest form of what I'm trying to do is:
import Tkinter as TK
from PIL import Image, ImageTk
im = Image.open("C:\\tinycat.jpg")
tkIm = ImageTk.PhotoImage(im)
tkIm.pack()
TK.mainloop()
When I try to run the code above, I get the following:
RuntimeError: Too early to create image
Exception AttributeError: "PhotoImage instance has no attribute
'_PhotoImage__photo'" in <bound method PhotoImage.__del__ of
<PIL.ImageTk.PhotoImage instance at 0x00C00030>> ignored
I've confirmed the file is present and can be opened in an image editor and also that it can be displayed using im.show(). What am I missing?

Tkinter has to be instantiated before you call ImageTk.PhotoImage():
TK.Tk()

It's very true what Meredith said you need to add that line for sure!
I would like to show you my image formatting and then compare it to yours and see if there any different, my code for a image is
master.image = PhotoImage(file="Banditlogo.gif")
w = Label(master, image=master.image)
w.photo = master
w.pack()
And your code is
im = Image.open("C:\\tinycat.jpg")
tkIm = ImageTk.PhotoImage(im)
tkIm.pack()
We are both using PIL with PhotoImage
I can't help wondering are both ways correct?
At this point in time I don't have enough knowledge to fully answer your PIL question but it is interesting to compare both codes as they are different. I can only suggest doing what I do when it comes to example codes people share with me, and that is "if mine don't work, try the example code and see if that fixes the code" when I find something that works I stick with it.
Would someone with more understanding of Tkinter please explane the workings of, How do I use PIL with Tkinter?
Knowledge is power so please share.

Related

When implementing Splash Screen, pyimage doesn't exist anymore

So, that's one of the strangest errors I've ever seen in Python. Hopefully, you can help me.
I have a tkinter mainwindow in main_file implementing images via:
from PIL import Image, ImageTk, ImageColor
#...
self.image_package_render = Image.open('ImagePackage.png')
self.image_package_render_data = np.array(self.image_package_render.convert('RGBA'))
self.plus_render = ImageTk.PhotoImage(self.image_package_render.resize((14, 14), box=(16, 20, 30, 34)))
When I launch the main_file directly, it works like a charm via root.mainloop().
Now I want to implement a splash screen by developing an external script:
import tkinter as tk
splash_root = tk.Tk()
splash_root.geometry("200x200")
splash_label = tk.Label(splash_root, text="Splash Screen", font=18)
splash_label.pack()
import main_file
splash_root.destroy()
tk.mainloop()
Now, however, main_file doesn't start up and throws me the error "_tkinter.TclError: image "pyimage12" doesn't exist".
(Also doesn't work, if I implement the splash_root directly in main_file).
It clearly has something to do with splash_root, but I can't get my head around it.
Cheers guys!
Update: Solved:
It appears that another mainloop apart from root.mainloop() in combination with another window besides a toplevel, just crashes the code somehow.
I implemented a toplevel window as splash like suggested here: Tkinter Show splash screen and hide main screen until __init__ has finished
Thank you!

"TclError: image", while adding a image to a Label

I have been stuck trying to add an image to my tkinter GUI and google does not seem to give answers. I understand that I should not use grid or pack gemoetry managers within the same master window, and I havent as far as I can tell but every attempt has resulted in either of the following error messages:
TclError: cannot use geometry manager grid inside . which already has slaves managed by pack
or:
TclError: image "pyimage86" doesn't exist
Incidently everytime I rerun my code the "pyimage86" changes, every run increases the number by 1, for example 'pyimage86', 'pyimage87', etc etc.
The first error message is particularly confusing because I am using .grid to place my labelled image into the class but the error is saying otherwise? (example code is not in a class, I know)
I have tried different images and converted the original image into a .TIF, .JNP, .PNG, .GIF but none give a result. I have also removed the Alpha channel (apprantly that might have been an issue when using ImageTK.PhotoImage but it did not help). I have also converted the image into grasyscale as a last ditch attempt but no luck.
import tkinter as tk
import PIL.Image
import PIL.ImageTk
root = tk.Tk()
image = Image.open("TemplateRack_GUI.png")
photo = ImageTk.PhotoImage(image)
label = tk.Label(image=photo)
label.image = photo
label.grid(row=5, column=5)
root.mainloop()
You say that your program gives you sometimes:
TclError: cannot use geometry manager grid inside which already has slaves managed by pack.
and sometimes:
TclError: image "pyimage86" doesn't exist.
I can't believe that!
Furthermore you said "I understand that I should not use grid or pack gemoetry managers within the same class"
About which class are you talking?
Tkinter docs says: Never mix grid and pack in the same master window.
Please check your code again because you are using somewhere pack and grid.

Replace text/image of Tkinter logo

I have a question regarding the Tkinter logo which appears in the top left corner of the Tk window. I would like to know how to change the name, and eventually replace the whole thing with an alternate logo. Is this possible?
The tried to write to the following property that i saw on another thread but no luck:
master=Tk()
master.title("name")
#Note I have also tried master.title= "name"
Does anybody have the secret?
Daniel W.
I remembered reading about this years ago and yes the thread was still there, but looks like it takes an icon bitmap only http://www.daniweb.com/software-development/python/threads/63769/tk-logo-on-gui-window If you find another way please post it.
from tkinter import Tk
frame = Tk()
frame.geometry('300x300') #Frame size (width,height)
frame.title('Frame Title') # Frame title
frame.iconbitmap('logo.ico') # Frame logo
frame.mainloop()
its work for me!.

Default Image sizes in ttk.Label

Currently I'm using this snippet of code which seems pretty easy:
label = ttk.Label(mainframe)
image1 = PhotoImage(file='my_image.gif')
label['image'] = image1
label.grid(column=1, row=0)
However, if I edit the size of my_image.gif in photoshop, then run it again, the image gets stretched to the same size, and this seems to continue no matter how small I make the base image. This seems to suggest to me that the PhotoImage or something above it enforces a default size or specific minimum size. I cannot find any documentation to suggest that this is the case.
From here I found the help(PhotoImage) suggestion which I used. When in the python interpreter I run the help(PhotoImage) command and I found this:
height(self)
Return the height of the image.
type(self)
Return the type of the imgage, e.g. "photo" or "bitmap".
width(self)
Return the width of the image.
But it doesn't seem to provide me with an image sizing of any type either.
After searching all over and seeing no reference at all, i'm beginning to suspect that using images in a Label is for a specific purpose and I'm approaching this all wrong. All i'm trying to do is place a logo at the top of the window, but I want the logo to be limited in size so it doesn't take over the whole window.
Also of note is this question which seems to be lacking an answer but I too am curious if there is some documentation on it. Maybe I'm missing something obvious but I did check the python documentation and the http://www.tkdocs.com site for more information.
Apparently I made an error, but I have no clue what it was. In the end this was this code that did it for me:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title("ImageTest")
label = ttk.Label(root)
image1 = PhotoImage(file='my_image.gif')
label['image'] = image1
label.grid(column=1, row=0)
root.mainloop()
It's all working now as expected.

cget('image') method returning pyimage1 instead of the image name

I'm new to programming and I'm attempting to create an application using tkinter from python 3.3. In this application I'm using buttons containing images and I want to perform actions that depend on the kind of image that the buttons are containing. This is a simplified version of my program:
from tkinter import *
master=Tk()
c_black = PhotoImage(file="c_black.gif")
b=Button(master, image=c_black)
print(b.cget('image'))
master.mainloop()
Instead of
c_black
the console returns
pyimage1
And I have no idea why. I've been trying to figure it out for hours now. Perhaps there's a way to do it differently?
With cget() you can only retrieve the property as a string, so you need to store the reference to the PhotoImage object:
b = Button(...)
b.image = c_black
print(b.image.cget('file'))

Categories