分类: Python/Ruby
2013-01-16 17:07:47
网上多列列表都是for python2only的,找了好久也没有找到一个for python3的多列列表,重新写一个控件又较复杂,好不容易找到一个for python2的多列列表的源代码,修改成for python3的,贴在这里,给需要的朋友。
MOVE_LINES = 0 MOVE_PAGES = 1 MOVE_TOEND = 2 class MultiListbox(Frame): def __init__(self, master, lists): Frame.__init__(self, master) self.lists = [] for l,w in lists: frame = Frame(self); frame.pack(side=LEFT, expand=YES, fill=BOTH) Label(frame, text=l, borderwidth=1, relief=RAISED).pack(fill=X) 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('', lambda e, s=self: s._select(e.y)) lb.bind(' ', lambda e, s=self: s._select(e.y)) lb.bind(' ', lambda e: 'break') lb.bind(' ', lambda e, s=self: s._b2motion(e.x, e.y)) lb.bind(' ', lambda e, s=self: s._button2(e.x, e.y)) self.bind (' ', lambda e, s=self: s._move (-1, MOVE_LINES)) self.bind (' ', lambda e, s=self: s._move (+1, MOVE_LINES)) self.bind (' ', lambda e, s=self: s._move (-1, MOVE_PAGES)) self.bind (' ', lambda e, s=self: s._move (+1, MOVE_PAGES)) self.bind (' ', lambda e, s=self: s._move (-1, MOVE_TOEND)) self.bind (' ', lambda e, s=self: s._move (+1, MOVE_TOEND)) 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 _move (self, lines, relative=0): """ Move the selection a specified number of lines or pages up or down the list. Used by keyboard navigation. """ selected = self.lists[0].curselection() try: selected = list(map(int, selected)) except ValueError: pass try: sel = selected[0] except IndexError: sel = 0 old = sel size = self.lists [0].size() if relative == MOVE_LINES: sel = sel + lines elif relative == MOVE_PAGES: sel = sel + (lines * int (self.lists [0]['height'])) elif relative == MOVE_TOEND: if lines < 0: sel = 0 elif lines > 0: sel = size - 1 else: print("MultiListbox._move: Unknown move type!") if sel < 0: sel = 0 elif sel >= size: sel = size - 1 self.selection_clear (old, old) self.see (sel) self.selection_set (sel) return 'break' def _select(self, y): row = self.lists[0].nearest(y) self.selection_clear(0, END) self.selection_set(row) self.focus_force() return 'break' def _button2(self, x, y): for l in self.lists: l.scan_mark(x, y) return 'break' def _b2motion(self, x, y): for l in self.lists: l.scan_dragto(x, y) return 'break' def _scroll(self, *args): for l in self.lists: l.yview(*args) return 'break' def curselection(self): return self.lists[0].curselection() def itemconfigure(self, row_index, col_index, cnf=None, **kw): lb = self.lists[col_index] return lb.itemconfigure(row_index, cnf, **kw) def rowconfigure(self, row_index, cnf={}, **kw): for lb in self.lists: lb.itemconfigure(row_index, cnf, **kw) def delete(self, first, last=None): for l in self.lists: l.delete(first, last) def get(self, first, last=None): result = [] for l in self.lists: result.append(l.get(first,last)) #if last: # return map(*([None] + result)) return result def index(self, index): self.lists[0].index(index) def insert(self, index, *elements): for e in elements: i = 0 for l in self.lists: l.insert(index, e[i]) i = i + 1 def size(self): return self.lists[0].size() def see(self, index): for l in self.lists: l.see(index) def selection_anchor(self, index): for l in self.lists: l.selection_anchor(index) def selection_clear(self, first, last=None): for l in self.lists: l.selection_clear(first, last) def selection_includes(self, index): return self.lists[0].selection_includes(index) def selection_set(self, first, last=None): for l in self.lists: l.selection_set(first, last) def yview_scroll(self, *args, **kwargs): for lb in self.lists: lb.yview_scroll(*args, **kwargs)