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

标签 python canvas tkinter scrollbar frame

我知道这里有很多类似的问题,但我发现这些问题似乎都不适合我。情况如下: 我需要在框架内动态加载复选框,但我不知道它们可以有多少个。所以我需要一个滚动条。我读到没有办法将滚动条放入框架中,除非我将框架放入 Canvas 中并将滚动条添加到 Canvas 中。我认为问题出在滚动区域上,但我不太确定。

这是我的代码的一部分:

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

最佳答案

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

关于python - 动态地将复选框添加到可滚动框架中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23483629/

相关文章:

C# - Windows Phone - MaxWidth 和 MaxHeight 属性被忽略

html - 清除 Canvas 矩形(但保留背景)

python-2.7 - 用于在窗口上打印串行数据的 python 代码。

python - 为什么菜单没有显示在我的 Tkinter GUI 上?

c++ - 如何在 Python 中处理来自 C++ 的 PyObject*

python - 如何使用 opencv 计算 2 个 numpy 数组的 "EMD",即 "histogram"?

javascript - 使用 HTML5 在上传前调整图片大小

python - 将一堆代码变成循环Python

python - pivot_table 索引中的 NaN 值导致数据丢失

Python:为什么我不能在类里面使用 `super`?