问题
我正在创建一个应用程序来处理一个人的所有联系人详细信息。记录存储在文本文件中,使得第10个索引的第5个索引由用户给出的每个联系人的昵称组成。我想将所有这些昵称列表作为按钮,当用户选择任何一个按钮时,将使用tkSimpleDialog.showinfo('text','contact details')
显示此联系人的详细信息。
<小时/> 的码
请注意,此代码无法实现我想要实现的目标。
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 contact
和see details of contact
等等。
但在这种情况下,记录数量不固定。所以我在这里解决了,不明白该怎么做。
我进一步尝试使用检查按钮,因此无论用户想要看到哪个记录,他都可以勾选并按继续并继续。但即使这样也失败了,因为首先创建了检查按钮,而不是代码在那里运行。
请帮我解决这个问题。
功能
Linux Mint 14
Python 2.7
tkinter 8.5
答案 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()