Georgi Georgiev
Georgi Georgiev

Reputation: 1623

Can not make vertical scroll work on canvas

I want to place for example 20 text boxes in a Canvas. So my widget hierarchy is main window -> canvas -> text boxes. The text boxes can not fit all in the canvas, so I want to attach a vertical scroll bar to it. Here is what I've tried:

from tkinter import *
root = Tk()
root_height = root.winfo_screenheight()
root_width = root.winfo_screenwidth()
root.geometry("%dx%d+0+0" % (root_width, root_height))

canvas = Canvas(root, height=root_height, width=root_width)
canvas.pack(fill=BOTH, expand=1)

scrollbar = Scrollbar(canvas)
scrollbar.pack(side=RIGHT, fill=Y)
canvas.config(yscrollcommand=scrollbar.set)

textBoxes = []

for i in range(0, 20):
    textBoxes.append(Text(canvas, height=1, width=20, bd=2))

y_offset = 15
for i in range(0, 20):
    textBoxes[i].place(x=10, y=y_offset)
    y_offset += 60

scrollbar.config(command=canvas.yview)


mainloop()

So basically, I tried to do what I've understood from tutorials and other questions -

  1. Set the widget’s(canvas) yscrollcommand callbacks to the set method of the scrollbar.

  2. Set the scrollbar’s command to the yview method of the widget(canvas).

Unfortunately the scrollbar appears unclickable. Where I am wrong and how can I achieve the desired behaviour?

Upvotes: 2

Views: 187

Answers (2)

tijko
tijko

Reputation: 8302

You can use a separate Frame widget that contains all the Text objects. Then in Canvas make a call to the .create_window method setting Frame as the window argument.

from tkinter import *

root = Tk()
root_width = root.winfo_screenwidth()
root_height = root.winfo_screenheight()

canvas = Canvas(root)
canvas.pack(side=LEFT, fill=BOTH, expand=True)

scrollbar = Scrollbar(root, orient=VERTICAL)
scrollbar.pack(side=RIGHT, fill=Y)

frame = Frame(canvas)
frame.pack(fill=BOTH, expand=True)

def resize(event):
    canvas.configure(scrollregion=canvas.bbox(ALL))

canvas.create_window((0, 0), window=frame, anchor=NW)

canvas.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=canvas.yview)
frame.bind('<Configure>', resize)

for i in range(20):
    text = Text(frame, width=30, height=1)
    text.grid(row=i, pady=i*10)

mainloop()

Upvotes: 2

Bryan Oakley
Bryan Oakley

Reputation: 386010

Scrollbars only scroll canvas objects. It will not scroll widgets added inside the canvas with pack, place or grid. For a widget to be scrollable it must be added with canvas.create_window(...).

Upvotes: 1

Related Questions