2017-03-11 64 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