Python TKinter row of images background [duplicate] - python

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 5 years ago.
Issue:
Why does this code not produce a row of 5 images? Ive tried different combinations of pack, place and grid but I can't resolve the issue. I think the current issue is that the backgrounds of images are overlapping each other but i tried reversing the loop to solve the issue and it changed nothing.
Code:
import base64
try:
# Python2
import Tkinter as tk
from urllib2 import urlopen
except ImportError:
# Python3
import tkinter as tk
from urllib.request import urlopen
root = tk.Tk()
root.title("display a row of images")
root.geometry("%dx%d+%d+%d" % (1000, 600, 0, 0))
images = ["C20KEWS", "ANYT6mV", "b3vwblN", "7Y1MG17", "ouXXEMi"]
for image in images:
imgbytes = urlopen("http://i.imgur.com/"+image+".gif").read()
imgb64 = base64.encodestring(imgbytes)
imageTK = tk.PhotoImage(data=imgb64)
imageContainer = tk.Frame(root,
bg="black",
width=200,
height=600
)
print images.index(image)*200, 0
imageContainer.place(x=images.index(image)*200, y=0, width=200, height=600)
imageLabel = tk.Label(imageContainer, image=imageTK, bg='black')
imageLabel.pack(side=tk.LEFT)
root.mainloop()

imageTk is overwritten, and garbage collected. They should be there to be displayed.
Save those ImageTk objects to prevent that.
root = tk.Tk()
root.title("display a row of images")
root.geometry("%dx%d+%d+%d" % (1000, 600, 0, 0))
images = ["C20KEWS", "ANYT6mV", "b3vwblN", "7Y1MG17", "ouXXEMi"]
photo_images = [] # <--------
for image in images:
imgbytes = urlopen("http://i.imgur.com/"+image+".gif").read()
imgb64 = base64.encodestring(imgbytes)
imageTK = tk.PhotoImage(data=imgb64)
photo_images.append(imageTK) # <-----------
imageContainer = tk.Frame(root,
bg="black",
width=200,
height=600
)
print images.index(image)*200, 0
imageContainer.place(x=images.index(image)*200, y=0, width=200, height=600)
imageLabel = tk.Label(imageContainer, image=imageTK, bg='black')
imageLabel.pack(side=tk.LEFT)
root.mainloop()

Related

display image by clicking a button tkinter [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 9 months ago.
I am trying to display an image in a window with tkinter, by clicking a button.
I created this function :
def tabuim():
tabu = Frame(win, width=600, height=400)
tabu.pack()
tabu.place(anchor='center', relx=0.8, rely=0.35)
img2 = ImageTk.PhotoImage(Image.open("Tabu.jpg"), master=win)
label2 = Label(tabu, image = img2, borderwidth=3, relief="solid")
label2.pack()
with this button :
button2 = Button(win, text = 'Tabu Route Solution', command = tabuim)
button2.place(relx = 0.5, rely = 0.5)
But it partially works. It only show a border without my image...
Thanks for you help
The following example displays a background image in a frame:
Import tkinter
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
Create a photoimage object of the image in the path
image1 = Image.open("<path/image_name>")
test = ImageTk.PhotoImage(image1)
label1 = tkinter.Label(image=test)
label1.image = test
Position image
label1.place(x=<x_coordinate>, y=<y_coordinate>)
root.mainloop()
This an example you can do as instead of resizing before loading the page you could resize after the image is loaded.

Why is my image not showing up in tkinter canvas [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 2 years ago.
I am trying to make this UI from a stimulus as part of an assessment for school. I tried to import the provided school logo and banner on the top frame of the page and put images on the canvas but have yet to achieve any results. When I run the code, the pictures won't load at all. The code that I was working with is as followed:
from tkinter import *
import random
import time
import sqlite3
from tkinter import simpledialog
from tkinter import messagebox
from tkcalendar import *
from tkinter import ttk
import math
from PIL import Image, ImageTk
import winsound
#-------------Frames setup--------------------------
class VendingApp(Tk):
def __init__(self):
Tk.__init__(self)
self._frame = None
self.switch_frame(Home)
def switch_frame(self, frame_class):
#Destroys current frame and replaces it with a new one.
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self._frame.pack()
####-----------------------Home page---------------------------
class Home(Frame):
def __init__(self, master):
Frame.__init__(self, master)
topFrame = Frame(self,width = 1024, height = 100, bd = 2, bg = "black")
topFrame.pack()
canvas_for_logo = Canvas(topFrame, height=100, width=100, bg = 'green') ##logo image
canvas_for_logo.grid(row=0, column=0, sticky='ne')
img_logo = Image.open("pic/sitelogo.png")
img_logo = img_logo.resize((40,40), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img_logo)
canvas_for_logo.create_image(0, 0, anchor=NW, image=logo)
canvas_for_banner = Canvas(topFrame, bg='red', height=100, width=924) #banner image
canvas_for_banner.grid(row=0, column=1, sticky='nw')
img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((40,40), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)
MidFrame = Frame(self,width = 1024, height = 628, bd = 2)
MidFrame.pack()
MidFrame.grid_propagate(False)
BottomFrame = Frame(self,width = 1024, height = 50, bd = 2, bg = "black")
BottomFrame.pack()
BottomFrame.grid_propagate(False)
if __name__ == "__main__":
root = VendingApp()
#Sets the size of the window
root.geometry("1024x768")
#Renames the TITLE of the window
root.title("Vending machine")
root.geometry("1024x768")
root.resizable(False, False)
root.mainloop()
I decided to make a separate file to test if the image would load without class, and it did. Codes are as followed:
from tkinter import ttk
from tkinter import*
import time
from PIL import Image, ImageTk
root = Tk()
canvas_for_logo = Canvas(root, height=100, width=100)
canvas_for_logo.pack()
img = Image.open("pic/sitelogo.png")
img = img.resize((105,105), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img)
canvas_for_logo.create_image(0, 0, anchor=NW, image=logo)
canvas_for_banner = Canvas(root, bg='red', height=100, width=924) #banner image
canvas_for_banner.pack()
img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((924,100), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)
root.mainloop()
Can someone please tell me what I did wrong? All replies are much appreciated. Thank you.
This is a typical Tkinter bug. I don't want to go into details cause I don't fully understand why it happens either, but it has something to do with the garbage collector and the fact that it doesn't consider the objects you have created for storing those images like being in use, so it deletes them; or something like that.
Luckily, it has an easy solution: you can either create an internal list variable, let say, self._images that stores each image you are using, something like:
self._images = list()
(...)
self._images.append(logo)
(...)
self._images.append(banner)
Or, you could assign to each canvas instance an attribute image (or img, it doesn't really matters) that stores the image instance it is going to carry. In your code, it will look similar to:
canvas_for_logo.image = logo
(...)
canvas_for_banner.image = banner
This way, you can avoid the garbage collector deleting what it shouldn't, cause now it acknowledges that this instances are being in use.

How to make background Transparent in TKinter by converting Label widget into Canvas widget?

I have a code that is working perfectly but it's not giving me transparent background, (here is the image ) after a research on web, I found the solution by using canvas widget, we can us images with transparent background.
Here is my code,
import tkinter as tk
from PIL import Image, ImageTk
def work(progress=1):
if progress > 300: # define the width by yourself
return
tmp_images = ImageTk.PhotoImage(progress_images.resize((progress, 10))) # the image size
lb.image = tmp_images # keep reference
lb["image"] = tmp_images # change the image
root.add = root.after(100, work, progress+10) # define the amplitude by yourself
root = tk.Tk()
progress_images = Image.open("path.png")
lb = tk.Label(root, bg="black")
lb.pack(side="left")
work()
root.mainloop()
but I am confused how to change Label widget into Canvas ? can anyone help me please ? I am noob in Tkinter still!!!
You can use canvas.create_text(...) to replace the labels and then use canvas.itemconfig(...) to update the labels. I got this from an other stack over flow question
reference link :-
add label ..
Below is a modified code using Canvas:
import tkinter as tk
from PIL import Image, ImageTk
def work(progress=10):
if progress > 300: # define the width by yourself
return
canvas.image = ImageTk.PhotoImage(progress_images.resize((progress, 30))) # the image size
canvas.itemconfig(pbar, image=canvas.image) # update image item
root.add = root.after(100, work, progress+10) # define the amplitude by yourself
root = tk.Tk()
progress_images = Image.open("path.png")
canvas = tk.Canvas(root, width=300, height=30, bg='black', highlightthickness=0)
canvas.pack()
pbar = canvas.create_image(0, 0, anchor='nw') # create an image item
work()
root.mainloop()

RuntimeError: Too early to create image [duplicate]

This question already has an answer here:
Python Tkinter Error, "Too Early to Create Image"
(1 answer)
Closed 4 years ago.
I am trying to create an image library and to call an image from that image library in tkinter. But this code gives me an error:
This is the image library file img.py:
from tkinter import *
food_0001 = PhotoImage(file='food_0001.gif')
food_0002 = PhotoImage(file='bg.gif')
This is the file intended to open images stored in img.py:
from tkinter import *
import img
window = Tk()
window.title('image')
canvas = Canvas(window, width = 800, height = 800)
canvas.pack()
canvas.create_image(0,0, anchor=NW, image=food_0001)
window.mainloop()
It is because PhotoImage() can only be called after creation of Tk().
Suggest to rewrite img.py to create PhotoImage() only when it is needed. Below is a sample way to do it:
from tkinter import *
imagelist = {
'food_0001': ['food_0001.png', None],
'food_0002': ['bg.png', None],
}
def get(name):
if name in imagelist:
if imagelist[name][1] is None:
print('loading image:', name)
imagelist[name][1] = PhotoImage(file=imagelist[name][0])
return imagelist[name][1]
return None
Then modify your main program to cater the change:
from tkinter import *
import img
window = Tk()
window.title('image')
canvas = Canvas(window, width=800, height=800)
canvas.pack()
canvas.create_image(0, 0, anchor='nw', image=img.get('food_0001'))
window.mainloop()
Of cause there are many other ways to do it and it depends on your imagination.

Tkinter and PIL error

I am trying to get a .gif animation to work next to a picture with buttons on it. but i seem to be having a issue, I am importing these modules
"import Tkinter" and "from PIL import Image, ImageTk, ImageSequence"
But, as soon as I make "import Tkinter"---"from Tkinter import *"
It says Tkinter is not defined, I have searched.. and searched.... and I cannot for the death of me find a solution.
I have to use "from Tkinter import *" because I don't know where to find the spesifics for a substetute for " * " I also need to use "Label", "bg" and "relief"
here is my code:
import Tkinter
from PIL import Image, ImageTk, ImageSequence
class App:
def __init__(self, parent):
self.parent = parent
self.canvas = Tkinter.Canvas(parent, width = 400, height = 500)
self.canvas.pack()
self.sequence = [ImageTk.PhotoImage(img)
for img in ImageSequence.Iterator(
Image.open(
r'C:\Users\Damian\Pictures\Gif folder\Originals\Bunnychan.gif'))]
self.image = self.canvas.create_image(200,200, image=self.sequence[0])
self.animating = True
self.animate(0)
def animate(self, counter):
self.canvas.itemconfig(self.image, image=self.sequence[counter])
if not self.animating:
return
self.parent.after(33, lambda: self.animate((counter+2) % len(self.sequence)))
root = Tkinter.Tk()
root.title('App')
app = App(root)
root.mainloop()
I have another piece that I am going to merge with this code:
import webbrowser
from Tkinter import *
from PIL import ImageTk,Image
Url1 = 'https://www.nedbank.co.za'
Url2 = 'https://www.facebook.com'
def openUrl1():
webbrowser.open(Url1, 2)
def openUrl2():
webbrowser.open(Url2, 2)
root = Tk()
root.title('App')
root.minsize(width = 400, height = 400)
root.maxsize(width = 400, height = 400)
image = Image.open("C:\\Users\\Damian\\Pictures\\Lores.png")
photo = ImageTk.PhotoImage(image)
label = Label(image = photo)
label.image = photo
label.place(x = 0, y = 0)
color1 = 'white'
button1 = Button(
text = color1,
bg = color1,
relief = "raised",
width = 220,
height = 85,
command = openUrl1
)
Original = Image.open("C:\\Users\\Damian\\Pictures\\NedbankLogoNew.png")
im_pm = ImageTk.PhotoImage(Original)
button1.config(image = im_pm)
button1.place(x = 0, y = 0)
root.mainloop()
The recommended way to import tkinter is this:
import Tkinter as tk
Once you do that, you use tkinter as you normally would, but you need to prepend tk. to all of the widgets and constants. You can do import Tkinter, of course, but that means you have to prefix everything with Tkinter. which is a bit too wordy IMO.
For example:
import Tkinter as tk
root = tk.Tk()
label = tk.Label(root, relief=tk.RAISED)
...
Personally I don't recommend using the constants. You can just use a string (eg: relief="raised", sticky="nsew", etc.), which gives exactly the same results.

Categories