How to display an image in tkinter using grid - python

I am trying to display an image to my GUI, through PhotoImage, however it is telling me that PhotoImage has no "grid" member.
I am using .grid() for all of my other widgets, like labels and buttons, so I can't use .pack(), if that would make a difference anyway. So, how could I display an image to my GUI with grids?
I don't know if code is necessary for this question, but
# it works by getting a random image from a list of files
Label(root, text=f"Enter a number between one and {len(files)}")
self.entry = Entry(root)
self.entry.grid()
Button(root, text="Submit", command=self.getEntry).grid()
Then, getEntry() is:
def getEntry(self):
PhotoImage(name="",
file=f{self.path}\\{self.showImage(self.entry.get())}).grid(row=1)
"""
showImage() just returns the correct file
(e.g: files[index] where index is the input)
"""

NOTE:
grid() is returning NoneValue, which means that your variable 'file' will be NoneValue.
To display an image in tkinter you'll need to do something like:
from PIL import Image, ImageTk
image = Image.open(image_path)
photo = ImageTk.PhotoImage(image)
label = Label(root, image = photo)
label.image = photo
label.grid(row=1)
# label.pack()
NOTE:
The PhotoImage class can read GIF and PGM/PPM images from files:
photo = PhotoImage(file="image.gif")
photo = PhotoImage(file="lenna.pgm")
If you need to work with other file formats, the Python Imaging
Library (PIL) contains classes that lets you load images in over 30
formats, and convert them to Tkinter-compatible image objects:
from PIL import Image, ImageTk
image = Image.open("lenna.jpg")
photo = ImageTk.PhotoImage(image)
You can use a PhotoImage instance everywhere Tkinter accepts an image
object.
An example:
label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()
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.

You have to use a widget that can support images. Typically a label, but button can also configure a button to show an image, as well as add images to text and canvas widgets.

Related

The background doesn't round the button tkinter

I am using tkinter to create a GUI. I use PIL to import an image as the background. Here is my code:
root = tk.Tk()
root.title("DFUInfo-v1")
img = ImageTk.PhotoImage(Image.open("background.jpg"))
l=Label(image=img)
l.pack()
root.configure(bg='white')
root.geometry("490x280")
In my app, buttons are rounded. But when I use the image, the background does not match the round buttons, here is the image:
Can somebody help me pls? Thanks
Here is how you can create rounded "buttons" in tkinter (what determines the visible shape is how the image looks):
from tkinter import Tk, Canvas
from PIL import Image, ImageTk
# use your images here
# open your images (my preference is to use `.open` before initialising `Tk`)
img = Image.open('rounded.png')
# resize to match window geometry
bg = Image.open('space.jpg').resize((500, 400))
# the function to call when button clicked
def func(event=None):
print('clicked')
root = Tk()
root.geometry('500x400')
# here are the converted images
photo = ImageTk.PhotoImage(img)
bg = ImageTk.PhotoImage(bg)
# from now on this will be the "root" window
canvas = Canvas(root, highlightthickness=0)
canvas.pack(fill='both', expand=True)
# add background
canvas.create_image(0, 0, image=bg, anchor='nw')
# create button and you have to use coordinates (probably can make
# custom grid system or sth)
btn = canvas.create_image(250, 200, image=photo, anchor='c')
# bind the "button" to clicking with left mouse button, similarly
# as `command` argument to `Button`
canvas.tag_bind(btn, '<Button-1>', func)
root.mainloop()
Most of the explanation is in the code comments, but note that the bound sequence works for the whole image but images are always square so you can click the button being outside of the visible part but only as far as the image goes, it is most certainly possible to create a button that doesn't have such issues but that requires some math
Important (suggestion):
I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.

Why can't my image load on my tkinter window?

I'm trying to add an image to my program but it's not working out, the code is correct as shown below, and the image i'm trying to open is in the same folder as the saved .py file.
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
root.title("Balance 0-21")
root.configure(width=400, height=200)
root.iconbitmap("C:/Users/user/Desktop/Projects/Balance 0-21/LogoCon.ico")
MasterCard = ImageTk.PhotoImage(Image.open("ten.png"))
MasterCardIMG = Label(image=MasterCard)
MasterCardIMG.grid(row=2, column=3)
root.mainloop()
try adding this after the MasterCardIMG Label creation (also for convention make the first letter lowercase as these aren't classes), I was having the same issue getting my images to show, I believe it has something to do with the label instance creation not being able to assign the image.
MasterCardIMG.image = MasterCard
(recommendation for convention)
masterCard = ImageTk.PhotoImage(Image.open("ten.png"))
masterCardIMG = Label(image=masterCard)
masterCardIMG.image = masterCard
masterCardIMG.grid(row=2, column=3)

How to use python Tkinter to iterate images?

How to use python Tkinter to iterate images?
import tkinter as tk
from PIL import ImageTk, Image
win = tk.Tk()
win.geometry('800x500') # set window size
win.resizable(0, 0) # fix window
images = ['01.jpg', '02.jpg', '03.jpg']
def next_img():
# show next image
for img in images:
img = Image.open(img)
img = ImageTk.PhotoImage(img)
panel = tk.Label(win, image=img)
panel.pack()
btn = tk.Button(text='Next image', command=next_img)
btn.pack()
win.mainloop()
But my panel doesn't show any images. I hope the panel waits me and I click the button to show next images. How to solve it.
The reason why your code doesn't display any images is a bit complicated. There are two factors working together:
Because you're creating your labels (the ones that you use to display the images) in a loop, you end up creating 3 labels and 3 buttons - one for each image. All of these are arranged below each other, so depending on the size of your images, some of them might be below the window's bottom edge. If you use small images, you'll see three "Next image" buttons in your window.
Tkinter images are garbage collected if you don't keep a reference to them in your python code. Since your loop overwrites the value of the img variable in each iteration, all images except the last one are garbage collected and aren't displayed.
To fix your code, first start by removing that loop. You don't need 3 labels and 3 buttons, and you don't need to load all 3 images immediately when the program starts either.
The code that loads and displays the image should be moved into the next_img function. You can update the label's image with the command panel['image'] = img.
In order to cycle through the list of images, it's easiest to use an iterator. You can turn your list of images into an iterator by calling images = iter(images). Then you can use the next function to get the next image from the iterator when you need it.
import tkinter as tk
from PIL import ImageTk, Image
win = tk.Tk()
win.geometry('800x500') # set window size
win.resizable(0, 0) # fix window
panel = tk.Label(win)
panel.pack()
images = ['01.jpg', '02.jpg', '03.jpg']
images = iter(images) # make an iterator
def next_img():
try:
img = next(images) # get the next image from the iterator
except StopIteration:
return # if there are no more images, do nothing
# load the image and display it
img = Image.open(img)
img = ImageTk.PhotoImage(img)
panel.img = img # keep a reference so it's not garbage collected
panel['image'] = img
btn = tk.Button(text='Next image', command=next_img)
btn.pack()
# show the first image
next_img()
win.mainloop()
This code will loop through the images once, and when the last image is reached, pressing the "Next image" button will have no effect. If you want to wrap around to the first image, you can itertools.cycle to create an infinitely looping iterator instead:
images = itertools.cycle(images)
Unfortunately, Tkinter is a little confusing and when placing an image in a label or button you will want to add on the line beneath
panel.photo = img
I'm not exactly sure why this works but it seems there are 2 values that take the image to display it.

Create a text over an image using python Tkinter

I am creating an Arduino interface on Sublime using python Tkinter..
I need to show a text over an image. Located in the middle of the screen (512, 200). I don't know how to do it using this library
import Tkinter as tk
from Tkinter import *
root = tk.Tk()
root.geometry("1024x574")
root.title("window")
photo = tk.PhotoImage(file= r"hi.gif")
cv = tk.Canvas()
cv.pack(side='top', fill='both', expand='yes')
cv.create_image(0, 0, image=photo, anchor='nw')
text=['my text']
root.mainloop()
Any suggestions?
You need to create a tk label widget and add your text to it. Then you need to use the tk label option compound=.
Taken directly from http://effbot.org/tkinterbook/label.htm:
"compound=
Controls how to combine text and image in the label. By default, if an image or bitmap is given, it is drawn instead of the text. If this option is set to CENTER, the text is drawn on top of the image. If this option is set to one of BOTTOM, LEFT, RIGHT, or TOP, the image is drawn besides the text (use BOTTOM to draw the image under the text, etc.). Default is NONE."
The following is a minimal but working example that accomplishes what you asked for:
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
image = Image.open('hi.gif')
tk_image = ImageTk.PhotoImage(image)
label = tk.Label(root, text='Some Plain Text', image=tk_image, compound='center')
label.pack()
root.mainloop()

Displaying a sequence of PIL images with Tkinter

I am generating PIL Image objects in a loop. I'd like to display these as they are generated with Tkinter.
How would I go about doing this?
You can create a TkInter window containing a Label, and each time you want to change the image, create a new ImageTk.PhotoImage from the old image and set the label's image property to the newly created PhotoImage. Example:
import Tkinter
import Image, ImageTk
root = Tkinter.Tk()
label = Tkinter.Label(root)
label.pack()
def change_image(image):
photoimage = ImageTk.PhotoImage(image)
label.config(image=photoimage)
root.mainloop()
Whenever you need to change the image, call change_image().

Categories

Resources