找到按钮列表中单击了哪个按钮

时间:2013-04-16 08:41:11

标签: python tkinter

问题

我正在创建一个应用程序来处理一个人的所有联系人详细信息。记录存储在文本文件中,使得第10个索引的第5个索引由用户给出的每个联系人的昵称组成。我想将所有这些昵称列表作为按钮,当用户选择任何一个按钮时,将使用tkSimpleDialog.showinfo('text','contact details')显示此联系人的详细信息。

<小时/> 的目标

  1. 决定在按钮列表中点击了哪个按钮。
  2. 这是我经常遇到的一个问题:将参数传递给回调函数
  3. <小时/> 的

    请注意,此代码无法实现我想要实现的目标。

    buttons = []
    
    inFile = open('test','r')
    
    for i in inFile:
    
        thisrecord = i    
        buttons.append(Button(self.frame,text='Name: %s' %i[5:10],command=self.show(thisrecord))
    
    inFile.close()
    

    <小时/> 我尝试了什么

    当我尝试上面的代码时,发生的事情就是每次显示存储在文件中的最后一条记录,无论我按下什么按钮。我发现了为什么会这样。显然,按钮都是一次创建的,然后每当调用每个按钮时都会调用回调函数。

    如果我的按钮数量有限,那么我肯定可以为每个按钮定义功能,然后将它们用作回调。这就是我在我的应用程序的欢迎页面中所做的事情,该页面包含以下按钮:add new contactsee details of contact等等。

    但在这种情况下,记录数量不固定。所以我在这里解决了,不明白该怎么做。

    我进一步尝试使用检查按钮,因此无论用户想要看到哪个记录,他都可以勾选并按继续并继续。但即使这样也失败了,因为首先创建了检查按钮,而不是代码在那里运行。

    帮我解决这个问题。


    功能

    Linux Mint 14
    Python 2.7
    tkinter 8.5

3 个答案:

答案 0 :(得分:3)

正如您已经注意到的那样,您甚至可以在创建按钮之前调用self.show(thisrecord),因为这是按钮参数的一部分。你想要一个函数作为回调。

所以要修复它会产生一个函数,它返回一个可以用作回调的函数:

# add to your class
def showCallback(self,record):
    """ returns a callback for self.show """
    def callback():                 # make a new function
        return self.show(record)    # that shows the given record
    return callback                 # return this function

for thisrecord in inFile:
    buttons.append(Button(self.frame,text='Name: %s' %i[5:10],
                           command=self.showCallback(thisrecord))

self.showCallback(thisrecord)现在将为每条记录返回不同的功能。

答案 1 :(得分:3)

在您的示例中,在创建Button时执行self.show(thisrecord),并且结果(可能为None)绑定到command

你想要的是在这里传递一个函数,当你单击按钮时执行该函数,而不是在构造时。这样做的一种方法是使用functools.partial,如下所示:

import Tkinter as tk
from functools import partial

root = tk.Tk()
buttons = []
inFile = ['... line1 ...', '... line2 ...', '...']

def show(par):
    print par

for i in inFile:
    thisrecord = i    
    button = tk.Button(root, text='Name: %s' %i[5:10], command=partial(show, thisrecord))
    button.pack()
    buttons.append(button)

tk.mainloop()

或者你可以定义自己的函数,它返回一个可以完成工作的回调函数。

note :在发布示例时,最好包含将其粘贴到解释器中以使其运行所需的所有内容...

答案 2 :(得分:1)

您正在做的事情:command=self.show(thisrecord)是您实际使用参数self.show(..)执行函数thisrecord并将返回值分配给键command。< / p>

你应该做什么:

command=partial(self.show, thisrecord)

partial所做的是返回一个带有冻结参数部分的新函数。


另一个展示partial的例子:

from functools import partial

def fn(x):
    print x

functions = []
for i in range(0,3):
    functions.append(partial(fn, i))

for func in functions:
    func()