为列表中的每个项目制作tkinter按钮?

时间:2014-02-12 19:49:54

标签: python python-2.7 tkinter

我想制作一些按钮,其中包含我从数据库返回的项目列表,这些按钮都调用传递给列表项的函数。像这样的代码,但有效。此代码的问题是所有按钮都使用'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()

3 个答案:

答案 0 :(得分:6)

这里有两件事:

  1. 您需要将以下一行缩进一级:

    button.pack()
    

    目前,您只能在最后一个按钮上调用pack方法。进行此更改将导致为每个按钮调用它。

  2. 所有按钮都将'item3'发送到func,因为这是item的当前值。重要的是要记住lambda函数包含的表达式是在运行时而不是编译时计算的。

    但是,同样重要的是要记住函数的参数及其默认值(如果有的话)都是在编译时而不是运行时评估的。

    这意味着您可以通过为lambda提供一个默认值设置为item的参数来解决问题。这样做会为for循环的每次迭代“捕获”item的值。

  3. 以下是解决这些问题的脚本版本:

    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()