【发布时间】:2014-05-19 02:07:25
【问题描述】:
我下载了一个 MultiListBox 小部件,以及我成功应用的排序扩展。但是,这个小部件在 python 3 中从未对我有用。库是 Tkinter (py2) 和 tkinter (py3)。
所以,我离工作越来越近了,但有一部分我不太明白如何过去。 apply() 函数已被弃用,而且似乎在 py3 中也没有。随它吧。
这是我不明白的:
我们有 apply(function, args [, keywords]) 和 map(function, iterable...)
apply() 函数的调用方式如下:
return apply(map, [None] + result)(结果是字符串元组的列表)
documentation 建议我采用将apply(function, *args, **keywords) 转换为function(*args, **keywords) 的方法。这一切都很好,但我不知道要传递什么作为新函数。
return map(what_am_i, result)
这里有一些相关的代码sn-ps。希望这一切都清楚,但随时要求更多。谢谢。
我添加了更多代码来为这里发生的事情提供上下文。也许这会产生一些见解,使这段代码更beautiful?
在此示例中,result 包含长度为 3(列)的 list,1000-tuples(行)。 1000-tuples 中的每个元素都是一个 string,其中包含 Subject、Sender 或 Date。
我现在更新了完整的 _sort() 函数。
现在,我已经更新了另一个重构 apply() 的实例。我不妨把这件事弄清楚到这个问题中,以便其他人都可以享受。
from tkinter import *
class MultiListbox(Frame):
def __init__(self, master, rowslist):
Frame.__init__(self, master)
self.rowslist = []
self.colmapping = {}
self.origData = None
for (row, colwidth) in rowslist:
frame = Frame(self);
b = Button(frame, ...)
b.bind(...)
listbox = Listbox(frame, ...)
self.rowslist.append(listbox)
listbox.bind(...)
...
...
...
def _scroll(self, *args):
for row in self.rowslist:
row.yview(None, args)
# apply(row.yview, args)
...
def get(self, first, last=None):
result = []
for row in self.rowslist:
result.append(row.get(first,last))
if last:
return map(None, result)
#return apply(map, [None] + result)
return result
...
def _sort(self, e):
# get the listbox to sort by (mapped by the header button)
b=e.widget
col, direction = self.colmapping[b]
# get the entire table data into mem
tableData = self.get(0,END)
if self.origData == None:
import copy
self.origData = copy.deepcopy(tableData)
rowcount = len(tableData)
#remove old sort indicators if it exists
for btn in self.colmapping:
lab = btn.cget('text')
if lab[0]=='<': btn.config(text=lab[4:])
btnLabel = b.cget('text')
#sort data based on direction
if direction==0:
tableData = self.origData
else:
if direction==1: b.config(text='<+> ' + btnLabel)
else: b.config(text='<-> ' + btnLabel)
# sort by col
tableData.sort(key=lambda x: x[col], reverse=direction<0)
#clear widget
self.delete(0,END)
# refill widget
for row in range(rowcount):
self.insert(END, tableData[row])
# toggle direction flag
if direction == 1:
direction = -1
else:
direction = direction + 1
self.colmapping[b] = (col, direction)
# =:> End of complete _sort(self, e) <:= #
...
if __name__ == '__main__':
tk = Tk()
Label(tk, text='SortableMultiListbox').pack()
mlb = MultiListbox(tk, (('Subject', 40), ('Sender', 20), ('Date', 10)))
for i in range(1000):
mlb.insert(END, ('Important Message: %d' % i, 'John Doe', '10/10/%04d' % (1900+i)))
mlb.pack(expand=YES,fill=BOTH)
tk.mainloop()
【问题讨论】:
标签: python python-2.7 python-3.x tkinter