Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to code the tkinter "scrolledtext" module

The code below produces an ugly but functional example of using a scroll bar in a text widget and results in a couple of questions. Note: this is done using Python 3 on a windows box.

  1. The scroll bar that appears is attached to the frame and although it scrolls the text box contents, I would prefer that it was attached to the text widget itself. I have been unable to get this to happen.

  2. There are a number of references to a Tkinter module called "scrolledtext" that is supposed to be a much better mechanism for adding scrollbars to text boxes but, I have not found any examples of how to import it and call it that I am able to get to work (probably need an example).


frame1 = tk.Frame(win,width=80, height=80,bg = '#808000')
frame1.pack(fill='both', expand='yes')
scrollbar = Scrollbar(frame1) 
scrollbar.pack(side=RIGHT, fill=Y)
editArea = Text(frame1, width=10, height=10, wrap=WORD, yscrollcommand=scrollbar.set)
editArea.pack()    
scrollbar.config(command=editArea.yview)
editArea.place(x=10,y=30)
like image 633
Bill Waters Avatar asked Jul 15 '13 14:07

Bill Waters


People also ask

What is ScrolledText in Tkinter?

The tkinter. scrolledtext module provides a class of the same name which implements a basic text widget which has a vertical scroll bar configured to do the “right thing.” Using the ScrolledText class is a lot easier than setting up a text widget and scroll bar directly.

How do I add a scrollbar to my text widget?

In order to create a Text widget, we have to instantiate a text object. Adding multiple texts will require to add the ScrollBar. In order to add a scrollbar in the text widget, we can call the ScrolledText(root) function. This function generally creates a text field with a scrollbar.

What is Python tkinter command?

In Tkinter, some widgets allow you to associate a callback function with an event using the command binding. It means that you can assign the name of a function to the command option of the widget so that when the event occurs on the widget, the function will be called automatically.


2 Answers

You were right, you can use the ScrolledText widget from tkinter.scrolledtext module, like this:

import tkinter as tk import tkinter.scrolledtext as tkst  win = tk.Tk() frame1 = tk.Frame(     master = win,     bg = '#808000' ) frame1.pack(fill='both', expand='yes') editArea = tkst.ScrolledText(     master = frame1,     wrap   = tk.WORD,     width  = 20,     height = 10 ) # Don't use widget.place(), use pack or grid instead, since # They behave better on scaling the window -- and you don't # have to calculate it manually! editArea.pack(padx=10, pady=10, fill=tk.BOTH, expand=True) # Adding some text, to see if scroll is working as we expect it editArea.insert(tk.INSERT, """\ Integer posuere erat a ante venenatis dapibus. Posuere velit aliquet. Aenean eu leo quam. Pellentesque ornare sem. Lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Cum sociis natoque penatibus et magnis dis. Parturient montes, nascetur ridiculus mus. """) win.mainloop() 

And there you go:

enter image description here

like image 187
Peter Varo Avatar answered Oct 12 '22 02:10

Peter Varo


While using the ScrolledText widget might save you a few lines of code, it's not doing anything you can't do yourself. Doing it yourself will help remove some of the mystery.

You're actually doing everything almost correct. The mistake you're making is that you should have your text widget fill it's container completely rather than being just a tiny part of it.

The standard way to do this is like this:

container = tk.Frame(...)
text = tk.Text(container, ...)
scrollbar = tk.Scrollbar(container, ...)
scrollbar.pack(side="right", fill="y")
text.pack(side="left", fill="both", expand=True)

That's all there is to it. Now, no matter how big your container gets due to window resizes, etc, the scrollbar will always appear attached to the text widget. You then treat this whole group of container, text widget and scrollbar as a single widget when adding it to your whole GUI.

Note that you can use grid here as well. Pack is easier if you only have a vertical scrollbar. If you have both horizontal and vertical scrollbars, grid makes a little more sense.

To complete the illusion, you can set the borderwidth of the text widget to zero, and set the borderwidth of the containing frame to 1 with a relief of sunken, and the scrollbar will appear to be "in" the text widget.

Here is a complete working example that looks more-or-less like your example:

import Tkinter as tk

win = tk.Tk()

win.configure(background="#808000")

frame1 = tk.Frame(win,width=80, height=80,bg = '#ffffff',
                  borderwidth=1, relief="sunken")
scrollbar = tk.Scrollbar(frame1) 
editArea = tk.Text(frame1, width=10, height=10, wrap="word",
                   yscrollcommand=scrollbar.set,
                   borderwidth=0, highlightthickness=0)
scrollbar.config(command=editArea.yview)
scrollbar.pack(side="right", fill="y")
editArea.pack(side="left", fill="both", expand=True)
frame1.place(x=10,y=30)

win.mainloop()

Personally I don't recommend doing global imports, and I don't recommend using place, but I wanted to keep this as close to your original as possible.

like image 31
Bryan Oakley Avatar answered Oct 12 '22 00:10

Bryan Oakley