Python- tkinter: Opening One Another image in another window? - python

Hello I am doing a job that I need (from a tkinter window containing an image) call another window that contains another imagem.I tried the following:
from tkinter import*
def abrir1():
b =Tk()
imagen = PhotoImage(file= "F2.png")
la = Label(b,image =imagen)
la.pack()
def abrir2():
b =Toplevel()
imagen = PhotoImage(file= "F2.png")
la = Label(b,image =imagen)
la.pack()
a = Tk()
canvas = Canvas(a, bg ="black",width = 512,height =512)
canvas.pack()
imagem = PhotoImage(file = "E2.png")
a1 = canvas.create_image(256,256,image = imagem)
btu1 = Button(a,text ="Abri1!",command = abrir1)
btu1.place(x = 150,y=400)
btu2 = Button(a,text ="Abri2!",command = abrir2)
btu2.place(x = 300,y=400)
But when I press the first button ( btu1 ) it returns the following error message:
_tkinter.TclError: image "pyimage2" doesn't exist
And when when I press the second button ( btu2 ) does not happen error but does not show the image, only the new window is created ;
I've tried several ways including placing * with canvas and without canvas* ;

You have two problems in your code.
The first problem is that you are creating two instances of Tk. A tkinter program needs to have exactly one instance.
The second problem is that the image you are creating is saved as a local variable. When the function returns, the variable is garbage collected. When a tkinter image is garbage collected the image data is discarded even though the widget still exists.
A very basic search of the internet yields this page: http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm

Related

Yet Another tkinter Image Garbage Collection Issue - RESOLVED: wrong parameter type [duplicate]

I have a label with an image, and a button which should update the label / delete the image in the label, so I can put a new image into the same label via label.config.
I tryed to use something like that: whenever you click on the button the it should remove the image with label.config(image = None) but it doesnt work, if I load new images into the label the old ones are still there:
# here is the label initialized
global brand_preview
brand_preview = Label(root, image = None)
brand_preview.place(x = 10, y = 60)
# thats the button which have to clear the label image
self.top_brand = Button(root, text = "clear", bg = "snow3", command=clear_label_image)
self.top_brand.place(x = 550, y = 60)
# thats how I load a photoimage into the label
photoimg_brand = ImageTk.PhotoImage(im_thumb)
brand_preview.image = photoimg_brand
brand_preview.config(image = photoimg_brand)
# Thats how the button works
def clear_label_image():
brand_preview.config(image = None)
brand_preview.image = None
All I want now that if we I click the Button the brand_preview loses the image / the image gets deleted
EDIT:
The main issue is solved, but that only works if the button only has to delete the image. If I want to delete and add a new one it doesnt work
def clear_label_image():
brand_preview.config(image = "")
photoimg_brand = ImageTk.PhotoImage(im_thumb)
brand_preview.image = photoimg_brand
brand_preview.config(image = photoimg_brand)
You're very close - the image parameter just needs an empty string rather than None.
def clear_label_image():
brand_preview.config(image='')
After some Googling, I found this solution
def clear_label_image():
#brand_preview.config(image = None)
brand_preview.image.blank()
brand_preview.image = None
This definitely clears the image from the button. I haven't tried changing to a new image.
I just copied it from the Web, and it worked. I created the image with
photoimg_brand = tk.PhotoImage(file='/usr/share/httpd/icons/world1.gif')
I did this with python 2.7, and my only import was import Tkinter as tk
If you are using label to show the image then you can do this:
label.pack_forget()
label should be global

What is difference between label.configure(image=value) and label.image=value?

from tkinter import *
from tkinter.filedialog import *
wd = Tk()
def func_open():
fname = askopenfilename(parent=wd, filetypes=( ("gifs","*.gif"), ("alls","*.*") ))
photo1 = PhotoImage( file = fname )
pLabel.configure( image = photo1 )
pLabel.image=photo1
temp = PhotoImage()
pLabel = Label(wd, image = temp )
pLabel.pack(expand=1)
mainMenu = Menu(wd)
wd.config(menu=mainMenu)
fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Open",command=func_open)
wd.mainloop()
2 lines of code above,
pLabel.configure( image = photo1 )
pLabel.image=photo1
if i remove one of these, func_open() can't print image file.
To me, it seems like both line says same thing,
as pLabel.configure( image = photo1 ) put image through argument photo1
and pLabel.image=photo1 is directly put photo1 to pLabel's image.
I tried search that .configure() method but i couldn't get any understandable imformation.
Widgets have internal configuration options that control its appearance and behavior. When you call the configure method, you are giving one of those options a value. Thus, pLabel.configure( image = photo1 ) sets the image option to the value of the photo1 variable.
When you do pLabel.image=photo1, you are creating a new instance variable on the pLabel python object named image and setting it to the value of the photo1 variable. The underlying tkinter widget has no knowledge of this attribute, and isn't affected by this attribute.
This is a common idiom for saving a reference to the image. The use of the word image is completely arbitrary, using pLabel.xyzzy=photo1 or pLabel.save_this=photo1 would solve the exact same problem.
For more information see Why does Tkinter image not show up if created in a function?

Images not getting applied on the button in Tkinter

The following project is supposed to show a message when clicking a certain colored button. But, whenever I execute the program it shows blank(white) buttons in the correct alignment, etc. Due to some reason the images are not loaded.
In future, I plan to add different images hence testing with colored image created in Paint and not in-built commands to show the color.
I will add the result below after the code.
Edit: All images are 100x100 pixels created in Microsoft Paint.I have tried other modules like PIL but to no avail.
# importing the module
import tkinter
import tkinter.messagebox
from tkinter import *
# importing the module
# initialising tkinter
class window(Frame):
def __init__(self,master = None):
Frame.__init__(self,master)
self.master = master
# initialising tkinter
# creating the window
root = Tk()
app = window(root)
root.geometry("350x350")
# creating the window
# colours
WHITE = (255,255,255)
BLACK = (0,0,0)
BLUE = (0,0,255)
RED = (255,0,0)
# colours
# image
red_image = "red.png"
blue_image = "blue.png"
yellow_image = "yellow.png"
green_image = "green.png"
# image
# creating a button function
def create_button(x,y,color,color2,picture):
click = Button(root, image = PhotoImage(picture), width= 150, height=150, command = lambda : tkinter.messagebox.showinfo( "Hello Python", "This is " + color))
click.image = PhotoImage(picture)
click.grid( row = x, column = y)
# creating a button function
create_button(0,0,'red','pink',red_image)
create_button(0,2,'blue','lightblue',blue_image)
create_button(2,0,'green','lightgreen',green_image)
create_button(2,2,'yellow','lightyellow',yellow_image)
# starting the widget
root.mainloop()
# starting the widget
There are two issues in your code:
You passed filename to PhotoImage() without using file keyword: PhotoImage(picture) should be PhotoImage(file=picture)
You did not keep the reference of the image assigned to button, but another instance of image
Below is the updated create_button() function that fixes the issues:
def create_button(x, y, color, color2, picture):
image = PhotoImage(file=picture)
click = Button(root, image=image, width=150, height=150, command=lambda: tkinter.messagebox.showinfo("Hello Python", "This is "+color))
click.image = image
click.grid(row=x, column=y)
For adding image in Button you have not use appropriate keywords.
Here is a simple example for you to add image in button
from tkinter import *
from tkinter.ttk import *
# creating tkinter window
root = Tk()
# Adding widgets to the root window
Label(root, text = 'Image adding', font =( 'Verdana',15)).pack(side = TOP, pady = 10)
# Creating a photoimage object to use image
photo = PhotoImage(file = "C:\Gfg\circle.png")
# here, image option is used to
# set image on button
Button(root, text = 'Click Me !', image = photo).pack(side = TOP)
root.mainloop()
I think it may help you

Tkinter image not showing

I made this piece of code:
from tkinter import *
from PIL import ImageTk, Image
import sys
import getnew
class startUp:
def __init__(self, master):
master.title("Tag checker")
master.resizable(False, False)
img1 = ImageTk.PhotoImage(Image.open("images/ss.png"))
cercaImg = Label(master, image = img1)
cercaImg.bind("<Button-1>",clicka)
cercaImg.grid(row=0,column=0)
img2 = ImageTk.PhotoImage(Image.open("images/opz.png"))
opzioniImg = Label(master, image = img2)
opzioniImg.grid(row=0,column=1)
img3 = ImageTk.PhotoImage(Image.open("images/exit.png"))
esciImg = Label(master, image = img3)
esciImg.bind("<Button-1>",(master.destroy and quit))
esciImg.grid(row=0,column=2)
def clicka(event):
print('ciaooo')
x = getnew.getSchools()
print(x[0][0],x[0][1],x[0][2])
root = Tk()
st = startUp(root)
root.mainloop()
The point is to have 3 images that, when clicked, execute a function, but he images don't show up. They do appear as size and 'clickable' zone and they execute the function, but the image as it is doesn't show up.
What am I doing wrong here ?
From tkinter docs on PhotoImage:
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.
The reason to do so is :
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.
Hence for your program:
img1 = ImageTk.PhotoImage(Image.open("images/ss.png"))
cercaImg = Label(master, image = img1)
cercaImg.image = img1 # Keep a reference
Similarly for the other images as well.

python error "unknown option "1": must be moveto or scroll" tkinter canvas

I am trying to create a image viewing program using tkinter, everything works fine except: I want to have a list of all the images in the directory the user chose, this list should be displayed on a canvas, with a horizontal scrollbar attached to it, I've seen other people on this page had kind of the same problem and someone said to use a frame, that works but when I want to use the scrollbar, I get the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in/
__call__
return self.func(*args)
File "/usr/lib/python3.4/tkinter/__init__.py", line 1549, in xview
res = self.tk.call(self._w, 'xview', *args)
_tkinter.TclError: unknown option "1": must be moveto or scroll
>>>
I can't make head or tail out of that, so please, any help appreciated, here is the actual code:
from tkinter import *
from PIL import Image,ImageTk
import os
import time
#next image
def Next():
i += 1
global img,i
print(i)
display_images(data[i])
#previous image
def Previous():
i -= 1
global img,i
print(i)
display_images(data[i])
#list of images on canvas
def show_images():
global photoButtons,imgFile,imOpen,imgFoto,resized,photolist
j = 0
for number in data:
print(">>>",number)
imOpen.append(Image.open(data[j]))
imgFile.append(imOpen[j])
resized.append(imgFile[j].resize((50,50),Image.ANTIALIAS))
imgFoto.append(ImageTk.PhotoImage(resized[j]))
photoButtons.append(Button(photolist, text=j,/
image=imgFoto[j],command=display_images(data[j]),width=50,/
height = 50))
photoButtons[j].pack(side=RIGHT)
j += 1
#display selected image
def display_images(image_name):
img = Image.open(image_name)
size = img.resize((700,500),Image.ANTIALIAS)
photoviewer.image = ImageTk.PhotoImage(size)
photoviewer.create_image(0,0, image=photoviewer.image,anchor='nw')
# END DEF's
global i
i=0
#root
root = Tk()
#root size
root.geometry("1000x720+0+0")
#canvas for displaying image
photoviewer = Canvas(root, width=700, height=500)
photoviewer.grid(row = 0, column = 0)
photoviewer.place(x=295, y=215,)
#frame (ive got this from another page of stack overflow)
frame=Frame(root,width=300,height=300)
frame.grid(row=0,column=0)
#canvas for displaying list of images
photolist = Canvas(frame, width=395, height=50)
#scrollbar
scrl=Scrollbar(frame,orient=HORIZONTAL)
scrl.pack(side=BOTTOM,fill=X)
scrl.config(command=photolist.xview)
photolist.pack(side=TOP)
imgFile = []
imOpen=[]
imgFoto=[]
resized = []
#get the directory with the images from the user
data = os.listdir()
print(data)
cd = input("change directory to: ")
while cd != "x":
os.chdir(cd)
data = os.listdir()
print(data)
cd = input("change directory to: ")
#end
#creating button for next image
nxt=Button(root,text=">",command= Next)
#creating button for previous image
prvs=Button(root,text="<",command= Previous)
photoButtons = []
show_images()
root.mainloop()
the idea is that the user should choose a directory then after they pressed 'x' the program should call show_images, which should display all the images in that directory on a canvas with a scrollbar attached to it, the user should then be able to pick and choose between them, and also choose next and previous, however, the scrollbar doesn't work.
To connect a scrollbar to a widget you must do two things: tell the widget which scrollbar to interact with (via xscrollcommand and/or yscrollcommand), and tell the scrollbar which widget to scroll (with the command attribute. You are neglecting to do the first part.
Add the following somewhere after creating the scrollbar:
photolist.configure(xscrollcommand=scrl.set)
Note: you don't need to go to the trouble of embedding a frame in the canvas if all you want to do is scroll some images. You can directly create images on the canvas. The advantage that the frame gives you is you can use pack so you don't have to calculate the coordinates of where to place the image, but it adds a lot of complexity. Since you're placing the images side-by-side, it's easy to compute the x/y coordinates for each image.

Categories