Reputation: 13
I need the images to change if the cursor is inside the window without moving, but I managed to make the image changes only if the cursor is moving inside the window, how can I change the code?
from itertools import cycle
import tkinter as tk
from PIL import ImageTk, Image
import glob
image_files = glob.glob("*.jpg")
root = tk.Toplevel()
root.geometry("1600x900")
pictures = cycle((ImageTk.PhotoImage(file=image), image) for image in image_files)
picture_display = tk.Label(root)
picture_display.pack()
def show_slides(event):
img_object, img_name = next(pictures)
root.after(500, picture_display.config(image=img_object))
root.bind("<Motion>", show_slides)
root.mainloop()
Upvotes: 1
Views: 59
Reputation: 2096
You could bind the <Enter>
and <Leave>
events and use a flag to control the call, followed by using the after
method to loop the function.
def show_slides(event=None):
global change_slide
img_object, img_name = next(pictures)
picture_display.config(image=img_object)
change_slide=root.after(500,show_slides)
def stop_slides(event):
root.after_cancel(change_slide)
root.bind("<Enter>", show_slides)
root.bind("<Leave>", stop_slides)
UPDATE
Using a flag might cause multiple calls being scheduled it the events happen during the 500ms
delay, you can use after_cancel
to terminate it.
Upvotes: 1
Reputation: 8270
You can calculate cursor position in loop and show image if it's located within tkinter window:
import glob
import tkinter as tk
from PIL import ImageTk
from itertools import cycle
class App(object):
def __init__(self):
self.root = tk.Tk()
self.root.geometry('900x600')
self.lbl = tk.Label(self.root)
self.lbl.pack()
files = glob.glob('*.jpg')
self.images = cycle((ImageTk.PhotoImage(file=f), f) for f in files)
self.show()
self.root.mainloop()
def show(self):
abs_coord_x = self.root.winfo_pointerx() - self.root.winfo_rootx()
abs_coord_y = self.root.winfo_pointery() - self.root.winfo_rooty()
if 0 <= abs_coord_x <= self.root.winfo_width() and 0 <= abs_coord_y <= self.root.winfo_height():
img_object, img_name = next(self.images)
self.lbl.config(image=img_object)
self.root.after(1000, self.show)
App()
Upvotes: 0