Thursday, July 26, 2012

Tkinter Listbox Famous Sayings Demo

This code is based on the Tcl sayings.tcl demo; it demonstrates the use of both Horizontal and Vertical scrollbars within a Listbox as well as resizing properties; when the window is maximized the listbox is given the extra space.


# File: listboxsayings.py
# References:
#    http://infohost.nmt.edu/tcc/help/pubs/tkinter//listbox.html
#    http://www.tcl.tk/man/tcl8.5/TkCmd/listbox.htm
#    http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_scrollbar.htm

from tkinter import *
from tkinter import ttk
from demopanels import MsgPanel, SeeDismissPanel

SAYINGS = (
    "Waste not, want not.",
    "Early to bed and early to rise makes a man healthy, wealthy, and wise.",
    "Ask not what your country can do for you, ask what you can do for your country.",
    "I shall return, NOT!",
    "A picture is worth a thousand words.",
    "User interfaces are hard to build.",
    "Thou shalt not steal.",
    "A penny for your thoughts.",
    "Fool me once, shame on you;  fool me twice, shame on me. Fool me thrice, and I'm the fool.",
    "Every cloud has a silver lining.",
    "Where there's smoke there's fire.",
    "It takes one to know one.",
    "Curiosity killed the cat.",
    "Take this job and shove it.",
    "Up a creek without a paddle.",
    "I'm mad as hell and I'm not going to take it any more.",
    "An apple a day keeps the doctor away.",
    "Don't look a gift horse in the mouth."
    )

class ListboxSayingsDemo(ttk.Frame):
    
    def __init__(self, isapp=True, name='listboxsayingsdemo'):
        ttk.Frame.__init__(self, name=name)
        self.pack(expand=Y, fill=BOTH)
        self.master.title('Listbox Famous Sayings Demo')
        self.isapp = isapp
        self._create_widgets()
        
    def _create_widgets(self):
        if self.isapp:
            MsgPanel(self, 
                     ["The listbox below contains a collection of well-known sayings.  ",
                      "You can scan the list either using the scrollbar or by scanning.\n\n",
                      "To scan, click in the listbox, hold the left mouse button down, and drag up or down."])
            
            SeeDismissPanel(self)
        
        self._create_demo_panel()
        
    def _create_demo_panel(self):
        demoPanel = ttk.Frame(self)
        demoPanel.pack(side=TOP, fill=BOTH, expand=Y)
                
        self._sayings_lb(demoPanel)        
                
    def _sayings_lb(self, parent):
        f = ttk.Frame(parent, borderwidth='.5c')
        
        # create and populate the listbox
        # 'setgrid' allows the widget to
        # control the resize dimension (i.e. character
        # vs pixel) used by the grid in its top-level window
        # 'height' = number of lines (not pixels)
        # 'width' = number of characters (not pixels)
        lb = Listbox(setgrid=True, height=10, width=20)
        lb.insert(END, *SAYINGS)
        
        # create scrollbars
        ysb = ttk.Scrollbar(orient=VERTICAL)
        xsb = ttk.Scrollbar(orient=HORIZONTAL)
        
        # attach scrollbars to the listbox
        ysb['command'] = lb.yview
        xsb['command'] = lb.xview
        lb['yscroll'] = ysb.set
        lb['xscroll'] = xsb.set
        
        # position the listbox and scrollbars        
        lb.grid(in_=f, row=0, column=0, rowspan=1, columnspan=1, sticky=NSEW)   
        ysb.grid(in_=f, row=0, column=1, rowspan=1, columnspa=1, sticky=NSEW)
        xsb.grid(in_=f, row=1, column=0, rowspan=1, columnspan=1, sticky=NSEW)
        
        # define which rows and columns get extra space on resize
        f.rowconfigure(0, weight=1, minsize=0)
        f.columnconfigure(0, weight=1, minsize=0)
        
        # make the frame holding the widgets resizeable
        f.pack(side=TOP, fill=BOTH, expand=Y)
             
if __name__ == '__main__':
    ListboxSayingsDemo().mainloop()