Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Sample code usable Tkinter listbox

19 views
Skip to first unread message

Alf P. Steinbach

unread,
Feb 28, 2010, 7:30:12 PM2/28/10
to
In case Someone Else(TM) may need this.

This code is just how it currently looks, what I needed for my code, so it's not
a full-fledged or even tested class.

But it works.


<code language="Py3">
import tkinter as t
import tkinter.simpledialog
import tkinter.messagebox
t.askstring = tkinter.simpledialog.askstring
t.warningbox = tkinter.messagebox.showwarning

class UsableListbox( t.Frame ):
def __init__( self, parent_widget ):
t.Frame.__init__( self, parent_widget )
scrollbar = t.Scrollbar( self, orient = "vertical" )
self.lb = t.Listbox( self, yscrollcommand = scrollbar.set )
scrollbar.config( command = self.lb.yview )
scrollbar.pack( side = "right", fill = "y" )
self.lb.pack( side = "left", fill = "both", expand = 1 )

def current_index( self ):
indices = self.lb.curselection()
assert( len( indices ) <= 1 ) # TODO: about multi-selection.
return None if len( indices ) == 0 else int( indices[0] )

def current( self ):
#return self.lb.get( "active" ) # Incorrect with mousing
i = self.current_index()
return "" if i is None else self.lb.get( i )

def append( self, item ):
return self.lb.insert( "end", item )

def add_selection_event_handler( self, handler ):
"An event handler takes one argument, a Tkinter Event"
return self.lb.bind( "<<ListboxSelect>>", handler )
</code>


Cheers,

- Alf

Message has been deleted

Alf P. Steinbach

unread,
Feb 28, 2010, 10:57:32 PM2/28/10
to
* rantingrick:

> On Feb 28, 6:30 pm, "Alf P. Steinbach" <al...@start.no> wrote:
>> In case Someone Else(TM) may need this.
>>
>> This code is just how it currently looks, what I needed for my code, so it's not
>> a full-fledged or even tested class.
>
> Thanks for sharing Alf,
> Thats works fine "as-is" but what about inheriting from "tk.Listbox"
> directly and having the "container frame" as an attribute? I prefer
> this API because I hate to write the laborious
> "megawidget.mainwidget.methodX()" when i could instead write
> "megawidget.methodX()". What is your opinion on this?

Well the frame contains a listbox and scrollbar. And with the frame as attribute
the object that you have a direct reference to would then not be the complete
thing on screen, with respect to sizing and placement and such. I generally
don't like widgets that present stuff outside their bounding box. I guess that
could be fixed up somehow by overriding this and that, but I find it simpler to
just make the enclosing widget the widget that one has a reference to. And in a
way it's also good that it's more laborious to directly access the tkinter
listbox stuff, because what I discovered so far is that much of it requires work
arounds and fixups, i.e. that it should be wrapped in higher level methods.

I had to add some more such functionality after I posted that code.

So, current (this is untested except that it works for what I'm using it for!):


<code language="Py3">


class UsableListbox( t.Frame ):
def __init__( self, parent_widget ):
t.Frame.__init__( self, parent_widget )
scrollbar = t.Scrollbar( self, orient = "vertical" )

self.lb = t.Listbox( self, exportselection = 0, yscrollcommand =

scrollbar.set )
scrollbar.config( command = self.lb.yview )
scrollbar.pack( side = "right", fill = "y" )
self.lb.pack( side = "left", fill = "both", expand = 1 )

def current_index( self ):
indices = self.lb.curselection()
assert( len( indices ) <= 1 ) # TODO: about multi-selection.
return None if len( indices ) == 0 else int( indices[0] )

def current( self ):
#return self.lb.get( "active" ) # Incorrect with mousing
i = self.current_index()
return "" if i is None else self.lb.get( i )

def item_count( self ):
return self.lb.size()

def clear( self ):
self.lb.delete( 0, "end" )

def append( self, item ):
return self.lb.insert( "end", item )

def select_item( self, i ):
assert( 0 <= i < self.item_count() )
self.lb.selection_set( i )

Message has been deleted

Alf P. Steinbach

unread,
Mar 1, 2010, 7:19:32 AM3/1/10
to
* rantingrick:
>
> kw.setdefault('activestyle', 'none')

Hm, let me steal this line... Thanks!


Cheers,

- Alf

Message has been deleted

Alf P. Steinbach

unread,
Mar 3, 2010, 1:51:23 PM3/3/10
to
* Alf P. Steinbach:

> In case Someone Else(TM) may need this.
>
> This code is just how it currently looks, what I needed for my code, so
> it's not a full-fledged or even tested class.
>
> But it works.


That code evolved a little to cover more Tk listbox quirks (thanks to Ratingrick
for the "activestyle"):


<code>


class UsableListbox( t.Frame ):
def __init__( self, parent_widget ):
t.Frame.__init__( self, parent_widget )
scrollbar = t.Scrollbar( self, orient = "vertical" )
self.lb = t.Listbox(
self,

exportselection = 0, activestyle = "none", selectmode = "browse",


yscrollcommand = scrollbar.set
)
scrollbar.config( command = self.lb.yview )
scrollbar.pack( side = "right", fill = "y" )
self.lb.pack( side = "left", fill = "both", expand = 1 )

def current_index( self ):
indices = self.lb.curselection()
assert( len( indices ) <= 1 ) # TODO: about multi-selection.
return None if len( indices ) == 0 else int( indices[0] )

def item_at( self, i ):


assert( 0 <= i < self.item_count() )

return "" if i is None else self.lb.get( i )

def current( self ):


#return self.lb.get( "active" ) # Incorrect with mousing

return self.item_at( self.current_index() )

def item_count( self ):
return self.lb.size()

def clear( self ):
self.lb.delete( 0, "end" )

def append( self, item ):

self.lb.insert( "end", item )

return self.item_count() - 1

def scroll_into_view( self, i ):
self.lb.see( i )

def select_item( self, i ):
assert( 0 <= i < self.item_count() )

old_i = self.current_index();
self.scroll_into_view( i )
if old_i is not None and old_i == i:
return
self.lb.selection_set( i )
if old_i is not None:
self.lb.selection_clear( old_i )

Message has been deleted
0 new messages