183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""A ScrolledText widget feels like a text widget but also has a
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehvertical scroll bar on its right.  (Later, options may be added to
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehadd a horizontal bar as well, to make the bars disappear
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehautomatically when not needed, to move them to the other side of the
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehwindow, etc.)
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehConfiguration options are passed to the Text widget.
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehA Frame widget is inserted between the master and the text, to hold
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehthe Scrollbar widget.
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehMost methods calls are inherited from the Text widget; Pack, Grid and
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehPlace methods are redirected to the Frame widget however.
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh__all__ = ['ScrolledText']
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom Tkinter import Frame, Text, Scrollbar, Pack, Grid, Place
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom Tkconstants import RIGHT, LEFT, Y, BOTH
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass ScrolledText(Text):
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __init__(self, master=None, **kw):
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.frame = Frame(master)
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.vbar = Scrollbar(self.frame)
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.vbar.pack(side=RIGHT, fill=Y)
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        kw.update({'yscrollcommand': self.vbar.set})
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Text.__init__(self, self.frame, **kw)
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.pack(side=LEFT, fill=BOTH, expand=True)
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.vbar['command'] = self.yview
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Copy geometry methods of self.frame without overriding Text
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # methods -- hack!
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        text_meths = vars(Text).keys()
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        methods = vars(Pack).keys() + vars(Grid).keys() + vars(Place).keys()
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        methods = set(methods).difference(text_meths)
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for m in methods:
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if m[0] != '_' and m != 'config' and m != 'configure':
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                setattr(self, m, getattr(self.frame, m))
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __str__(self):
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return str(self.frame)
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef example():
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    import __main__
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    from Tkconstants import END
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    stext = ScrolledText(bg='white', height=10)
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    stext.insert(END, __main__.__doc__)
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    stext.pack(fill=BOTH, side=LEFT, expand=True)
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    stext.focus_set()
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    stext.mainloop()
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == "__main__":
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    example()
56