如何从命令中识别按钮?

时间:2014-09-23 18:37:06

标签: python events button tkinter tkinter-entry

我在for循环中创建了一个条目列表。所有条目都存储在一个列表中,以便稍后我可以获得所有输入:

inputs = [e.get() for e in self.entries]

但是,我还在for循环中的每个条目旁边创建了一个按钮(因此它们每个都调用相同的函数)。如何识别哪个按钮属于哪个行/条目?我可以用事件做点什么吗?

row = 0
self.entries = []
self.comments = []
for n in names:
   e = Entry(self.top, bd = 5)
   e.insert(0, n)
   e.grid(column = 1, row = self.row, sticky = 'NSWE', padx = 5, pady = 5)
   self.entries.append(e)
   self.comments += [""]
   commentButton = Button(self.top, text = "comment", command = self.commentSelected)
   commentButton.grid(column = 3, row = self.row, sticky = 'NSWE', padx = 5, pady = 5)
   self.row = self.row + 1

2 个答案:

答案 0 :(得分:1)

是 - 使用Callback Shims(Currying Functions)

(Russell Owen提供)

我发现我经常希望将额外数据传递给回调函数,此外通常给出。例如, Button 小部件不向其命令回调发送任何参数,但我可能想使用一个回调函数来处理多个按钮,在这种情况下我需要知道哪个按钮被压了。

处理此问题的方法是在将回调函数传递给窗口小部件之前定义回调函数,并包含所需的任何额外信息。不幸的是,像大多数语言一样,Python并没有处理早期绑定(定义函数时已知的信息)和后期绑定(调用函数时已知的通知)的混合特别好。我个人认为最简单,最干净的解决方案是:

编写我的回调函数,将所有需要的数据作为参数。 使用回调填充类来创建一个可调用的对象,该对象存储我的函数和额外的参数,并在调用时做正确的事情。换句话说,它使用保存的数据和调用者提供的数据调用我的函数。 我希望下面给出的例子能说明这一点。

我使用的回调垫片是RO.Alg.GenericCallback,它可以在我的RO包中找到。下面的示例中给出了不处理关键字参数的简化版本。所有的垫片代码都是基于Scott David Daniels的python配方,他称之为#strong; currying a function " (这个术语可能比#34更常见;回调垫片")。

#!/usr/local/bin/Python
"""                       Example showing use of a callback shim"""
import Tkinter

def doButton(buttonName):
    """                   My desired callback.
                          I'll need a callback shim
                          because Button command callbacks receive no arguments.
    """
    print buttonName, "pressed"

class SimpleCallback:
    """                   Create a callback shim.
                          Based on code by Scott David Daniels
                          (which also handles keyword arguments).
    """
    def __init__(self, callback, *firstArgs):
        self.__callback = callback
        self.__firstArgs = firstArgs

    def __call__(self, *args):
        return self.__callback (*(self.__firstArgs + args))


root = Tkinter.Tk()

buttonNames = ( "Button 1", "Button 2", "Button 3" )
for name in buttonNames:
    callback = SimpleCallback( doButton, name )
    Tkinter.Button( root, text = name, command = callback ).pack()

root.mainloop()

答案 1 :(得分:0)

您还可以使用lambda

from tkinter import *

def bla(b):
   ...

root = Tk()

buttons = []
for i in range(...):
    button = Button(root)
    button.configure(command=lambda b=button: bla(b))  # Make sure the Button object already exists
    buttons.append(button)
    button.pack()

root.mainloop()

据我所知,你现在无法在单个列表理解中创建按钮,但它比类imho更简单,更易读。