[Tutor] Scrolling multilistbox help

Michael Lange klappnase at freenet.de
Tue Jul 19 11:06:43 CEST 2005


On Mon, 18 Jul 2005 13:54:45 +0000
"Alberto Troiano" <albertito_g at hotmail.com> wrote:

> Hey tutors
> 
> I'm using the Multilistbox class and I noticed that it only handles the 
> mouse scroll and the scrollbar to go down or up.I succesfully implemented 
> the sort function that came with the class
> I also added code to handle the up and down arrow keys and it goes down all 
> right but only select the item and it doesn't scroll down or up
> 
> How can make it go up or down?
> I'm sendind the class here:
> 

Hi Alberto,

I haven't tested your code, but if I understand you correctly, the problem
is that the list is not automatically scrolled when you select a new item with
the Up and Down keys (right?).
Maybe it's the easiest to add a line like this to your _select1() and _select2() methods:

   l.see(int(l.curselection()[0]))

where l is the first of the listboxes; this should make sure the selected item is visible
(at least if you use selectmode=SINGLE). If keeping all lists in sync works, this
should be enough to scroll all other lists, too (like I said, untested though).

I hope this helps

Michael



> class MultiListbox(Frame):
>     fila=0
>     sortedBy=-1
>     def __init__(self, master, lists):
> 	Frame.__init__(self, master)
> 	self.lists = []
> 	for l,w,a in lists:
> 	    frame = Frame(self,background="red"); frame.pack(side=LEFT, expand=YES, 
> fill=BOTH)
> 	    Button(frame,background="red",foreground="white",font="Verdana 8 
> bold",text=l, borderwidth=1, relief=RAISED,command=lambda a=a: 
> self._sortBy(a)).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('<B1-Motion>', lambda e, s=self: s._select(e.y))
> 	    lb.bind('<Double-Button-3>', lambda e, s=self: s._devolverfila(e.y))
> 	    lb.bind('<Return>', lambda e, s=self: s._devolverfila(e.y))
> 	    lb.bind('<Button-1>', lambda e, s=self: s._select(e.y))
> 	    lb.bind('<Down>', lambda s: _select1())
>                     lb.bind('<Up>', lambda s: _select2())
> 	    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,background="red"); frame.pack(side=LEFT, fill=Y)
> 	Label(frame,background="red",foreground="white",font="Verdana 8 bold", 
> borderwidth=1, relief=RAISED).pack(fill=X)
> 	sb = Scrollbar(frame,background="red", orient=VERTICAL, 
> command=self._scroll)
> 	sb.pack(expand=YES, fill=Y)
> 	self.lists[0]['yscrollcommand']=sb.set
> 
>     def _sortBy(self, column):
>         """ Sort by a given column. """
>         if column == self.sortedBy:
>             direction = -1 * self.direction
>         else:
>             direction = 1
>         elements = self.get(0, END)
>         self.delete(0, END)
>         elements.sort(lambda x, y: self._sortAssist(column, direction, x, 
> y))
>         self.insert(END, *elements)
>         self.sortedBy = column
>         self.direction = direction
> 
>     def _sortAssist(self, column, direction, x, y):
>         if column!=0:
>             c = cmp(x[column], y[column])
>             if c:
>                 return direction * c
>             else:
>                 return direction * cmp(x, y)
>         else:
>             c = cmp(int(x[column]), int(y[column]))
>             if c:
>                 return direction * c
>             else:
>                 return direction * cmp(x, y)
> 
>     def _select(self, y):
> 	row = self.lists[0].nearest(y)
> 	self.selection_clear(0, END)
> 	self.selection_set(row)
> 	self.fila=row
> 	return 'break'
> 
>     def _devolverfila(self, y):
> 	row = self.lists[0].nearest(y)
> 	self.selection_clear(0, END)
> 	self.selection_set(row)
> 	self.fila=row
> 
>     def _select1(self):
>         if self.fila==self.size()-1:
>             pass
>         else:
>             self.selection_clear(0, END)
>     	    self.selection_set(self.fila+1)
>             self.fila+=1
>             self._scroll()
> 	return 'break'
> 
>     def _select2(self):
>     	if self.fila==0:
>             pass
>         else:
>             self.selection_clear(0, END)
>             self.selection_set(self.fila-1)
>             self.fila-=1
> 	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:
> 	    apply(l.yview, args)
> 
>     def curselection(self):
> 	return self.lists[0].curselection()
> 
>     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 apply(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)
> 
> 
> THanks in advanced
> 
> Alberto
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
> 


More information about the Tutor mailing list