动态在可滚动框架中添加复选框
我知道这里有很多类似的问题,但我找到的这些都不适合我。情况是这样的:
我需要在一个框架里动态加载复选框,但我不知道会有多少个复选框。所以我需要一个滚动条。我听说在框架里放滚动条是不行的,除非把框架放到一个画布里,然后把滚动条加到画布上。我觉得问题可能和滚动区域有关,但我不太确定。
这是我代码的相关部分:
def checkboxes_container(self):
# Checkboxes frame
self.checkboxes_frame = \
tk.Frame(self,
height=450,
bg='red', bd=0,
highlightthickness=0)
# Canvas widget to add scroll to the checkboxes holder
self.canvas = \
tk.Canvas(self.checkboxes_frame,
bg='blue', bd=0,
highlightthickness=0)
# Canvas sizer
canvas_sizer = tk.Frame(self.canvas, height=350,
bg='#444444', bd=0,
highlightthickness=0)
canvas_sizer.pack(side=tk.LEFT)
# Checkboxes holder
self.checkbox_pane = \
tk.Frame(self.canvas,
bg='#444444', bd=0,
highlightthickness=0)
self.checkbox_pane.grid_propagate(False)
# Scrollbar for checkbox pane
self.scrollbar = tk.Scrollbar(self.checkboxes_frame,
bg='grey', bd=0,
activebackground='#A3A3A3',
troughcolor='#444444',
width=16,
orient=tk.VERTICAL)
self.canvas.create_window(0, 0, window=self.checkbox_pane)
# Grid holder
self.checkboxes_frame.grid(row=1, column=0, sticky=tk.W+tk.E)
# Grid widgets to the holder
self.canvas.pack(expand=True, side=tk.LEFT, fill=tk.BOTH)
self.checkbox_pane.pack(expand=True, fill=tk.BOTH)
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.scrollbar.config(command=self.canvas.yview)
self.canvas.config(yscrollcommand=self.scrollbar.set,
scrollregion=
self.canvas.bbox('all'))
self是我的基本框架小部件,我在里面放其他小部件的容器(就像这个)。
如果有人能帮我,我会非常感激。我今天一直在尝试这个……我一定很接近成功了……或者我很笨。
提前谢谢你们!祝好!
编辑:添加了修改后的代码:
class ScrollableFrame(tk.Frame):
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, kwargs)
# create a canvas object and a vertical scrollbar for scrolling it
self.vscrollbar = tk.Scrollbar(self, orient=tk.VERTICAL)
self.vscrollbar.pack(side='right', fill="y", expand="false")
self.canvas = tk.Canvas(self,
bg='#444444', bd=0,
height=350,
highlightthickness=0,
yscrollcommand=self.vscrollbar.set)
self.canvas.pack(side="left", fill="both", expand="true")
self.vscrollbar.config(command=self.canvas.yview)
# reset the view
self.canvas.xview_moveto(0)
self.canvas.yview_moveto(0)
# create a frame inside the canvas which will be scrolled with it
self.interior = tk.Frame(self.canvas, kwargs)
self.canvas.create_window(0, 0, window=self.interior, anchor="nw")
class Application(tk.Frame):
# ...
def checkboxes_container(self):
self.checkbox_pane = ScrollableFrame(self,
bg='#444444')
self.checkbox_pane.grid(row=1, column=0,
columnspan=3,
sticky='nwes')
1 个回答
3
创建一个类然后调用它,可能比直接使用 Tkinter.Frame 更简单。
注意,有一个叫做 interior 的实例变量,你需要用它来在滚动框架里面显示小部件。
import Tkinter as tk
class ScrollableFrame(tk.Frame):
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
# create a canvas object and a vertical scrollbar for scrolling it
self.vscrollbar = tk.Scrollbar(self, orient=tk.VERTICAL)
self.vscrollbar.pack(side='right', fill="y", expand="false")
self.canvas = tk.Canvas(self,
bg='#444444', bd=0,
height=350,
highlightthickness=0,
yscrollcommand=self.vscrollbar.set)
self.canvas.pack(side="left", fill="both", expand="true")
self.vscrollbar.config(command=self.canvas.yview)
# reset the view
self.canvas.xview_moveto(0)
self.canvas.yview_moveto(0)
# create a frame inside the canvas which will be scrolled with it
self.interior = tk.Frame(self.canvas, **kwargs)
self.canvas.create_window(0, 0, window=self.interior, anchor="nw")
self.bind('<Configure>', self.set_scrollregion)
def set_scrollregion(self, event=None):
""" Set the scroll region on the canvas"""
self.canvas.configure(scrollregion=self.canvas.bbox('all'))
if __name__ == '__main__':
root = tk.Tk()
checkbox_pane = ScrollableFrame(root, bg='#444444')
checkbox_pane.pack(expand="true", fill="both")
def button_callback():
for x in range(1,20):
tk.Checkbutton(checkbox_pane.interior, text="hello world! %s" % x).grid(row=x, column=0)
btn_checkbox = tk.Button(checkbox_pane.interior, text="Click Me!", command=button_callback)
btn_checkbox.grid(row=0, column=0)
root.mainloop()
代码摘自 这里