2012-04-21 109 views
1

我做了一個非常簡單的GUI,它有一個按鈕並顯示圖像(.gif)。我的目標是每當你按下按鈕時輸出另一個.gif文件。在我的文件目錄中有2個.gif文件,並且每當你按下按鈕時都要在這兩個文件之間切換。當按下按鈕時顯示重複圖像的簡單GUI

#Using python2.7.2 
import Tkinter 

root = Tkinter.Tk() 

try: 
    n 
except: 
    n = 0 

def showphoto(par): 
    if par%2 == 0: 
     try: 
      label2.destroy() 
     except: 
      pass 
     photo = Tkinter.PhotoImage(file="masc.gif") 
     label2 = Tkinter.Label(image=photo) 
     label2.image = photo 
     label2.pack() 

    else: 
     try: 
      label2.destroy() 
     except: 
      pass 
     photo = Tkinter.PhotoImage(file="123.gif") 
     label2 = Tkinter.Label(image=photo) 
     label2.image = photo 
     label2.pack() 

myContainer1 = Tkinter.Frame(root, width = 100, height = 100) 
myContainer1.pack() 

def callback(event): 
    global n 
    showphoto(n) 
    n = n + 1 

button1 = Tkinter.Button(myContainer1) 
button1["text"]= "Next pic" 
button1["background"] = "green" 
button1.bind("<Button-1>", callback(n))  
button1.pack()     

root.mainloop() 

當前的代碼只是輸出第一圖像(masc.gif),但是當我按下按鈕不切換到另一圖像(123.gif)。我究竟做錯了什麼?

+0

我覺得這個代碼,你只需要使用n回調的全球外。而不是'try:n;除了:n = 0',爲什麼不使用'global n; n = 0'? – gary 2012-04-21 17:03:59

+0

我這樣做,它不會改變任何東西。另外,據我所知,在函數之外聲明一個可變的全局是多餘的。 – Bentley4 2012-04-22 08:43:44

回答

3

使用類可以更容易實現,因爲該類可以在不使用全局變量的情況下保存所有必需的數據。

import Tkinter as tk 
from collections import OrderedDict 

class app(tk.Frame): 
    def __init__(self,master=None, **kwargs): 
     self.gifdict=OrderedDict() 
     for gif in ('masc.gif','123.gif'): 
      self.gifdict[gif]=tk.PhotoImage(file=gif) 
     tk.Frame.__init__(self,master,**kwargs) 
     self.label=tk.Label(self) 
     self.label.pack() 
     self.button=tk.Button(self,text="switch",command=self.switch) 
     self.button.pack() 
     self.switch() 

    def switch(self): 
     #Get first image in dict and add it to the end 
     img,photo=self.gifdict.popitem(last=False) 
     self.gifdict[img]=photo 
     #display the image we popped off the start of the dict. 
     self.label.config(image=photo) 

if __name__ == "__main__": 
    A=tk.Tk() 
    B=app(master=A,width=100,height=100) 
    B.pack() 
    A.mainloop() 

當然,這可能是更普遍的做...(圖像週期通過例如可以通過列表),而這將通過所有的圖像self.gifs切換...

這種方法也消除了每次銷燬和重新創建標籤的必要性,而不是我們重複使用我們已有的標籤。

編輯

現在我用的OrderedDict來存儲文件。 (密鑰=文件名,值= PhotoImages)。然後我們彈出字典中的第一個元素進行繪圖。當然,如果您使用的是python2.6或更早的版本,除了字典之外,您還可以保留一個列表並使用列表來獲取密鑰。

+0

這個版本泄漏內存 - 每次你切換你創建另一個圖像。相反,創建圖像並將其存儲在字典中。下次切換時,請檢查字典並使用已創建的圖像(如果存在)。您也可以通過簡單地從列表的前面拉取圖像並將其添加到最後來消除混淆的索引計算。 – 2012-04-21 19:57:08

+0

@BryanOakley--它確實泄漏了內存嗎?雖然確實每次切換都會創建一個新的圖像,但舊的應該已經被垃圾收集了(我認爲......)無論如何,改變列表的順序是一個好主意(因爲是字典),所以我編輯。唯一的缺點是你需要有足夠的內存來存儲整個gif序列。 – mgilson 2012-04-21 22:18:06

1
button1 = Tkinter.Button(myContainer1) 
button1["text"]= "Next pic" 
button1["background"] = "green" 
button1.bind("<Button-1>", callback(n)) 

首先,你綁定<Button-1>事件None(這就是callback(n)計算結果爲)。您應該將其綁定到callback(不包括括號(也稱呼叫運營商))。

其次,我建議你換callback不接受任何參數,取出bind呼叫,創建您的按鈕:

button1 = Tkinter.Button(myContainer1, command=callback)