Tkinter 可滚动和可扩展的 PanedWindow

Tkinter Scrollable and expandable PanedWindow

我已经在 Whosebug 上搜索了很多,还有很多博客、文档...但我没有找到使“PanedWindow”可滚动和展开 + 填充的方法。

检查这个例子

"""Test"""
# pylint: disable=unused-wildcard-import,wildcard-import
from tkinter import Canvas, Scrollbar, Tk, Wm
from tkinter.constants import BOTH, CENTER, HORIZONTAL, LEFT, NSEW, X
from tkinter.ttk import Button, Frame, Label, PanedWindow, Style

STYLE = {
    "TButton": {
        "configure": {
            "background": "#333333",
            "foreground": "white",
            "padding": 8,
            "relief": "flat",
            "border": 2,
        },
        "map": {
            "background": [("active", "#777777")],
            "foreground": [("active", "white")],
        },
    },
}


class ScrollableFrame(Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        scrollbar = Scrollbar(self, orient="vertical")
        scrollbar.pack(side="right", fill="y")

        canvas = Canvas(self, borderwidth=2, background="red")
        canvas.pack(side=LEFT, fill=BOTH, expand=True)
        canvas.configure(yscrollcommand=scrollbar.set)

        scrollbar.configure(command=canvas.yview)
        frame = Frame(canvas, style="DEBUG.TFrame")

        canvas.create_window((0, 0), window=frame, anchor=CENTER)

        # COMMENT THIS, and the paned is scrollable, but frame does NOT expand
        # frame.pack(expand=1, fill=BOTH)

        frame.bind("<Configure>", self.on_configure)

        self.scollbar = scrollbar
        self.canvas = canvas
        self.frame = frame

    def on_configure(self, event):
        self.canvas.configure(
            scrollregion=self.canvas.bbox("all"),
        )


def create_right_pane(master):
    frame = Frame(master)
    label = Label(frame, text="This is a cool text")
    label.pack()
    return frame


def create_left_pane(master):
    frame = ScrollableFrame(master)
    title = Label(frame.frame, text="Hello !!!")
    title.pack(expand=True, fill=BOTH, anchor=CENTER)
    for i in range(100):
        Button(frame.frame, text=f"Channel {i} ❱").pack(expand=True, fill=BOTH)
    return frame


app = Tk(className="MyApp")
style = Style()
style.theme_create("app", None, STYLE)
style.theme_use("app")
app.title("MyApp")
app.geometry("1120x550")

splitpane = PanedWindow(app, orient=HORIZONTAL)
splitpane.pack(expand=True, fill=BOTH)

leftframe = create_left_pane(splitpane)
rightframe = create_right_pane(splitpane)

splitpane.add(leftframe, weight=1)
splitpane.add(rightframe, weight=5)

app.mainloop()

ScrollableFrame中有评论class

我想做的只是让内容“填充space”并且“可滚动”。

如果您发现问题,并且可以修复它(或提供解决方案)...谢谢!

默认情况下,内框会根据其内容展开或缩小到最佳大小。由于框架的内容不如 canvas 宽,因此框架不会像 canvas.

宽。

如果你想让它填充 canvas,你需要在 canvas 改变大小时明确设置宽度与 canvas 的宽度相同。

首先,让我们确保我们可以通过给它一个标签来识别内部框架。您可以轻松捕获 window_create.

返回的标识符
canvas.create_window((0, 0), window=frame, anchor=CENTER, tags=("inner_frame",))

接下来,添加绑定以在 canvas 配置更改时调用函数。

canvas.bind("<Configure>", self.resize_inner_frame)

最后,定义resize函数。在 <Configure> 事件中,event 对象将包含一个 width 参数,代表对象的宽度。我们可以用它来确定内框的宽度。

def resize_inner_frame(self, event):
    self.canvas.itemconfigure("inner_frame", width=event.width)

您可能需要调整宽度以适应 canvas 边框。