fernando
fernando

Reputation: 99

How to create a scrollbar in a canvas in tkinter using python 3.8

I have created a canvas c and I want to put a scrollbar in the canvas to scroll down and up all the things I put in the canvas (I'm planning to put a lot of things). But the scrollbar is not working. What I'm doing wrong?

from tkinter import *

root = Tk()

c=Canvas(root)
c.config(width=160,height=100)
c.grid(row=0,column=0)

Scrb=Scrollbar(root,orient=VERTICAL)
Scrb.grid(column=2)
c.config(scrollregion=c.bbox("all"))
c.config(yscrollcommand=Scrb.set)
Scrb.config(command=c.yview)

label = Label(c, text="this is to fill room")
label1 = Label(c, text="this is to fill room")
label2 = Label(c, text="this is to fill room")
label3 = Label(c, text="this is to fill room")
label4 = Label(c, text="this is to fill room")
label5 = Label(c, text="this is to fill room")
label6 = Label(c, text="this is to fill room")
list_labels = [label,label1,label2,label3,label4,label5,label6]

for i in range(0,7):
    list_labels[i].grid(row=i,column=0)

root.mainloop()

Upvotes: 0

Views: 137

Answers (1)

Joel Toutloff
Joel Toutloff

Reputation: 484

There are a few problems here. First, Labels are not canvas items, they are their own widgets that you are gridding in to the root. (While you did put the canvas as their parent, that doesn't work, but due to how canvas's work, it actually just passes that up to the root instead of erroring--which would be nice, but there are reasons it is this way.)

Next, you have overridden the 0, 0 grid that you put the canvas in with the first label (where i=0) so the canvas doesn't even show.

Next, you put the scrollbar in column 2 and just skipped column 1. There is nothing wrong with this (maybe you are going to put something in column one later, who knows,) I just want to make sure you knew what was happening there.

What you really need to figure out is if you are wanting to scroll a canvas or scroll some widgets (like labels, buttons etc.) If really want a scrolling canvas, take a look at http://effbot.org/zone/tkinter-scrollbar-patterns.htm#canvas For your convivence, I have included a snippet from there (with some added elements on the canvas so you can really see the scrolling) if you just want to copy and paste:

from tkinter import *
root = Tk()
frame = Frame(root, bd=2, relief=SUNKEN)

frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)

xscrollbar = Scrollbar(frame, orient=HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=E+W)

yscrollbar = Scrollbar(frame)
yscrollbar.grid(row=0, column=1, sticky=N+S)

canvas = Canvas(frame, bd=0, scrollregion=(0, 0, 1000, 1000),
                xscrollcommand=xscrollbar.set,
                yscrollcommand=yscrollbar.set)

canvas.grid(row=0, column=0, sticky=N+S+E+W)

xscrollbar.config(command=canvas.xview)
yscrollbar.config(command=canvas.yview)

for i in range(100):
    canvas.create_rectangle(
        i/10*100, i%10*100, i/10*100+50, i%10*100+50,
        fill='green')

frame.pack()

If you are actually just wanting a scroll area where you can put any widget you want in it, what people online seem to recommend is take the scrolling canvas and put a window in it, and then in that window add your items. So you were kinda on the right track to do that. You also want the scrollregion configuration to happen every time things are moved around and not just once when it is made. Here is a modified version of what you had:

from tkinter import *

root = Tk()
frame = Frame(root, width=160, height=100)
c=Canvas(frame)
c.config(width=160,height=100)
c.pack(side=LEFT)

def innerFrameGo(_):
    c.configure(scrollregion=c.bbox('all'))

inner_frame = Frame(c)
inner_frame.bind("<Configure>", innerFrameGo)
inner_frame_id = c.create_window(0,0,window=inner_frame,anchor=NW)

Scrb=Scrollbar(frame,orient=VERTICAL)
Scrb.pack(side=RIGHT, fill=Y)
c.configure(yscrollcommand=Scrb.set)
Scrb.config(command=c.yview)

frame.pack()

for i in range(0,7):
    label = Label(inner_frame, text="this is to fill room")
    label.grid(row=i, column=0)

root.mainloop()

P.S. about that list of Labels you made...if you are typing in things over and over, that is a good sign that there is an easier way to do what you are trying to do. Since you were going to have a for-loop anyway, I moved that part down there.

Upvotes: 2

Related Questions