Trouble adding Images into a Gui using tkinter - python-3.x

OK so i am trying to make a program that displays an image when pressing a button, and i am having trouble getting the images into the program
this is my full code:
# Nicolas Bart
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import *
window = tk.Tk()
window.title('Bad Meme Generator')
window.geometry('500x500')
window.configure(bg='saddle brown')
meme_label = tk.Label(window, text='PRESS BUTTON FOR BAD MEMES:',
fg='blue4', bg='brown4', font=('comicsans', '20'))
meme_label.grid(pady=25, padx=25, column=0, row=0)
def button_command():
meme_window = tk.Tk()
meme_window.title('I Warned You')
meme_window.grid()
image = Image.open('pexels-photo-247932.jpg')
photo = ImageTk.PhotoImage(image)
label = tk.Label(meme_window, image=photo)
label.image = photo
label.place(x = 0, y = 0)
button = tk.Button(window, text='Dont Do It!', command=button_command,
padx=100, pady=75, font=('comicsans', '20'),
bg='brown4', fg='blue4')
button.grid(column=0, row=1)
warning_label = tk.Label(window, text="Really shit tier memes incoming:",
bg='brown4', fg='blue4',
font=('comicsans', '20'))
warning_label.grid(pady=75)
window.mainloop()
every time i run this program, when i press the button to open the image, it gives the error "AttributeError: type object 'Image' has no attribute 'open'"
the specific part of the program that is giving the error is:
def button_command():
meme_window = tk.Tk()
meme_window.title('I Warned You')
meme_window.grid()
image = Image.open('pexels-photo-247932.jpg')
photo = ImageTk.PhotoImage(image)
label = tk.Label(meme_window, image=photo)
label.image = photo
label.place(x = 0, y = 0)
any help would be appreciated. Thank you :)

This is a good example of why you shouldn't do from tkinter import *. Tkinter has an Image class, so by doing this import after importing Image from PIL you overwrite the PIL class with the tkinter class.
Since you're already importing tkinter the preferred way (import tkinter as tk), you don't need to import tkinter a second time. You need to remove the statement from tkinter import *.
You also make the mistake of creating more than one instance of Tk. I don't know if it contributes to the problem or not, but it's not something you should be doing. If you need additional windows then you should create instances of Toplevel.

Related

How to embed a base64 image into python 3 guizero/tkinter?

I am trying to embed a base64 image into either a box or the picture widget so my application requires less files. I found a way to do it with plain tkinter at Base64 string to image in tkinter answered by Bryan Oakley and I updated the code to work with python 3.
What they did
import tkinter as tk
IMAGE_DATA = '''
R0lGODlhEAAQALMAAAAAAP//AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAA\nAAAAACH5BAEAAAIALAAAAAAQABAAQAQ3UMgpAKC4hm13uJnWgR
TgceZJllw4pd2Xpagq0WfeYrD7\n2i5Yb+aJyVhFHAmnazE/z4tlSq0KIgA7\n
'''
root = tk.Tk()
image = tk.PhotoImage(data=IMAGE_DATA)
label = tk.Label(root, image=image, padx=20, pady=20)
label.pack()
root.mainloop()
What I've tried
import tkinter as tk
from guizero import *
import base64
app= App()
#the same image they used for testing
IMAGE_DATA = '''
R0lGODlhEAAQALMAAAAAAP//AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAA\nAAAAACH5BAEAAAIALAAAAAAQABAAQAQ3UMgpAKC4hm13uJnWgR
TgceZJllw4pd2Xpagq0WfeYrD7\n2i5Yb+aJyVhFHAmnazE/z4tlSq0KIgA7\n
'''
box=Box(app,width=app.width,height=app.height)
box.bg='gray'
#button=PushButton(app, image=IMAGE_DATA)
#image = Picture(box, image=IMAGE_DATA)
#picText = Text(box, tk.data=IMAGE_DATA)
#Pure tkinter
'''
image = tk.PhotoImage(data=IMAGE_DATA)
label = tk.Label(box, image=image, padx=20, pady=20)
label.pack()
'''
app.display()
What I used
https://lawsie.github.io/guizero/ (module)
https://base64.guru/converter/encode/image (converts images to base 64)
The image option requires an instance of the PhotoImage class from tkinter. So, create an instance, and pass that to guizero widget.
image = tk.PhotoImage(data=IMAGE_DATA)
button=PushButton(app, image=image)

Display video size on label tkinter

The below code displays video on the label. But, problem is that, it is displayed in a very zoom (large) manner. I want to resize it to display correctly on label. When I use the option image=image.resize(), I get an error
ValueError: cannot resize this array: it does not own its data
import tkinter as tk, threading
import imageio
from PIL import Image, ImageTk
video_name = "e.mp4"
video = imageio.get_reader(video_name)
#video = video.resize(20,20)
def stream(label):
for image in video.iter_data():
frame_image = ImageTk.PhotoImage(Image.fromarray(image))
label.config(image=frame_image)
label.image = frame_image
root = tk.Tk()
my_label = tk.Label(root, width=500,height=500)
my_label.place(x=0,y=0)
thread = threading.Thread(target=stream, args=(my_label,))
thread.daemon = 1
thread.start()
root.mainloop()
You can call resize() on the return image of Image.fromarray(image):
frame_image = ImageTk.PhotoImage(Image.fromarray(image).resize((100,100)))

darken the whole tkinter window

I'm programming a game sa my graduation project in school. Once the manager closes the game, I want the other users to have a pop up that the game is ended and a button to click on in order to continue.
I want the whole window (with all the widgets) to get darker (not totally black but darker). Everything besides the pop up and the "continue" button
Enyone has a clue what I can do? I searched on the Internet and found nothing :/
Not able to use ImageGrab on linux, here is my solution:
import tkinter as tk
import numpy as np
import time
import pyscreenshot as ImageGrab
from PIL import Image, ImageTk
def grab(widget):
box = (widget.winfo_rootx(), widget.winfo_rooty(), widget.winfo_rootx()+widget.winfo_width(), widget.winfo_rooty()+widget.winfo_height())
grab = ImageGrab.grab(bbox=box)
return grab
def darken(widget):
widget.overlay = ImageTk.PhotoImage(Image.fromarray(np.asanyarray(grab(widget))//2))
cvs = tk.Canvas(widget, width=widget.winfo_width(), height=widget.winfo_height())
cvs.place(x=0,y=0)
cvs.create_image(0, 0, anchor='nw', image=widget.overlay)
return cvs
root = tk.Tk()
def apply_dark():
cvs = darken(root)
b = tk.Button(root, text='Ok')
def d():
cvs.destroy()
b.destroy()
b.config(command=d)
b.place(x=50, y=10)
tk.Label(root, text='Label1').grid(row=0, column=0)
tk.Label(root, text='Label2').grid(row=0, column=1)
tk.Button(root, text='Button1').grid(row=1, column=0)
tk.Button(root, text='Darken', command=apply_dark).grid(row=1, column=1)
root.mainloop()
Fiddle around with this code. Of course this is in fact just a quick bodge (non-reliable, inefficient), but still - works for me.
Hope that's helpful!

How to fix this syntax error with the while loop

I am trying to make it so that when you close the tinker GUI another one opens and this process repeats
I have tried this while command but it says invalid syntax.
from tkinter import *
root = Tk()
photo = PhotoImage(file="scary.png")
label = Label(root, image=photo)
label.pack()
root.mainloop()
while 2 > 1
You can try this for infinite times opening the tkinter window:
from tkinter import *
from PIL import Image, ImageTk
image = Image.open("scary.png")
photo = ImageTk.PhotoImage(image)
while True:
root = Tk()
label = Label(root, image=photo)
label.pack()
root.mainloop()
EDIT
I've added code for opening image of any format in Tkinter, for that you have to install the required package with pip install pillow (PIL package)
I've tested it without image, it is working. Hope it helps !
You were missing the loop body.
Now it has but since 2 > 1 is always true it's an infinite loop.
from tkinter import *
root = Tk()
photo = PhotoImage(file="scary.png")
label = Label(root, image=photo)
label.pack()
root.mainloop()
while 2 > 1:
pass

tkinter can not display the image

I want to put an image(light.gif) in the button of tkinter.
However, the image is not shown and only a small transparent box appears at the specified position.
My Code is
from tkinter import* #To use Tkinter
from tkinter import ttk #To use Tkinter
from tkinter import messagebox #To use Tkinter
import tkinter.font # To use Font
win = Tk()
win.title("Main Control")
win.geometry('450x400+100+300')
win.resizable(0,0)
def a1():
a1 = Toplevel()
a1.title("a1")
a1.geometry('450x350+560+100')
a1.resizable(0,0)
lignt_sensor_image=PhotoImage(file = 'light.gif')
light_sensor_button=Button(a1,width=15,height=8)
light_sensor_button.place=(x=275,y=200)
a1.mainloop()
newa1 = Button(win, text='A1', font=font1, command=a1, height = 5, width = 10)
newa1.place(x=50, y=30)
win.mainloop()
Please help me
You must keep a reference to the image; as it is created in a function, it was destroyed the moment the function exited.
There also were typos in your code that prevented it from running.
The following shows your image in the popup window.
import tkinter as tk
from tkinter import PhotoImage
def spawn_toplever_a1():
global light_sensor_image # <- hold the image in the global variable, so it persists
a1 = tk.Toplevel() # do not name your variables the same as your function
a1.title("a1")
a1.geometry('450x350+560+100')
light_sensor_image = PhotoImage(file='light.gif')
light_sensor_button = tk.Button(a1, image=light_sensor_image, text="my image", compound="center")
light_sensor_button.place(x=275,y=100) # <-- typo - removed '=' sign
# <-- removed call to mainloop
light_sensor_image = None # declare variable to hold the image
win = tk.Tk()
win.title("Main Control")
win.geometry('450x400+100+300')
win.resizable(0,0)
newa1 = tk.Button(win, text='A1', command=spawn_toplever_a1, height = 5, width = 10)
newa1.place(x=50, y=30)
win.mainloop()

Resources