2014-12-04 29 views
1

我是一個大氣科學家,爲了創建一個簡單的圖像查看器,通過python(2.7使用PIL和Tkinter)掙扎着,它將顯示我們最終生成的一些預測產品。我想實現一個開始,停止,前進,後退和循環按鈕。循環按鈕及其關聯的回調當前正常工作。循環方法記入Glenn Pepper(通過谷歌發現一個開源項目)。 下面是代碼:Tkinter圖像查看器方法

from Tkinter import * 
from PIL import Image, ImageTk 
import tkMessageBox 
import tkFileDialog 

#............................Button Callbacks.............................# 

root = Tk() 
root.title("WxViewer") 
root.geometry("1500x820+0+0") 

def loop(): 
    StaticFrame = [] 
    for i in range(0,2): 

     fileName="filename"+str(i)+".gif" 
     StaticFrame+=[PhotoImage(file=fileName)] 
    def animation(currentframe): 

     def change_image(): 
      displayFrame.create_image(0,0,anchor=NW, 
         image=StaticFrame[currentframe], tag='Animate') 
      # Delete the current picture if one exist 
     displayFrame.delete('Animate') 
     try: 
      change_image() 
     except IndexError: 
        # When you get to the end of the list of images - 
        #it simply resets itself back to zero and then we start again 
      currentframe = 0 
      change_image() 
     displayFrame.update_idletasks() #Force redraw 
     currentframe = currentframe + 1 
      # Call loop again to keep the animation running in a continuous loop 
     root.after(1000, animation, currentframe) 
    # Start the animation loop just after the Tkinter loop begins 
    root.after(10, animation, 0) 


def back(): 
    print("click!") 

def stop(): 
    print("click!") 

def play(): 
    print("click!") 

def forward(): 
    print("click!") 
#..........................ToolFrame Creation............................# 

toolFrame = Frame(root) 
toolFrame.config(bg="gray40") 
toolFrame.grid(column=0,row=0, sticky=(N,W,E,S)) 
toolFrame.columnconfigure(0, weight = 1) 
toolFrame.rowconfigure(0, weight = 1) 
toolFrame.pack(pady = 0, padx = 10) 


backButton = Button(toolFrame, text="Back", command = back) 
backButton.pack(side = LEFT) 

stopButton = Button(toolFrame, text = "Stop", command = stop) 
stopButton.pack(side = LEFT) 

playButton = Button(toolFrame, text = "Play", command = play) 
playButton.pack(side = LEFT) 

forwardButton = Button(toolFrame, text = "Forward", command = forward) 
forwardButton.pack(side = LEFT) 

loopButton = Button(toolFrame, text = "Loop", command = loop) 
loopButton.pack(side = LEFT) 

toolFrame.pack(side = TOP, fill=X) 

#........................DisplayFrame Creation..........................# 
displayFrame = Canvas(root, width=1024,height=768) 
displayFrame.config(bg="white") 
displayFrame.grid(column=0,row=0, sticky=(N,W,E,S)) 
displayFrame.columnconfigure(0, weight = 1) 
displayFrame.rowconfigure(0, weight = 1) 
displayFrame.pack(pady = 5, padx = 10) 
displayFrame.pack(side = LEFT, fill=BOTH) 

#...............................Execution...............................# 

root.mainloop() 

這是相當簡單的。我已經搜索了GitHub的項目,谷歌和stackoverflow,但我不確定如何使這五種方法相互發揮很好。任何人都可以分享一些關於如何構建其他四種方法的指示,以便它們適當地工作?感謝您的時間!

+0

Tkinter不知道是線程安全的,所以像這樣的事情可能並不總是像它第一次出現那樣直截了當。我會嘗試使用線程安全的mtTkinter(http:// http://tkinter.unpythonic.net/wiki/mtTkinter),然後使用線程模塊處理更新。 – 2014-12-04 18:34:27

回答

2

我會用下面的東西(未經測試)替換當前的循環函數。更改:添加一些全局名稱以在函數之間共享數據;在current_image有效的情況下,使change_image完成更改圖像所需的一切;除了起始值以外,當current_image改變時,它總是一個有效的圖像號;因子forward()out of animate()(這只是重複次數前向調用)。

n_images = 2 
images = [PhotoImage(file="filename"+str(i)+".gif") for i in range(n_images)] 
current_image = -1 
def change_image(): 
    displayFrame.delete('Animate') 
    displayFrame.create_image(0,0, anchor=NW, 
         image=StaticFrame[current_image], tag='Animate') 
    displayFrame.update_idletasks() #Force redraw 

callback = None 
def animate(): 
    global callback 
    forward() 
    callback = root.after(1000, animate) 

這裏有三個其他功能。

def forward(): 
    global current_image 
    current_image += 1 
    if current_image >= n_images: 
     current_image = 0 
    change_image() 

def back(): 
    global current_image 
    current_image -= 1 
    if current_image < 0: 
     current_image = n_images-1 
    change_image() 

def stop(): 
    if callback is not None: 
     root.after_cancel(callback) 
+1

所有這一切都很好!唯一的例外是stop方法,它拋出了錯誤TclError:wrong#args:應該是「在取消id |命令之後」這裏的任何提示? – 3722839 2014-12-05 06:36:04

+2

我看到你爲current_image添加了全局語句。我添加了一個用於回調的動畫,並且一個警衛在回調爲無時(清除錯誤)不會調用after_cancel。該文檔說一個參數 - 一個從root.after(或after_idle)返回的id。我嘗試了一個最簡單的例子,這個工程。其他更改(如果不在您的版本中),代碼是否會更好地工作? – 2014-12-05 22:54:46