Travis Valdez
Travis Valdez

Reputation: 97

Tkinter; Using a Scrollbar in a Canvas

I'm trying to create a scrollbar in part of my program. The parent frame has three label frame widgets, one of which needs to display as many as 50 option menus, making a scrollbar desirable.

I know you can't use a scrollbar to scroll a label frame, so inside this label frame I've created a canvas, which can be scrolled. I've then inserted a frame inside the canvas, which I'll use to display the option menus. I then attach a scrollbar to the canvas, and the scrollbar is placed inside the label frame. The problem is that the scrollbar looks functional, but only the first 10 option menus are visible, no matter how much it appears I've scrolled. Here is an example below:

from Tkinter import *

app = Tk()
app.title("Example App")
app.geometry("550x400+300+300")

# Creating the first label frame
entryframe = LabelFrame(app,text="Entry",width=250,height=250)
entryframe.pack(side="top",fill=BOTH)

# Creating a frame to contain the options selected by the user; also using a canvas & 
# label frame to enable the use of a scrollbar
outcomesframe = LabelFrame(app,text="User Input",width=250,height=650)
outcomesframe.pack(side="left",fill=BOTH)
outcomescanvas = Canvas(outcomesframe,relief=SUNKEN)
outcomescanvas.config(width=230,height=650)
outcomescanvas.config(scrollregion=(0,0,300,1000))
outcomescanvas.config(highlightthickness=0)

# Creating scrollbar
scrollbar = Scrollbar(outcomesframe)
scrollbar.config(command=outcomescanvas.yview)
outcomescanvas.config(yscrollcommand=scrollbar.set)
scrollbar.pack(side="right",fill=Y)
outcomescanvas.pack(side="left",expand=YES,fill=BOTH)

# Creating the frame in which the option menus will be inserted
outcomesframe2 = Frame(outcomescanvas,width=230,height=1000)
outcomesframe2.pack(side="top",fill=BOTH)

# Creating the third label frame
statsframe = LabelFrame(app,text="Third Label Frame",width=250,height=250)
statsframe.pack(side="right",fill=BOTH)

# Creating the option menus
for i in range(50):
    vars()["labeltext"+str(i)] = StringVar()
    vars()["labeltext"+str(i)].set("Menu"+str(i+1)+":")
    vars()["label"+str(i)] = Label(outcomesframe2,textvariable=vars()["labeltext"+str(i)])
    vars()["label"+str(i)].grid(row=i,column=0)

    vars()["variable"+str(i)] = StringVar()
    vars()["variable"+str(i)].set("Select...")
    vars()["menu"+str(i)] = OptionMenu(outcomesframe2,vars()["variable"+str(i)],"Option1","Option2")
    vars()["menu"+str(i)].pack()

app.mainloop()

Upvotes: 2

Views: 779

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385870

When you scroll a canvas, it only scrolls items that are canvas objects. That means you must use create_window to place a window in the canvas, rather than using pack or grid.

...
outcomescanvas.create_window(0,0,window=outcomesframe2, anchor="nw")
...

Upvotes: 0

Related Questions