I have a project that draws turtle on a Canvas widget. I already know how to save the drawing but how do you open them. This is an example of what I'm trying to say :
from tkinter import *
root = Tk()
... #Just creating widgets
def openDrawing:
...#What goes in here ?
fileMenu.add_command(label = "Open Drawing",command=openDrawing,accelerator="Ctrl+O")
root.mainloop()
PostScript file formats containing image data are supported by the PIL library. So you can open your turtle .ps file like this:
import PIL
# Load the .ps file using PIL
ps_file = PIL.Image.open("turtle_file.ps")
ps_turtle = PIL.ImageTk.PhotoImage(ps_file)
...
...
# Let us suppose you want to display it on a label
label = Label(image=ps_turtle)
label.image = ps_turtle # keep a reference
label.pack()
Related
Today i was Trying to Display All .png files in my current Directory In a GUI With Python and Tkinter but The Code Was Not Wroking in a Way That i expected It only Displays The Last Image of the Folder and The Space for Other Images Was Blank.
# Importing Essentials
import os
from tkinter import Tk, Label, PhotoImage
# Initialize Tk root Class
root = Tk()
# Set Default Size of Our Tkinter Window - (WidthxHeight)
root.geometry("200x910")
# Set Minimum Size of Our Window - (Width, Height)
root.minsize(350, 200)
# Add a Label
WelcomeLabel = Label(text="All Images of This Folder")
WelcomeLabel.pack()
# Get All PNG Files in a List name pngFiles
pngFiles = []
for item in os.listdir():
if item.endswith(".png"):
pngFiles.append(item)
# Display All The PNG files to our GUI Screen
for file in pngFiles:
photoLoaded = PhotoImage(file=file)
mainImageLabel = Label(image=photoLoaded)
mainImageLabel.pack()
# Run The MainLoop
root.mainloop()
In tkinter the images must have references in memory, you cannot overwrite and reuse them, my solution is to make a list using pathlib, and then create the labels
If you display an image inside a function, then make sure to keep reference to the > image object in your Python program, either by storing it in a global variable or > by attaching it to another object.
Basics For Displaying Image In Tkinter Python
import pathlib
from tkinter import Tk, Label, PhotoImage
root = Tk()
root.geometry("200x910")
root.minsize(350, 200)
wellcome = Label(text="All Images of This Folder")
wellcome.pack()
# create a list from images with memory reference
images_with_ref = []
for img in pathlib.Path('.').glob('*.png'):
photoLoaded = PhotoImage(file=img)
images_with_ref.append(photoLoaded)
# create labels with correct images
for image in images_with_ref:
Label(image=image).pack()
root.mainloop()
With the current code you are overwriting your photoLoaded with every loop.
Instead you have can pack these photoLoaded in a list.
Additionally working with grids is recommended when working with multiple items.
both things are implemented in the code below:
# Importing Essentials
import os
from tkinter import Tk, Label, PhotoImage
# Initialize Tk root Class
root = Tk()
# Set Default Size of Our Tkinter Window - (WidthxHeight)
root.geometry("200x910")
# Set Minimum Size of Our Window - (Width, Height)
root.minsize(350, 200)
# Add a Label
WelcomeLabel = Label(text="All Images of This Folder")
WelcomeLabel.grid(row=0)
# Get All PNG Files in a List name pngFiles
pngFiles = []
for item in os.listdir():
if item.endswith(".png"):
pngFiles.append(item)
print(pngFiles)
# Display All The PNG files to our GUI Screen
i = 0
pics = []
for file in pngFiles:
pics.append(PhotoImage(file=file))
Label(root, image=pics[i]).grid(row=i + 1)
i += 1
# Run The MainLoop
root.mainloop()
I am writing an application that consists of three tkinter windows on the same page: a calendar, a notepad and a 'picture of the day' which is fetched from a bank of images when initiated by the user. The image is named after the calendar date + .jpg. It works fine...the first time. When I select another date and retrieve the image for that date, it comes up behind the first image in the 'picture of the day' window. The problem is that the first image does not disappear when replaced by another. I do not want to close the window, just close the current picture and replace it by the new one. There might a simple way, but I spent hours searching for it. The code below of part of the application. Hopefully, it shows where the problem is. Can you point me in the right direction? Thanks
from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog
import os
photo = Toplevel()
photo.geometry("300x250+1300+150")
photo.resizable(width=True, height=True)
photo.attributes("-topmost", True)
def openfn(): # To go fetch a new image
filename = filedialog.askopenfilename(title='open')
return filename
root.destroy()
def open_img(): # To open a new image
x = openfn()
img = Image.open(x)
img = img.resize((225,200), Image.ANTIALIAS)
im = ImageTk.PhotoImage(img)
panel = Label(photo, image=im)
panel.image = im
panel.pack()
img=img.save(cal.calphoto) # Saves the image (calphoto is date + .jpg)
def retrieve_photo(): # To open an existing image
img=Image.open(cal.calphoto)
im = ImageTk.PhotoImage(img)
panel = Label(photo, image=im)
panel.image = im
panel.pack()
I changed a few things in your code. The main thing is the take the label with the image into the global scope so the function open_img() can make changes to it instead of creating a new label each time it is called. Below open_img() now configures the label to show the image selected each time it is called. (This is basically illustrating what Delrius said.)
from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog
import os
photo = Toplevel()
photo.geometry("300x250+1300+150")
photo.resizable(width=True, height=True)
photo.attributes("-topmost", True)
panel = Label(photo) # panel Label moved into global scope so the
# functions below can access it
def openfn():
filename = filedialog.askopenfilename(title='open')
return filename
root.destroy()
def open_img():
x = openfn()
img = Image.open(x)
img = img.resize((225,200), Image.ANTIALIAS)
im = ImageTk.PhotoImage(img)
panel.config(image=im) # panel label is configured to show image selected
panel.image = im
panel.pack()
I am trying to run sample code and I am running into a problem where sublime says "_tkinter.TclError: couldn't recognize data in image file "C:\Users\atave\Dropbox\Python\tkinter Python Tutorial\Labels\prac.png". Can anyone tell me why? I have already set up sublime as an exception in the firewall, does it have to do with the location of the image?
import tkinter as tk
from tkinter import ttk
# create the root window
root = tk.Tk()
root.geometry('300x200')
root.resizable(False, False)
root.title('Label Widget Image')
# display an image label
photo = tk.PhotoImage(file="C:\\Users\\atave\\Dropbox\\Python\\tkinter Python Tutorial\\Labels\\prac.png")
image_label = ttk.Label(
root,
image=photo,
padding=5
)
image_label.pack()
root.mainloop()
the tk.PhotoImage doesn't work that well with .png files. I would suggest conversion to .bmp file or using PIL(Pillow) module- tk.PhotoImage(ImageTk.PhotoImage(file="C:\\Users\\atave\\Dropbox\\Python\\tkinter Python Tutorial\\Labels\\prac.png")
The ImageTk in ImageTk.PhotoImage() is imported from PIL(from PIL import ImageTk)
Working in a EXE file with background and Icon embed, I read some ideas about to use img2py in order to create module.py that can be imported into the EXE with pyinstaller.
I successfully create the imagebg.py (BG2.png Background) and imageico.py (ico2.ico Icon) modules using img2py. But there is no example or way to set that images into the modules in the tkinter label as background and the icon into the code.
Please anybody can help me.
Main code where must be imported BG ad ICON modules and use them as background and Icon images for tkinter GUI
#Main code GUI tkinter
import imagebg #from here we must import PNG_File.png for Background
import imageico #from here we must import ICO_File.ico for Icon
import wx #from img2py installation
from tkinter import *
root=Tk()
#set windows size
root.resizable(width=False, height=False)
root.geometry("925x722")
#set title
root.title("SOFT1)")
#frame 1
f1=Frame(root, width=345,height=475,bg="light
grey",highlightbackground="black",highlightthickness=4)
f1.place(x=20,y=235)
#set a image as BG
Logo=PhotoImage(file="PNG_File.png")
lab6=Label(root, image=Logo)
lab6.place(x=0, y=0)
#set a image as ICON
root.iconbitmap("ICO_File.ico")
mainloop()
The module imagebg.py for backgroud generated with IMG2PY
BG2 = PyEmbeddedImage(
b'iVBORw0KGgoAAAANSUhEUgAAAsUAAAKECAIAAABgrdCGAAAACXBIWXMAAA7EAAAOxAGVKw4b'
b'AAAgAElEQVR4nOzdd2Ab5d0H8Oe0hy1vecYjcZw4cfYimwQIEEbYhQJlFgqU3UFZLR2M9i2l'
b'tLRlFcouI5Qww15hZJEdO4kdOx7xtiVrj7v3DwdFlmXppu4kfT9/Wfbdc78YY339TMrpdBIA'
b'AAAAAVRyFwAAAABJD3kCAAAAhEKeAAAAAKGQJwAAAEAo5AkAAAAQCnkCAAAAhEKeAAAAAKGQ'
b'JwAAAEAo5AkAAAAQCnkCAAAAhEKeAAAAAKGQJwAAAEAo5AkAAAAQCnkCAAAAhEKeAAAAAKGQ'
b'JwAAAEAo5AkAAAAQCnkCAAAAhEKeA..... to much characters to be placed in this post
The module imageico.py for icon generated with IMG2PY
from wx.lib.embeddedimage import PyEmbeddedImage
ico2 = PyEmbeddedImage(
b'iVBORw0KGgoAAAANSUhEUgAAAsUAAAKECAYAAADvz0fRAAAABHNCSVQICAgIfAhkiAAAIABJ'
b'REFUeJzs3WeAVNXdBvDnTi/b+7L0svSmIIKd2Gus0ZhiSeKreZOYmGpL15i8SdTEFKMpGkss'
b'GEuMqNFYsCAgHRZYWFiWsn12p7f7fkBwy8zszC1z7537/L7ozs6c82dh4dkz/3OOEAgERBAR'
b'ERERmZhF6wKIiIiIiLTGUExEREREpsdQTERERESmx1BMRERERKbHUExEREREpsdQTERERESm'
b'x1BMRERERKbHUExEREREpsdQTERERESmx1BMRERERKbHUExEREREpsdQTERERESmx1BMRERE'
b'RKbHUExEREREps.... to much characters to be placed in this post
Please any idea of how to use the modules as images for background and icon in the main code GUI Tkinter
You need to convert the wx.Image to PIL compatible image if you want to use it in tkinter application.
Below is an example based on your posted code:
import tkinter as tk
from PIL import Image, ImageTk
import imagebg
import imageico
# function to convert a wx.Image to PIL.ImageTk.PhotoImage
def wx2pil(wx_image):
image = wx_image.Image
w, h = image.GetWidth(), image.GetHeight()
data = image.GetData()
img = Image.frombytes('RGB', (w, h), bytes(data))
return ImageTk.PhotoImage(img)
root = tk.Tk()
root.resizable(False, False)
root.geometry('925x722')
root.title('SOFT1')
# use iconphoto() instead of iconbitmap()
root.iconphoto(False, wx2pil(imageico.ico2))
#set a image as BG
logo = wx2pil(imagebg.BG2)
tk.Label(root, image=logo).place(x=0, y=0)
#frame 1
f1 = tk.Frame(root, width=345, height=475, bg='lightgray', highlightbackground='black', highlightthickness=4)
f1.place(x=20, y=235)
root.mainloop()
Note that I use wxPython v4.1.0.
As it depends on wxPython, why don't you use wxPython for the GUI directly instead of tkinter?
I am trying to load an image into a canvas in python. However I am getting the error: TclError: couldn't recognize data in image file "C:\testimage\spongesea.jpg"
import Tkinter
from Tkinter import *
import time
import inspect
import os
from PIL import Image, ImageTk
class game_one:
def __init__(self):
global root
global canvas_one
root = Tk()
root.title(" Thanks Josh Dark
canvas_one = Tkinter.Canvas(root, bg="BLACK")
canvas_one.pack(expand= YES, fill= BOTH)
canvas_one.focus_set() #allows keyboard events
p = PhotoImage(file="C:\testimage\spongesea.jpg")
canvas_one.create_image(0, 0, image = p, anchor=NW)
root.grab_set()#I forget what this does. Don't change it.
root.lift()#This makes root appear in front of the other applications
ObjectExample = game_one()# starts the animation
I can open the image manually from the file, so it is not corrupted, and it is calling the correct place. Any ideas? Thanks
PhotoImage works only with GIF and PGM/PPM.
You have to use Image, ImageTk to work with other formats
from PIL import Image, ImageTk
image = Image.open("lenna.jpg")
photo = ImageTk.PhotoImage(image)
BTW: read PhotoImage and see "Garbage Collection problem" in note.