将复选框动态添加到可滚动框架中

时间:2014-05-05 23:36:36

标签: python canvas tkinter scrollbar frame

我知道这里有很多类似的问题,但我找到的这些问题似乎都不适合我。这就是交易: 我需要在框架内动态加载复选框,但我不知道它们有多少。所以我需要一个滚动条。我已经读过没有办法将滚动条放入框架,除非我将框架放入框架中画布并将滚动条添加到画布。我认为问题是关于scrollregion的问题,但我不太确定。

以下是我的代码的一部分:

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 个答案:

答案 0 :(得分:2)

创建一个类然后调用它而不是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()

代码来自here