Make tkinter buttons for every item in a list?

隐身守侯 提交于 2021-02-18 07:56:26

问题


I would like to make some buttons, with a list of items I get back from a database, that all call a function passing in the list item. Something like this code but that works. The problem with this code is that all of the buttons call the function with '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()

回答1:


There are two things here:

  1. You need to indent the following line one level:

    button.pack()
    

    Currently, you only have the pack method being called on the last button. Making this change will cause it to be called for each button.

  2. All of the buttons are sending 'item3' to func because that is the current value of item. It is important to remember that the expression enclosed by a lambda function is evaluated at run-time, not compile-time.

    However, it is also important to remember that both a function's parameters as well as their default values (if any) are evaluated at compile-time, not run-time.

    This means that you can fix the problem by giving the lambda a parameter whose default value is set to item. Doing so will "capture" the value of item for each iteration of the for-loop.

Below is a version of your script that addresses these issues:

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



回答2:


You should use 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()



回答3:


The same logic, but this is an example of creating a calculator. Only display, no calculations. Here I used grid() instead of 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()


来源:https://stackoverflow.com/questions/21738149/make-tkinter-buttons-for-every-item-in-a-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!