How Do I Simulate A Scrollbar In Tkinter Canvas
Solution 1:
How do i simulate a Scrollbar in Tkinter Canvas
The scrollbar has a well defined interface. To simulate a scrollbar all you need to do is implement this interface. This is most easily done by creating a class that has the following attributes:
- you need to define the
set
method, which is called whenever the widget being scrolled wants to update the scrollbar - you need to add mouse bindings to call the
yview
method of the widget being controlled by the scrollbar (orxview
if creating a horizontal widget).
If you do those two things, your scrollbar can be used exactly like a built-in scrollbar.
For the rest of this answer, I'm going to assume you want to simulate a vertical scrollbar. Simulating a horizontal scrollbar works identically, but instead of 'top' and 'bottom', you are dealing with 'left' and right'.
Defining the set method
The set method will be called with two fractions. The canonical documentation describes it like this:
This command is invoked by the scrollbar's associated widget to tell the scrollbar about the current view in the widget. The command takes two arguments, each of which is a real fraction between 0 and 1. The fractions describe the range of the document that is visible in the associated widget. For example, if first is 0.2 and last is 0.4, it means that the first part of the document visible in the window is 20% of the way through the document, and the last visible part is 40% of the way through.
Defining the bindings
The other half of the equation is when the user interacts with the scrollbar to scroll another widget. The way this happens is that the scrollbar should call the yview
command of the widget to be controlled (eg: canvas, text, listbox, etc).
The first argument you must pass to the command is either the string "moveto" or "scroll".
If "moveto", the second argument is a fraction which represents the amount that has been scrolled off of the top. This is typically called when clicking on the scrollbar, to immediately move the scrollbar to a new position
if "scroll", the second argument is an integer representing an amount, and the third argument is either the string "units" or "pages". The definition of "units" refers to the value of the
yscrollincrement
option. "pages" represents 9/10ths of the window height. This is typically called when dragging the mouse over the scrollbar.
The options are spelled out in the man pages for each scrollable widget.
Example
The following is an example of a uses a text widget, so that you can see that when you type, the scrollbar properly grows and shrinks. If you click anywhere in the scrollbar, it will scroll to that point in the documentation.
To keep the example short, this code doesn't handle dragging the scrollbar, and it hard-codes a lot of values that probably ought to be configurable. The point is to show that all you need to do to simulate a scrollbar is create a class that has a set
method and which calls the yview
or xview
method of the connected widget.
First, the scrollbar class
import tkinter as tk
classCustomScrollbar(tk.Canvas):
def__init__(self, parent, **kwargs):
self.command = kwargs.pop("command", None)
tk.Canvas.__init__(self, parent, **kwargs)
# coordinates are irrelevant; they will be recomputed# in the 'set' method
self.create_rectangle(0,0,1,1, fill="red", tags=("thumb",))
self.bind("<ButtonPress-1>", self.on_click)
defset(self, first, last):
first = float(first)
last = float(last)
height = self.winfo_height()
x0 = 2
x1 = self.winfo_width()-2
y0 = max(int(height * first), 0)
y1 = min(int(height * last), height)
self.coords("thumb", x0, y0, x1, y1)
defon_click(self, event):
y = event.y / self.winfo_height()
self.command("moveto", y)
Using the class in a program
You would use this class exactly like you would a native scrollbar: instantiate it, and set the command to be the yview
command of a scrollable widget.
This example uses a text widget so you can see the scrollbar updating as you type, but the exact same code would work with a Canvas, or any other scrollable window.
root = tk.Tk()
text = tk.Text(root)
sb = CustomScrollbar(root, width=20, command=text.yview)
text.configure(yscrollcommand=sb.set)
sb.pack(side="right", fill="y")
text.pack(side="left", fill="both", expand=True)
with open(__file__, "r") as f:
text.insert("end", f.read())
root.mainloop()
Post a Comment for "How Do I Simulate A Scrollbar In Tkinter Canvas"