使可滚动框架在 tkinter 环境中看起来很自然

问题描述 投票:0回答:1

我所向往的

我正在创建一个可滚动框架。它实际上是一个包含滚动条和画布的框架,其中有另一个框架。这样,可以使用滚动条滚动画布内的框架。 您可以在here看到一个有效的“垂直滚动框架”。

我希望它看起来只是一个左侧带有滚动条(并且能够滚动)的框架,以这种方式使用它:

root = tkinter.Tk()
scroll_frame = ScrollFrame(root)

for i in range(100):
   ttk.Button(scroll_frame, text=f"Button {i}").pack()

scroll_frame.pack()
root.mainloop()

显然,这在我给出的示例中是不可能的,因为按钮将被打包在容器框架中,这是不可滚动的。我们必须这样做:

ttk.Button(scroll_frame.interior, text=...)

并且

ScrollFrame
不再类似于 tkinter 小部件...

我想到了什么

  • 我的第一个想法是像事件一样捕捉
    ScrollFrame
    作为主人的归属,并给出
    interior
    框架;但我还没有找到任何方法来做到这一点。

另外,我颠倒了角色:

ScrollFrame()
返回内部框架,容器框架是
ScrollFrame().container
ScrollFrame
现在是内部框架,问题是我必须这样写:

scroll_frame = ScrollFrame()
...
scroll_frame.container.pack()   #doesn't look natural

为了解决这个问题,我有两个想法:

  • 将其放入
    ScrollFrame.__init__
self.pack  = self.pack_configure  = container.pack
self.grid  = self.grid_configure  = container.grid
self.place = self.place_configure = container.place

但这可能是问题的根源,因为有很多东西与包、网格和位置相关,所以我还必须添加周围的所有内容,例如

pack_forget
,也许
packinfo
grid_forget
等,我可能不会包括他们全部。

  • 然后我发现了
    <Map>
    事件并想:“哦!这很简单,我要做这样的事情:”
def on_map(event):
   container.tk.call((event.geometry_manager, "configure", container._w) + event.options)

self.bind("<Map>", on_map)

不幸的是,我还没有找到任何方法来获取有关事件如何调用的信息。如果使用一些参数调用 grid 方法,我希望容器显示为 grid 和这些参数,而不是 pack 或其他任何东西......

请帮忙!

我想做的事是不是一个坏主意? 有没有办法正确地做到这一点?

python tkinter
1个回答
0
投票

TomSchimansky 在他的

customtkinter
CTkScrollableFrame 中解决了这个问题,方法是让他的类成为实际内部
Frame
,并首先创建一个父级
Frame
Canvas
来包装自身。

看一下其 init 方法的摘录:

def __init__(self, master: Any, width: int = 200, height: int = 200, ... ):
    ...
    # first creating parent frame and canvas
    self._parent_frame = CTkFrame(master=master, width=0, height=0, corner_radius=corner_radius,
                                  border_width=border_width, bg_color=bg_color, fg_color=fg_color, border_color=border_color)
    self._parent_canvas = tkinter.Canvas(master=self._parent_frame, highlightthickness=0)
    ...
    # then creating the "actual" frame that is represented by self
    tkinter.Frame.__init__(self, master=self._parent_canvas, highlightthickness=0)
    ...

请注意,您必须覆盖框架类的所有方法,例如

pack
grid
,以定位父级而不是离子框架,例如:

def pack(self, **kwargs):
    self._parent_frame.pack(**kwargs)
© www.soinside.com 2019 - 2024. All rights reserved.