This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 4 years ago.
I am trying to display an image in a window. I tried it two methods, using classes and single snippet.
I am confused why this is showing correct output:
from Tkinter import *
from PIL import ImageTk, Image
root = Tk()
picture="path/image.jpg"
image = Image.open(picture).resize((350, 350), Image.ANTIALIAS)
print(image)
pic = ImageTk.PhotoImage(image)
panel = Label(root, image = pic)
panel.grid(sticky="news")
root.mainloop()
but not the below one?
from Tkinter import *
from PIL import ImageTk, Image
class DisplayImage():
def __init__(self, root):
self.root = root
def stoneImg(self, picture="path/default_image.png"):
image = Image.open(picture).resize((350, 350), Image.ANTIALIAS)
pic = ImageTk.PhotoImage(image)
panel = Label(self.root, image=pic)
panel.grid(sticky="news")
if __name__ == '__main__':
root = Tk()
DisplayImage(root).stoneImg()
root.mainloop()
The difference is that in your second example, the picture was referred to only by a local variable, which went away at the end of the function. Garbage collection works a bit weirdly in Tkinter, since all of the GUI-related objects exist in the embedded Tcl interpreter, outside of Python's control.
The simple solution is to add a line like panel.image = pic, so that a reference to the image exists for as long as the widget itself does.
Related
This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed last year.
I'm trying to load an image into tkinter, to use as a background image. The image is a GIF (originally JPG, but I heard that tkinter doesn't support that format) with the same dimensions as the window. Anyway, when I ran my code, it ran, but the tkinter window was empty! Here's my code for the window:
class Window(Tk):
def __init__(self):
super().__init__()
self.geometry("700x600")
self.resizable(False, False)
def background_img(self, img_path):
background_img = PhotoImage(file=img_path)
background_img_label = Label(self, image=background_img)
background_img_label.place(x=0, y=0)
window = Window()
img_path = "background.gif"
window.background_img(img_path)
window.mainloop()
Can you please tell me what I'm doing wrong? Thanks in advance.
As TDG said, the names background_img (function) and background_img (tkinter.PhotoImage) override each other. You should rename one.
This question already has an answer here:
displaying the selected image using tkinter
(1 answer)
Closed 4 years ago.
How do I select an image to show using dialog? I only can show an image when I know it's exact path. But I want to be like that dialog when you upload your photo to social networks or something. Now I have this code:
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
img = Image.open(r"images\photo1.jpg")
show_img = ImageTk.PhotoImage(img)
panel = Label(root, image=show_img)
panel.pack(side="bottom", fill="both", expand="yes")
root.mainloop()
You use the Tkinter FileDialog, let the user choose the image and use that location as string for your image http://effbot.org/tkinterbook/tkinter-file-dialogs.htm
This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 4 years ago.
I am trying to display an image in a window...seems simple enough right? Well I have a big bug!
I have this exact same code in one file:
import Tkinter
root = Tkinter.Tk()
canvas = Tkinter.Canvas(root)
canvas.grid(row = 0, column = 0)
photo = Tkinter.PhotoImage(file = '/Users/Richy/Desktop/1.gif')
image1 = canvas.create_image(0,0, image=photo)
root.mainloop()
It works.
I have this in part of a bigger file:
def officialPictureWindow(self):
t = Toplevel(self)
t.wm_title("Official Image")
self.__canvas3 = Canvas(t)
self.__canvas3.grid(row = 0, column = 0)
photo = PhotoImage(file = '/Users/Richy/Desktop/1.gif')
image1 = self.__canvas3.create_image(0,0, image=photo)
It doesn't work!
That function is called when someone presses a button on a menubar I have. All the other menubar buttons I have operate properly and show their windows. There's no images in the others though.
This gives no no error. Just a blank screen. Does anyone know why?
You need to keep an additional reference to photo so it doesn't get prematurely garbage collected at the end of the function. An Introduction to Tkinter explains further:
Note: When a PhotoImage object is garbage-collected by Python (e.g. when you return from a function which stored an image in a local variable), the image is cleared even if it’s being displayed by a Tkinter widget.
To avoid this, the program must keep an extra reference to the image object. A simple way to do this is to assign the image to a widget attribute, like this:
label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()
In your case, you could attach the image to your self variable, or maybe the canvas. It doesn't really matter, as long as it is assigned to something.
self.image = photo
#or:
self.__canvas3.image = photo
This question already has answers here:
Image resize under PhotoImage
(5 answers)
Closed 6 years ago.
I have an image that I display and I would like to resize (enlarge, actually) that image. Here's my code, using other SO questions, but I get no result - my image still has the same size. Resizing the button also does not change the image size.
I've tried the answers from this SO question: Image resize under PhotoImage but they won't work.
from Tkinter import *
root = Tk()
root.withdraw()
def cleanUp():
root.destroy()
def openWebsite():
print 'Will try to implement opening the website here.'
window = Toplevel(root)
window.protocol('WM_DELETE_WINDOW', cleanUp)
photo = PhotoImage(file="Header.pgm")
photo.zoom(2)
button = Button(window, image=photo, command=openWebsite)
button.pack()
root.mainloop()
PhotoImage.zoom() returns a new image, it does not modify the original image. Try rebinding photo like this:
photo = photo.zoom(2)
From the help:
zoom(self, x, y='') method of Tkinter.PhotoImage instance
Return a new PhotoImage with the same image as this widget
but zoom it with X and Y.
How can I add an image to a widget in tkinter?
Why when I use this code it does not work:
some_widget.config(image=PhotoImage(file="test.png"), compound=RIGHT)
but this does work?:
an_image=PhotoImage(file="test.png")
some_widget.config(image=anImage, compound=RIGHT)
Your image is getting garbage collected when you try to use it in the first version.
effbot is ancient, but here's good snippet:
You must keep a reference to the image object in your Python program, either by storing it in a global variable, or by attaching it to another object.
In the second version the image is declared at the global level.
Here's another example that would demonstrate this issue, that you would expect to also work, after all it's the same code just in a function
Doesn't work:
import tkinter as tk
from PIL import ImageTk
root = tk.Tk()
def make_button():
b = tk.Button(root)
image = ImageTk.PhotoImage(file="1.png")
b.config(image=image)
b.pack()
make_button()
root.mainloop()
Does work:
import tkiner as tk
from PIL import ImageTk
root = tk.Tk()
def make_button():
b = tk.Button(root)
image = ImageTk.PhotoImage(file="1.png")
b.config(image=image)
b.image = image
b.pack()
make_button()
root.mainloop()
Why? The variables in make_button are local to that function. Same idea if you run into this type of problem inside a class.