【问题标题】:Tkinter Scrollable and expandable PanedWindowTkinter 可滚动和可扩展的 PanedWindow
【发布时间】:2021-06-13 18:33:48
【问题描述】:

我已经在 Stackoverflow 上进行了很多搜索,并且搜索了很多博客、文档……但我没有找到使“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类中有注释

  • 评论 frame.pack() => 它滚动,但内容没有展开,也没有填满 X

  • 取消注释 frame.pack() => 现在内容填满了空间,但它不可滚动

我想做的只是让内容“填满空间”并“可滚动”。

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

【问题讨论】:

    标签: python tkinter tk ttk scrollable


    【解决方案1】:

    默认情况下,内框会扩大或缩小到适合其内容的最佳尺寸。由于框架的内容没有画布那么宽,所以框架不会像画布那么宽。

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

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

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

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

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

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

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

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

    【讨论】:

    • 你是我的英雄!我将解决最后一个问题,在启动时,sizer 放置不当,canvas 不适合框架。我需要“刷新”视图(调整大小或移动 sizer),但解决方案非常酷。非常感谢。
    • 请注意,边框和背景颜色是在这里调试的,我删除了它们,没关系
    • 通过从“resize_inner_frame”方法添加对“on_configure”的调用来修复;)
    猜你喜欢
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多