我想制作一些按钮,其中包含我从数据库返回的项目列表,这些按钮都调用传递给列表项的函数。像这样的代码,但有效。此代码的问题是所有按钮都使用'item3'
调用该函数。
#!/usr/bin/env python
from Tkinter import *
root = Tk()
def func(name):
print name
mylist = ['item1','item2','item3']
for item in mylist:
button = Button(root,text=item,command=lambda:func(item))
button.pack()
root.mainloop()
答案 0 :(得分:6)
这里有两件事:
您需要将以下一行缩进一级:
button.pack()
目前,您只能在最后一个按钮上调用pack
方法。进行此更改将导致为每个按钮调用它。
所有按钮都将'item3'
发送到func
,因为这是item
的当前值。重要的是要记住lambda函数包含的表达式是在运行时而不是编译时计算的。
但是,同样重要的是要记住函数的参数及其默认值(如果有的话)都是在编译时而不是运行时评估的。
这意味着您可以通过为lambda提供一个默认值设置为item
的参数来解决问题。这样做会为for循环的每次迭代“捕获”item
的值。
以下是解决这些问题的脚本版本:
from Tkinter import *
root = Tk()
def func(name):
print name
mylist = ['item1', 'item2', 'item3']
for item in mylist:
button = Button(root, text=item, command=lambda x=item: func(x))
button.pack()
root.mainloop()
答案 1 :(得分:1)
您应该使用functools.partial
:
import functools
from Tkinter import *
root = Tk()
def func(name):
print name
mylist = ['item1','item2','item3']
for item in mylist:
button = Button(root,text=item,command=functools.partial(func,item))
button.pack()
root.mainloop()
答案 2 :(得分:0)
逻辑相同,但这是创建计算器的示例。仅显示,不计算。在这里,我使用grid()而不是pack()。
import tkinter
main_window = tkinter.Tk()
main_window.title("Calculator")
main_window.geometry('500x500+550+200')
main_window['padx'] = 8
main_window.columnconfigure(0, weight=1)
main_window.columnconfigure(1, weight=1)
main_window.columnconfigure(2, weight=1)
main_window.columnconfigure(3, weight=1)
main_window.columnconfigure(4, weight=1)
main_window.columnconfigure(5, weight=1)
main_window.rowconfigure(0, weight=1)
main_window.rowconfigure(1, weight=1)
main_window.rowconfigure(2, weight=1)
main_window.rowconfigure(3, weight=1)
main_window.rowconfigure(4, weight=1)
main_window.rowconfigure(5, weight=1)
main_window.rowconfigure(6, weight=1)
main_window.rowconfigure(7, weight=1)
title_label = tkinter.Label(main_window, text="Calculator")
title_label.grid(row=0, columnspan=6)
number_entry = tkinter.Entry(main_window)
number_entry.grid(row=1, columnspan=4, sticky='nwes')
button_list = [('C', 'E'),
('7', '8', '9', '+'),
('4', '5', '6', '-'),
('1', '2', '3', '*'),
('0', '=', '/')]
for outer_num, outer_val in enumerate(button_list):
for inner_num, inner_val in enumerate(outer_val):
x = 1
y = inner_num
if inner_val == "=":
x = 2
if inner_val == "/":
y += 1
tkinter.Button(main_window, text=inner_val).grid(row=outer_num + 2, column=y, columnspan=x,
sticky='news')
main_window.mainloop()