I am trying to display images in a directory randomly in a single window that changes every 3 seconds. I also want it to be cross platform, as I am developing in Windows, but it will run on linux.
Currently I have this working code that iterates through all the image files of a directory with a mouse click (Code Below)
import os, sys, Tkinter, Image, ImageTk
def button_click_exit_mainloop (event):
event.widget.quit()
root = Tkinter.Tk()
root.bind("<Button>", button_click_exit_mainloop)
root.geometry('+%d+%d' % (-5,-5)) #controls where the window is
#gets list of file names in certain directory. In this case, the directory it is in
dirlist = os.listdir('.')
for f in dirlist:
try:
image1 = Image.open(f)
root.geometry('%dx%d' % (image1.size[0],image1.size[1]))
tkpi = ImageTk.PhotoImage(image1)
label_image = Tkinter.Label(root, image=tkpi)
label_image.place(x=0,y=0,width=image1.size[0],height=image1.size[1])
root.mainloop() # wait until user clicks the window
except Exception, e:
pass
The way it does this however is when the mouse clicks on the window it calls a function to close the widget.
The problem I am having is how to call this function, or close the widget without an event. Any suggestions?
This is what I currently have. This doesn't work obviously because it is stuck in the root.mainloop(), but it shows what I have generally in mind (Code below)
import os, sys, Tkinter, Image, ImageTk, random
root = Tkinter.Tk()
root.geometry('+%d+%d' % (-5,-5)) #controls where the window is
#gets list of file names in certain directory. In this case, the directory it is in
dirlist = os.listdir('.') #might not be in order, CHECK!!!
while True:
randInt = random.randint(0, 1)
image = Image.open(dirlist[randInt])
root.geometry('%dx%d' % (image.size[0],image.size[1]))
tkpi = ImageTk.PhotoImage(image)
label_image = Tkinter.Label(root, image=tkpi)
label_image.place(x=0,y=0,width=image.size[0],height=image.size[1])
root.mainloop()
time.sleep(3)
Thank you!
-Jonathan
EDIT: Response to Bryan Oakley: I tried what you suggested, and this looks like the solution.
The function is being called every 3 seconds, and a window is being created, but the image is not being placed in the window.
Is it that I do not have access to the root? How do I gain access?
Here is what I have currently:
import os, sys, Tkinter, Image, ImageTk, random
def changeImage():
#gets list of file names in certain directory. In this case, the directory it is in
dirlist = os.listdir('.') #might not be in order, CHECK!!!
#get random image
randInt = random.randint(0, 1)
image = Image.open(dirlist[randInt])
#set size to show, in this case the whole picture
root.geometry('%dx%d' % (image.size[0],image.size[1]))
#Creates a Tkinter compatible photo image
tkpi = ImageTk.PhotoImage(image)
#Put image in a label and place it
label_image = Tkinter.Label(root, image=tkpi)
label_image.place(x=0,y=0,width=image.size[0],height=image.size[1])
# call this function again in three seconds
root.after(3000, changeImage)
root = Tkinter.Tk()
root.geometry('+%d+%d' % (-5,-5)) #controls where the window is
changeImage()
root.mainloop()
Thank you!!
SOLUTION EDIT: I did not change the code so the label is only created once, so a label is created with each call. I did not do this because this could be applied to many other variables (dirlist = os.listdir('.') for exmaple), but would make the code harder to read. I did not see any disadvantage other than maybe more cycles used? I did not see a memory increase over time, which is all that mattered to me.
Here is the code, thank you Bryan Oakley for helping me!!
import os, Tkinter, Image, ImageTk, random
def changeImage():
global tkpi #need global so that the image does not get derefrenced out of function
#gets list of file names in certain directory. In this case, the directory it is in
dirlist = os.listdir('.')
#get random image
randInt = random.randint(0, 1)
image = Image.open(dirlist[randInt])
#set size to show, in this case the whole picture
root.geometry('%dx%d' % (image.size[0],image.size[1]))
#Creates a Tkinter compatible photo image
tkpi = ImageTk.PhotoImage(image)
#Put image in a label and place it
label_image = Tkinter.Label(root, image=tkpi)
label_image.place(x=0,y=0,width=image.size[0],height=image.size[1])
# call this function again in 1/2 a second
root.after(500, changeImage)
tkpi = None #create this global variable so that the image is not derefrenced
root = Tkinter.Tk()
root.geometry('+%d+%d' % (-5,-5)) #controls where the window is
changeImage()
root.mainloop()