2013-04-16 56 views
0

問題找到被點擊了按鈕

我創建一個應用程序,它利用一個人的所有聯繫方式照顧名單的哪個按鈕。記錄存儲在文本文件中,以便第10個索引的第5個索引由用戶給出的每個聯繫人的暱稱組成。我想列出所有這些暱稱作爲按鈕,當用戶選擇任何一個按鈕時,此聯繫人的詳細信息將使用tkSimpleDialog.showinfo('text','contact details')顯示。


目標

  1. 決定被點擊的按鈕列表的按鈕。
  2. 這是我經常面臨一個問題:一個參數傳遞給回調函數


代碼

請注意,此代碼不能完成我想要實現什麼。

buttons = [] 

inFile = open('test','r') 

for i in inFile: 

    thisrecord = i  
    buttons.append(Button(self.frame,text='Name: %s' %i[5:10],command=self.show(thisrecord)) 

inFile.close() 


我試過

當我試圖在上面的代碼又是什麼happenned是存儲在文件中的最後一個記錄是每次都顯示,不管按鈕我按。我發現爲什麼會發生這種事情。顯然這些按鈕都是一次創建的,然後每當調用每個按鈕時都會調用回調函數。

如果我的按鈕數量有限,那麼我肯定可以爲每個按鈕定義函數,然後將它們用作回調函數。這就是我在我的應用程序的歡迎頁面上所做的事情,它具有如下按鈕:add new contactsee details of contact等等。

但是在這種情況下,記錄數量不固定。所以我在這裏修復並且不知道該怎麼做。

我進一步嘗試使用檢查按鈕,以便無論用戶想要查看哪條記錄,他都可以打勾並按繼續並繼續。但即使這樣做也失敗了,因爲再次檢查按鈕是首先創建的,而不是代碼在那裏運行。

幫我解決這個問題。


規格

Linux Mint的14
的Python 2.7
Tkinter的8.5

+0

我敢肯定,我已經在過去幾周出現了類似的問題,至少兩次,但在爲他們尋找可能不會成功( –

+0

)你描述的行爲與你展示的片段不匹配,你的代碼的行爲是當按鈕被創建時實際執行回調,並且當點擊按鈕時不執行任何動作 – FabienAndre

+0

是的,我解釋的行爲是我想完成什麼,代碼沒有完成,我將編輯這個問題的效果。謝謝! – IcyFlame

回答

3

正如你已經注意到了,你叫self.show(thisrecord)甚至可以創建一個按鈕之前,因爲這是一部分按鈕參數。你希望有一個函數作爲回調。

因此,要解決它作出這樣的返回,可以用來作爲一個回調函數功能:

# add to your class 
def showCallback(self,record): 
    """ returns a callback for self.show """ 
    def callback():     # make a new function 
     return self.show(record) # that shows the given record 
    return callback     # return this function 

for thisrecord in inFile: 
    buttons.append(Button(self.frame,text='Name: %s' %i[5:10], 
          command=self.showCallback(thisrecord)) 

self.showCallback(thisrecord)將返回不同的功能,爲每個記錄現在。

+0

非常感謝你!奇蹟般有效!!! – IcyFlame

+0

一個非常優雅的解決方案!非常感謝!我一直在想爲什麼我沒有想到這個! – IcyFlame

3

在您的示例中,self.show(thisrecord)在創建按鈕時執行,結果(可能爲無)綁定到command

你想要的是傳遞一個函數,當你點擊按鈕時執行,而不是在施工時執行。這樣做的一個方法是使用functools.partial,像這樣:

import Tkinter as tk 
from functools import partial 

root = tk.Tk() 
buttons = [] 
inFile = ['... line1 ...', '... line2 ...', '...'] 

def show(par): 
    print par 

for i in inFile: 
    thisrecord = i  
    button = tk.Button(root, text='Name: %s' %i[5:10], command=partial(show, thisrecord)) 
    button.pack() 
    buttons.append(button) 

tk.mainloop() 

,也可以定義自己的函數返回一個回調函數,將做的工作。

:發佈一個例子,當它總是好的,包括必要的,只是將其粘貼到一個解釋一切,使運行它...

1

什麼你做:command=self.show(thisrecord)是,你實際上是在執行函數self.show(..)與參數thisrecord並將返回值分配給密鑰command

你實際上應做什麼:

command=partial(self.show, thisrecord) 

什麼partial確實是返回與參數的凍結部分新功能。


另一個例子來證明partial

from functools import partial 

def fn(x): 
    print x 

functions = [] 
for i in range(0,3): 
    functions.append(partial(fn, i)) 

for func in functions: 
    func()