概述
您只能将滚动条与一些小部件关联起来,根小部件和Frame不是那组小部件的一部分。
最常见的解决方案是创建一个画布小部件,并将滚动条与该小部件关联起来。然后,将包含标签小部件的框架嵌入到画布中。确定框架的宽度/高度,并将其输入画布。scrollregion选项,以便滚动区域与框架的大小完全匹配。
在画布上直接绘制文本项并不困难,因此如果画布框架内嵌解决方案看起来过于复杂,您可能需要重新考虑这种方法。由于要创建网格,每个文本项的坐标将非常容易计算,特别是如果每一行的高度相同(如果使用单一字体,可能就是这样)。
要在画布上直接绘图,只需计算出所使用字体的线条高度(这方面有一些命令)。然后,每个y坐标是row*(lineheight+spacing)..x坐标将是基于每列中最宽项的固定数。如果为列中的所有项都赋予标记,则可以使用单个命令调整列中所有项的x坐标和宽度。
面向对象的解决方案
下面是一个使用面向对象方法的画布框架内嵌解决方案的示例:importtkinterastkclassExample(tk.Frame):
def__init__(self,root):
tk.Frame.__init__(self,root)
self.canvas=tk.Canvas(root,borderwidth=0,background="#ffffff")
self.frame=tk.Frame(self.canvas,background="#ffffff")
self.vsb=tk.Scrollbar(root,orient="vertical",command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set)
self.vsb.pack(side="right",fill="y")
self.canvas.pack(side="left",fill="both",expand=True)
self.canvas.create_window((4,4),window=self.frame,anchor="nw",
tags="self.frame")
self.frame.bind("",self.onFrameConfigure)
self.populate()
defpopulate(self):
'''Putinsomefakedata'''
forrowinrange(100):
tk.Label(self.frame,text="%s"%row,width=3,borderwidth="1",
relief="solid").grid(row=row,column=0)
t="thisisthesecondcolumnforrow%s"%row
tk.Label(self.frame,text=t).grid(row=row,column=1)
defonFrameConfigure(self,event):
'''Resetthescrollregiontoencompasstheinnerframe'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))if__name__=="__main__":
root=tk.Tk()
Example(root).pack(side="top",fill="both",expand=True)
root.mainloop()
程序解决方案
以下是不使用对象的解决方案:importtkinterastkdefpopulate(frame):
'''Putinsomefakedata'''
forrowinrange(100):
tk.Label(frame,text="%s"%row,width=3,borderwidth="1",
relief="solid").grid(row=row,column=0)
t="thisisthesecondcolumnforrow%s"%row
tk.Label(frame,text=t).grid(row=row,column=1)defonFrameConfigure(canvas):
'''Resetthescrollregiontoencompasstheinnerframe'''
canvas.configure(scrollregion=canvas.bbox("all"))root=tk.Tk()canvas=tk.Canvas(root,borderwidth=0,background="#ffffff")frame=
tk.Frame(canvas,background="#ffffff")vsb=tk.Scrollbar(root,orient="vertical",command=canvas.yview)canvas.configure
(yscrollcommand=vsb.set)vsb.pack(side="right",fill="y")canvas.pack(side="left",fill="both",expand=True)canvas.create_window((4,4),
window=frame,anchor="nw")frame.bind("",lambdaevent,canvas=canvas:onFrameConfigure(canvas))populate(frame)root.mainloop()
注:若要在python2.x中执行此操作,请使用Tkinter而不是tkinter在导入语句中