简体   繁体   中英

Tkinter: Combining a Scrollbar with a Canvas

I know this isn't the first time a question like this is asked, but even after like 2 hours of browsing the Internet I can't get it to work:

So I'm trying to create a Tkinter-Frame, that contains several Buttons (As Example I took 30). But Because I don't have enough space in my program, I need to add an Scrollbar next to it, so that one can scroll through the Buttons.

The Problems I had where, that the inner "moving part" of the bar was as big as the whole scrollbar and couldn't be moved, which I kinda solved by using scollregion=(0,0,1000,1000) , but even then the moving of the bar had no effect on the canvas whatsoever.

Here Is the corresponding code that I extracted out of my program:

import Tkinter as tk

root = tk.Tk()
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=50)
root.columnconfigure(1, weight=1)

root.minsize(300,400)
root.maxsize(300,400)

#Buttons
buttonFrame = tk.Canvas(root, bg='#bbb')
buttonFrame.grid(row=0, column=0, sticky=tk.N+tk.E+tk.S+tk.W)
buttonFrame.columnconfigure(0, weight=1)

scroll = tk.Scrollbar(root, command=buttonFrame.yview)
scroll.grid(row=0, column=1, sticky=tk.N+tk.E+tk.S+tk.W)
buttonFrame.configure(yscrollcommand=scroll.set)

for i in range(30):
    tk.Button(buttonFrame, text=str(i+1)).grid(row=i, column=0, sticky=tk.N+tk.E+tk.S+tk.W)

root.mainloop()

As you (hopefully) see, the slider can't even be moved nor does it change anything on the canvas, even if I squeeze a scrollregion=(bla) somewhere in there.

2 Questions: a.) What do I need to add (or remove), so that I can scroll through the list of Buttons b.) Does the fix from a. still work when I make the Scrollbar a child of the buttonFrame instead of the root ?

To add widgets to a Canvas you have to use the create_window method, not grid() . Then you have to update the canvas before setting the scrollregion.

for i in range(30):
    btn = tk.Button(buttonFrame, text=str(i+1))
    buttonFrame.create_window((100,i*50), window=btn)
root.update()
buttonFrame.config(scrollregion=buttonFrame.bbox("all"))

If you try that I suspect it's not what you were looking for, since the create_window method requires absolute positioning (you can't use grid or pack). That's why most people put a Frame in the Canvas, and add their widgets to that instead. Many people have abstracted this faux Frame that is actually a Frame in a Canvas in another Frame, including me .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM