2010-04-28 80 views
1

我正在用Tkinter编写幻灯片程序,但我不知道如何在不绑定键的情况下转到下一个图像。在Python中退出Tks mainloop?

import os, sys 
import Tkinter 
import Image, ImageTk 
import time 

root = Tkinter.Tk() 
w, h = root.winfo_screenwidth(), root.winfo_screenheight() 
root.overrideredirect(1) 
root.geometry("%dx%d+0+0" % (w, h)) 
root.focus_set() 

root.bind("<Escape>", lambda e: e.widget.quit()) 

image_path = os.path.join(os.getcwd(), 'images/') 
dirlist = os.listdir(image_path) 

for f in dirlist: 
    try: 
     image = Image.open(image_path+f) 
     tkpi = ImageTk.PhotoImage(image)   
     label_image = Tkinter.Label(root, image=tkpi) # ? 
     label_image.place(x=0,y=0,width=w,height=h) 
     root.mainloop(0) 
    except IOError: 
     pass 
root.destroy() 

我想补充一个time.sleep(10)“而不是”的root.mainloop(0),因此它会10S后进入下一个图像。现在,当我按下ESC时它会改变。我怎样才能在那里有一个计时器?

编辑:我应该补充说,我不希望另一个线程即使工作也不会进行睡眠。

+0

启动和停止主循环没有太大的意义 - 这是一个无限循环,旨在为你的程序的运行寿命。 – 2010-05-03 15:39:09

+0

[这里是使用Tkinter的幻灯片的完整示例](https://gist.github.com/8b05c3ea0302f0e2c14c) – jfs 2012-12-15 18:22:00

回答

5

您可以尝试

root.after(10*1000, root.quit) 
+0

非常感谢!奇迹般有效。 – olofom 2010-04-29 22:19:04

5

有没有必要在你的图片做一个循环 - 你已经在一个循环(主循环)运行,所以利用它。这样做的典型方法是创建一个方法,绘制一些东西,等待一段时间,然后调用它自己。这不是递归,它只是告诉主循环“在N秒后再次打电话给我”。

这里有一个工作示例:

import glob 
import Tkinter 

class Slideshow: 
    def __init__(self, pattern="*.gif", delay=10000): 

     root = Tkinter.Tk() 
     root.geometry("200x200") 

     # this label will be used to display the image. Make 
     # it automatically fill the whole window 
     label = Tkinter.Label(root) 
     label.pack(side="top", fill="both", expand=True) 

     self.current_image = None 
     self.image_label = label 
     self.root = root 
     self.image_files = glob.glob(pattern) 
     self.delay = delay # milliseconds 

     # schedule the first image to appear as soon after the 
     # the loop starts as possible. 
     root.after(1, self.showImage) 
     root.mainloop() 


    def showImage(self): 
     # display the next file 
     file = self.image_files.pop(0) 
     self.current_image = Tkinter.PhotoImage(file=file) 
     self.image_label.configure(image=self.current_image) 

     # either reschedule to display the file, 
     # or quit if there are no more files to display 
     if len(self.image_files) > 0: 
      self.root.after(self.delay, self.showImage) 
     else: 
      self.root.after(self.delay, self.root.quit) 

    def quit(self): 
     self.root.quit() 


if __name__ == "__main__": 
    app=Slideshow("images/*.gif", 1000)