2017-03-11 94 views
-2

所以我想按下項目的按鈕時打印項目的文本。如何在for循環中正確地創建Tkinter按鈕?

from tkinter import * 
from tkinter import ttk 

root = Tk() 
root.title('test') 

mainframe = ttk.Frame(root, padding='8') 
mainframe.grid(column=0, row=0) 

items = [ 
    { 
     'name' : '0001', 
     'text' : '1111', 
    },{ 
     'name' : '0002', 
     'text' : '2222', 
    },{ 
     'name' : '0003', 
     'text' : '3333', 
    }, 
] 

rcount = 1 #row count 
for item in items: 
    ttk.Label(mainframe, text=item['name']).grid(column=1, row=rcount, sticky=W) 
    ttk.Button(mainframe, text='->', command=lambda:print(item['text'])).grid(column=2, row=rcount, sticky=W) 
    rcount += 1 

root.mainloop() 

無論按下哪三個按鈕,我都會得到3333。如果我刪除lambda,我在程序開始時獲得1111 2222 3333,但這時按鈕沒有任何作用。

+0

例如,如果我按下按鈕3,2,1,2,3,我希望看到'3333 2222 1111 2222 3333'。相反,我得到'3333 3333 3333 3333 3333'(回覆該人問我期望的按鈕做什麼) –

回答

1

你可以做的簡單的改變是使用functools.partial而不是lambda。由於按下按鈕後,拉姆達評估的聲明,最後一個項目將是3333分保存指定參數和行爲一樣拉姆達(評估聲明按下按鈕後)

#rest the same 
from functools import partial 
for rcount, item in enumerate(items, start=1): #use this as row count 
    ttk.Label(mainframe, text=item['name']).grid(column=1, row=rcount, sticky=W) 
    ttk.Button(mainframe, text='->', command=partial(print,item['text'])).grid(column=2, row=rcount, sticky=W) 

有關如何更多信息使用部分看https://docs.python.org/3/library/functools.html#functools.partial

+1

FWIW這個問題也可以用lambda來解決。這不是lambda的使用錯誤,而是lambda的_incorrect_使用。 –

+0

你說得對,lambda也可以用來解決這個問題,但我相信它更容易使用partial – abccd