Tkinter, problem when using 2 scrollbars

Bryan Castillo rook_5150 at yahoo.com
Mon Oct 21 16:14:52 EDT 2002


> > I'd whip something up real quick, but I don't have Tk on this machine.
> >
> > Jeff
> >
> >
> 
> How's this:
> 
> class ScrolledListbox(Frame):
>     def __init__(self, parent):


I posted a few hours ago, and it hasn't shown up for me yet.  I should
have done more work before posting the last message.  Anyway, I was
wondwering how one might implement a Class/Function that would create
a widget with scrollbars, using a parameter to determine and create
the original widget within the bars. (Something like the Scrolled
method in perl/Tk).  So I came up with a function that takes a widget
class, derives a new subclass from it, instantiates it and adds
scrollbars to it (Based on ScrolledText).  This should work for the
original poster's problem, and be more extensible.  I am wondering if
there are any problems with my code or if there are better ways to do
this.





from Tkinter import *
from Tkinter import _cnfmerge
import new
import sys

def Scrolled(master, wclass, cnf=None, **kw):

  # Parts stolen from ScrolledText
  if cnf is None: cnf = {}
  if kw:          cnf = _cnfmerge((cnf, kw))

  # figure out where scrollbars should go and if there are any
  scrollbars = "se"
  if cnf.has_key("scrollbars"):
    scrollbars = cnf["scrollbars"]
    del cnf["scrollbars"]

  wrow=0; wcol=0
  hscrrow=0; hscrcol=0; do_hscr=0
  vscrrow=0; vscrcol=0; do_vscr=0 

  for c in scrollbars:
    if   c == "e": do_vscr=1; vscrcol=1; wcol=0; hscrcol=0
    elif c == "w": do_vscr=1; vscrcol=0; wcol=1; hscrcol=1
    elif c == "n": do_hscr=1; hscrrow=0; wrow=1; vscrrow=1
    elif c == "s": do_hscr=1; hscrrow=1; wrow=0; vscrrow=0

  frame = apply(Frame, (master,))

  # Create new class type inheriting from wclass
  # I'm not sure if I should do something with 3rd arg dict
  t_class  = new.classobj("Scrolled"+wclass.__name__, (wclass,), {})

  # Instantiate new type and call constructor
  t_widget = new.instance(t_class)
  apply(t_class.__init__, (t_widget, frame,), cnf)
 
  t_widget.frame = frame

  # Create scrollbars
  if do_vscr:
    t_widget.vbar = Scrollbar(t_widget.frame, orient=VERTICAL)
    t_widget.vbar.grid(row=vscrrow, column=vscrcol, sticky='ns')
    t_widget['yscrollcommand'] = t_widget.vbar.set
    t_widget.vbar['command']   = t_widget.yview

  if do_hscr:
    t_widget.hbar = Scrollbar(t_widget.frame, orient=HORIZONTAL)
    t_widget.hbar.grid(row=hscrrow, column=hscrcol, sticky='ew')
    t_widget['xscrollcommand'] = t_widget.hbar.set
    t_widget.hbar['command']   = t_widget.xview

  t_widget.grid(row=wrow, column=wcol, sticky='nsew')
  t_widget.frame.grid_columnconfigure(wcol, weight=1)
  t_widget.frame.grid_rowconfigure(wrow, weight=1)

  # Copy geometry methods of t_widget.frame -- hack!
  for geo_m in (Pack, Grid, Place):
    for method in getattr(geo_m, "__dict__"):
      if method[0] != '_' and method != 'config' and method !=
'configure':
        setattr(t_widget, method, getattr(t_widget.frame, method))

  return t_widget


class TkTestApp:

  def on_exit(self, event):
    print "Exit"   
    self.tk.destroy()
    sys.exit(0) 

  def __init__(self):
    self.tk = Tk()
    self.tk.title("TkTestApp")

    # Test Text widget
    self.text = Scrolled(self.tk, Text, 
	scrollbars = "sw",
	foreground = "blue", 
        wrap       = "none"
    )
    self.text.grid(row=1, column=0, sticky=N+S+E+W)

    # Test List widget
    self.list = Scrolled(self.tk, Listbox, 
        selectmode = "extended",
	scrollbars = "e",
    )
    for i in range(1,10):
      self.list.insert("end", ("option %d" % i))
    self.list.grid(row=0, column=0, sticky=N+S+E+W)

    self.tk.grid_rowconfigure(0, weight=1)
    self.tk.grid_rowconfigure(1, weight=1)
    self.tk.grid_columnconfigure(0, weight=1)

    self.list.bind("<Button-2>", self.on_exit)
    self.list.bind("<Button-3>", self.on_exit)
    self.tk.mainloop()

TkTestApp()



More information about the Python-list mailing list