| SortableTable |
UserPreferences |
| Tkinter Wiki | FrontPage | RecentChanges | TitleIndex | WordIndex | SiteNavigation | HelpContents | moin.sf.net |
Go to http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52266 and download Brent Burley's excellent widget, then copy over the following methods to make it sortable by clicking on column header
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | def __init__(self, master, lists):
Frame.__init__(self, master)
self.lists = []
self.colmapping={}
self.origData = None
for l,w in lists:
frame = Frame(self); frame.pack(side=LEFT, expand=YES, fill=BOTH)
b = Button(frame, text=l, borderwidth=1, relief=RAISED)
b.pack(fill=X)
b.bind('<Button-1>', self._sort)
self.colmapping[b]=(len(self.lists),1)
lb = Listbox(frame, width=w, borderwidth=0, selectborderwidth=0,
relief=FLAT, exportselection=FALSE)
lb.pack(expand=YES, fill=BOTH)
self.lists.append(lb)
lb.bind('<B1-Motion>', lambda e, s=self: s._select(e.y))
lb.bind('<Button-1>', lambda e, s=self: s._select(e.y))
lb.bind('<Leave>', lambda e: 'break')
lb.bind('<B2-Motion>', lambda e, s=self: s._b2motion(e.x, e.y))
lb.bind('<Button-2>', lambda e, s=self: s._button2(e.x, e.y))
frame = Frame(self); frame.pack(side=LEFT, fill=Y)
Label(frame, borderwidth=1, relief=RAISED).pack(fill=X)
sb = Scrollbar(frame, orient=VERTICAL, command=self._scroll)
sb.pack(expand=YES, fill=Y)
self.lists[0]['yscrollcommand']=sb.set
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.keys():
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
def colsort(x, y, mycol=col, direction=direction):
return direction*cmp(x[mycol], y[mycol])
tableData.sort(colsort)
#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 += 1
self.colmapping[b] = (col, direction) |
Screenshots: Original listbox, modified sortable listbox