微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Tkinter 可滚动和可扩展的 PanedWindow

如何解决Tkinter 可滚动和可扩展的 PanedWindow

我已经在 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,**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,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

    enter image description here

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

    enter image description here

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

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

解决方法

默认情况下,内部框架将扩展或收缩到其内容的最佳大小。由于框架的内容没有画布那么宽,所以框架不会和画布一样宽。

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

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

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

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

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)

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。