Tkinter:将滚动条与 Canvas 相结合

Tkinter: Combining a Scrollbar with a Canvas

我知道这不是第一次有人问这样的问题,但即使在浏览 Internet 大约 2 小时后我也无法让它工作:

所以我正在尝试创建一个包含多个按钮的 Tkinter-Frame(例如,我使用了 30 个)。但是因为我的程序中没有足够的space,我需要在它旁边添加一个滚动条,这样就可以滚动浏览按钮。

我遇到的问题是,该条的内部 "moving part" 与整个滚动条一样大并且无法移动,我通过使用 scollregion=(0,0,1000,1000) 解决了这个问题,但即使那么条形图的移动对 canvas 没有任何影响。

这是我从程序中提取的相应代码:

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()

如您(希望)所见,滑块甚至无法移动,也不会改变 canvas 上的任何内容,即使我在其中某处挤压 scrollregion=(bla)

2个问题: a.) 我需要添加(或删除)什么,以便我可以滚动浏览按钮列表 b.) 从 a. 进行修复。当我将滚动条设为 buttonFrame 而不是 root?

的子项时仍然有效

要将小部件添加到 Canvas,您必须使用 create_window 方法,而不是 grid()。然后你必须在设置 scrollregion 之前更新 canvas。

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"))

如果您尝试这样做,我怀疑这不是您想要的,因为 create_window 方法需要绝对定位(您不能使用 grid 或 pack)。这就是为什么大多数人将一个框架放在 Canvas 中,并将他们的小部件添加到其中。许多人已经抽象出这个虚假的框架,它实际上是另一个框架 Canvas 中的一个框架,including me