Hey I'm following a tutorial, https://www.youtube.com/watch?v=a1Y5e-aGPQ4 , and I can't get it to work properly. I'm trying to add an image when you press on a menu button:
from tkinter import *
from PIL import *
class Window(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.init_Window()
def init_Window(self):
self.master.title("GUI")
self.pack(fill =BOTH, expand=1)
#quitButton = Button(self, text = "Quit", command = self.client_exit)
#quitButton.place(x=0,y=0)
menu = Menu(self.master)
self.master.config(menu=menu)
file=Menu(menu)
file.add_command(label='Save',command= self.client_exit)
file.add_command(label='Exit',command= self.client_exit)
menu.add_cascade(label='File',menu=file)
edit = Menu(menu)
edit.add_command(label='Show Image', command=self.showImg)
edit.add_command(label='Show Text', command=self.showTxt)
menu.add_cascade(label='Edit',menu=edit)
def showImg(self):
load = Image.open('Pic.png')
render = ImageTk.PhotoImage(load)
img = Label(self, image=render)
img.image = render
img.place(x=0,y=0)
def showTxt(self):
text = Label(self,text='Hey')
text.pack
def client_exit(self):
exit()
root = Tk()
root.geometry("400x300")
app = Window(root)
root.mainloop()
I have tried asking around school, StackOverflow, and YouTube for about 3 days now, and nothing has solved my problem, if you need any more info about it please ask. I am getting the error code:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1558, in __call__
return self.func(*args)
File "/root/Desktop/Python Programs/Tkinter.py", line 35, in showImg
load = Image.open('pic.png')
AttributeError: type object 'Image' has no attribute 'open'
You use import * so you don't know if you use tkinter.Image or PIL.Image . And this is why you shouldn't use import *
Try
from PIL import Image, ImageTk
Images are a bit tricky to get right, some tips: Keep the image object global, to avoid garbage collection, avoid Attribute Error (by reading the docs).
In this example I don t use PIL and I load a gif image
#!/usr/bin/python
#-*-coding:utf-8 -*
#Python 3
#must have a valid gif file "im.gif" in the same foldeer
from tkinter import *
Window=Tk()
ListePhoto=list()
ListePhoto.append(PhotoImage(file="im.gif"))
def Try():
Window.title('image')
Window.geometry('+0+0')
Window.configure(bg='white')
DisplayImage()
def DisplayImage():
label_frame=LabelFrame(Window, relief='ridge', borderwidth=12, text="AnImage",
font='Arial 16 bold',bg='lightblue',fg='black')
ListeBouttons=list()#Liste Vide pour les Radiobutton(s)
RadioButton = Radiobutton(label_frame,text="notext",image=ListePhoto[0], indicatoron=0)
RadioButton.grid(row=1,column=1)
label_frame.pack(side="left")
if __name__ == '__main__':
Try()
Related
So I have a couple of images in a folder and I want to do a little pack opener on tkinter where if I press on a button it randomly opens an Image of that folder and shows it. So I did this:
import os
import random
from PIL import Image
from tkinter import *
def pack():
path ='C:\\Users\\matt\OneDrive\Images\cards'
files = os.listdir(path)
index = random.randrange(0, len(files))
image = Image.open(files[index])
image.show()
pack_button = Button(window,text = " Pack ",fg="white",bg = 'black',command = pack)
pack_button.grid(row = 2,column = 1,padx = 10,pady = 5)
window.mainloop()
The problem is that this function doesn't want to work and it always tells me:
AttributeError: type object 'Image' has no attribute 'open'
Can someone please help me? And does someone know how to do a button out of an image?
Thank you in advance.☺
Assuming you're using Python 3, and you have a folder named card images in the same directory as your Python script, and that folder contains .png images of your playing cards, then the following should work:
import tkinter as tk
def get_random_image_path():
from random import choice
from pathlib import Path
return str(choice(list(Path("card images").glob("*.png"))))
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title("Random card")
self.geometry("171x239")
self.resizable(width=False, height=False)
self.image = tk.PhotoImage(file=get_random_image_path())
self.button = tk.Button(self, image=self.image, command=self.assign_new_image)
self.button.pack()
def assign_new_image(self):
self.image = tk.PhotoImage(file=get_random_image_path())
self.button.configure(image=self.image)
def main():
application = Application()
application.mainloop()
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
Note: I just grabbed three public domain card images from Wikimedia Commons. You can download them either in .svg or .png format in different resolutions. In my case I downloaded them as .pngs with a resolution of 171x239, which is why I picked the same dimensions for the tkinter window. Since I've only downloaded three images, sometimes it appears as though clicking the button doesn't seem to do anything, which isn't the case - it's just that, with only three images to choose from, we're likely to pick the same image multiple times in a row.
To get your example running, see a minimal solution below.
For a ready Tkinter program and to avoid PIL use Paul M.'s solution.
import os
import random
from PIL import Image
# assuming that this dir contains only images
# otherwise test if r is an image
img_folder = r'/home/ktw/Desktop/test_img'
def pack():
r = random.choice(os.listdir(img_folder))
image = Image.open(os.path.join(img_folder, r))
image.show()
if __name__=='__main__':
pack()
EDIT:
This should work for you. Just change the path to the full path of your image folder.
choice(os.listdir(img_folder)) gives you only the name of the random file. os.path.join(img_folder, choice(os.listdir(img_folder))) builds an absolute path from the image folder and the random image so Tk.PhotoImage should work.
import tkinter as tk
import os
from random import choice
from pathlib import Path
img_folder = r'/home/ktw/Desktop/images'
def get_random_image_path():
return os.path.join(img_folder, choice(os.listdir(img_folder)))
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title("Random card")
self.geometry("171x239")
self.resizable(width=False, height=False)
self.image = tk.PhotoImage(file=get_random_image_path())
self.button = tk.Button(self, image=self.image, command=self.assign_new_image)
self.button.pack()
def assign_new_image(self):
self.image = tk.PhotoImage(file=get_random_image_path())
self.button.configure(image=self.image)
if __name__=='__main__':
application = Application()
application.mainloop()
import tkinter as tk
import os
from random import choice
from pathlib import Path
from PIL import Image
img_folder = r'C:\\Users\\matt\OneDrive\Images\cards'
def get_random_image_path():
return os.path.join(img_folder, choice(os.listdir(img_folder)))
class Application(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("Random card")
self.resizable(width=False, height=False)
self.image = tk.PhotoImage(get_random_image_path())
self.button = tk.Button(self, image=self.image, command=self.assign_new_image)
self.button.pack()
def assign_new_image(self):
self.image = tk.PhotoImage(file=get_random_image_path())
self.button.configure(image=self.image)
if __name__=='__main__':
application = Application()
application.mainloop()
and it says this:
File "C:\Users\matt\OneDrive\Images\cards\pack opener.py", line 31, in <module>
application = Application()
File "C:\Users\matt\OneDrive\Images\cards\pack opener.py", line 22, in __init__
self.button = tk.Button(self, image=self.image, command=self.assign_new_image)
File "C:\Users\matt\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 2679, in __init__
Widget.__init__(self, master, 'button', cnf, kw)
File "C:\Users\matt\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 2601, in __init__
self.tk.call(
_tkinter.TclError: image "C:\\Users\\matt\OneDrive\Images\cards\Vettel.png" doesn't exist
I am able to get the image to display in the GUI with Tkinter however I can not get this part of the code to work as I am trying to keep it all either under one .py file because it is easier for me to keep everything in one singular window.
The error I am getting is:
Traceback (most recent call last):
File "C:/Users/Holcomb Family/PycharmProjects/webscrapeTKINTER/venv/main4.py", line 32, in <module>
run = MainWin(root)
pil_img = Image.open(my_picture)
AttributeError: type object 'Image' has no attribute 'open'
My code:
import io
from PIL import Image, ImageTk
from tkinter import *
from urllib.request import urlopen
root = tk.Tk()
root.title("New Window")
class MainWin:
def __init__(self, master):
self.master = master
url1 = "https://img.finalfantasyxiv.com/lds/pc/global/images/itemicon/"
url2 = "da/dad2c1875e87e7a7f1d02fce24f0bd0351cdda11.png?n5.45"
pic_url = url1 + url2
my_page = urlopen(pic_url)
my_picture = io.BytesIO(my_page.read())
pil_img = Image.open(my_picture)
tk_img = ImageTk.PhotoImage(pil_img)
self.label = tk.Label(root, image=tk_img)
self.label.pack(padx=5, pady=5)
root = Tk()
run = MainWin(root)
root.mainloop()
Summary of code purpose: change tk.Button['image'] to either selected file, or screen snip
I'm getting this error:
_tkinter.TclError: image "<PIL.Image.Image image mode=RGB size=600x400 at 0x34045F0>" doesn't exist
But I can't understand why it doesn't exist since if I useprint(self.image_selected) I get
<PIL.Image.Image image mode=RGB size=600x400 at 0x3D16650>
Does it need to be a global variable? Doesn't adding self take care of that?
CODE
import tkinter as tk
from tkinter import filedialog
from PIL import ImageGrab, ImageTk
class MCVE():
def __init__(self, master):
self.master = master
self.ButtonOne = tk.Button(text="start",width=30,height=30,command = lambda: self.GetImg(master))
self.ButtonOne.pack()
self.image_selected = None
def GetImg(self, master):
self.newWin = tk.Toplevel(self.master)
self.ButtonTwo = tk.Button(self.newWin,text="snip", command = lambda: self.Snip(self.master))
self.ButtonThree = tk.Button(self.newWin, text="open", command = lambda: self.FileO(self.master))
self.ButtonTwo.pack()
self.ButtonThree.pack()
def Snip(self, master):
self.image_selected = ImageGrab.grab(bbox=(0,0,600,400))
self.changeImg()
def FileO(self, master):
ret = filedialog.askopenfilename() # filedialog.askopenfilename(initialdir='/home/user/images/')
if ret:
self.image_selected = ImageTk.PhotoImage(file=ret)
self.changeImg()
def changeImg(self):
if self.image_selected:
print(self.image_selected)
#self.ButtonOne['image'] = self.image_selected
self.ButtonOne.config(image=self.image_selected)
def main():
root = tk.Tk()
MCVE(root)
root.mainloop()
if __name__ == '__main__':
main()
I tested the program, and as you stated, the 'snip' button gave me the error. I could fix it by changing the format of the image to a ImageTk.PhotoImage.
def Snip(self, master):
self.image_selected = ImageTk.PhotoImage(ImageGrab.grab(bbox=(0,0,600,400)))
self.changeImg()
I have to say, though, that the photo showed on the button icon after selecting the image was weird, but I guess it was because i tested it with the wrong resolution! ;)
When I run this I get the error
File "C:/Users/plarkin2020334/PycharmProjects/untitled1/venv/Start.py", line 24, in add_list
file.write(text)
NameError: name 'text' is not defined
I don't know why it won't run it but I think the basis of the code is right.
import tkinter
from datetime import datetime
from time import strftime
from tkinter import *
from tkinter import PhotoImage
from tkinter import ttk
from tkinter.ttk import *
root = tkinter.Tk()
class FrameStart1(tkinter.Frame):
image = PhotoImage(file='C:/Users/plarkin2020334/Pictures/DQ_Logocp.png')
def __init__(self, parent, *args, **kwargs):
tkinter.Frame.__init__(self, parent, *args, **kwargs)
Label(self, image=self.image).place(relx=0, rely=0, anchor=NW)
Label(self, text="Enter any additional Instructiuons for the day:", background="#3f49e5").place(relx=.0, rely=.45)
Button(self, text="Add to Todays List", command=self.add_list()).place(relx=.30, rely=.51)
Entry(self).place(relx=.0, rely=.51)
text = Entry.get()
def add_list(self):
file = open("List.txt", "w")
file.write(text)
def runStart1():
MyFrameStart1 = FrameStart1(root)
MyFrameStart1.pack(expand='true', fill='both')
MyFrameStart1.configure(background="#3f49e5")
root.geometry("500x300")
runStart1()
root.mainloop()```
I'm new to using classes, but wouldn't it have to be referenced as self.text since you are defining it in the __init__ method?
This question already has answers here:
Tkinter error: Couldn't recognize data in image file
(10 answers)
Closed 3 hours ago.
I'm currently in the middle of a recorded Python lecture and I think the version of python the teacher is using is outdated and he is writing a tkinter program but after copying it I keep getting this error:
Traceback (most recent call last):
File "C:\Users\1234\AppData\Local\Programs\Python\Python36-32\Lecture Class 11.py", line 35, in <module>
photo = PhotoImage(file="Me With My 5th Place.jpg")
File "C:\Users\1234\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 3539, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Users\1234\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 3495, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't recognize data in image file "Me With My 5th Place.jpg"
And here is my code:
from tkinter import *
class Application(Frame):
def __init__(self, master):
super(Application, self).__init__(master)
self.grid()
self.button_clicks = 0
self.create_widgets()
def create_widgets(self):
self.label1 = Label(self)
label1.image = photo
label1.grid()
self.button1 = Button(self)
self.button1["text"] = "Click me!!!"
self.button1["command"] = self.update_count
self.button1.grid(row=1, column=1)
self.button2 = Button(self)
self.button2["text"] = "Reset click counter"
self.button2["command"] = self.reset_count
self.button.grid(row=3, column= 1)
def update_count(self):
self.button_clicks += 1
self.button1["text"] = "Total clicks: " + str(self.button_clicks)
def res_count(self):
self.button_clicks = 0
self.button["text"] = "I am reset. Click me!!!"
root = Tk()
root.title("CP101 click counter")
root.geometry("400x400")
photo = PhotoImage(file="Me With My 5th Place.jpg")
app = Application(root)
root.mainloop()
.jpg is not supported by default by tkinter. You can use .jpg files using PIL:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except:
import Tkinter as tk
from PIL import Image, ImageTk
if __name__ == '__main__':
root = tk.Tk()
label = tk.Label(root)
img = Image.open(r"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg")
label.img = ImageTk.PhotoImage(img)
label['image'] = label.img
label.pack()
root.mainloop()
This is quite normal. Tkinter does not yet support .jpg files. To solve the problem you want to either to convert your file to .png, .gif or similar or use Pillow module to add support for .jpg files.