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.
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.
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)
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.
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.
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.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With