首页 > 解决方案 > Tkinter 刷新/更新滚动条以适应画布内容

问题描述

在画布中加载新框架后,滚动条不适合内容。
如果我手动调整窗口大小,滚动条会适合内容。
加载框架时如何强制滚动条适应内容?
这是重现我的问题的代码:

from tkinter import *

class MyApp:
    def __init__(self):
        self.root = Tk()
        self.mainframe = Frame(self.root)
        self.mainframe.pack(fill=BOTH, expand=True)
        self.mainframe.columnconfigure(0, weight=1)

        self.contentCanvas = Canvas(self.mainframe)
        self.contentCanvas.grid(sticky=N + S + W + E)

        self.horizontalBar = Scrollbar(self.mainframe, orient=HORIZONTAL)
        self.horizontalBar.grid(rowspan=2, sticky=W + E + S)
        self.horizontalBar.config(command=self.contentCanvas.xview)
        self.contentCanvas.config(xscrollcommand=self.horizontalBar.set)

        self.contentFrame = Frame(self.contentCanvas)
        self.content = Frame(self.contentFrame)
        self.content.grid()
        Button(self.content, text="Load Long Content", command=self.loadLongContent).grid()

        self.contentCanvas.bind("<Configure>", lambda e: self.contentCanvas.configure(scrollregion=self.contentFrame.bbox("all")))
        self.contentCanvas.create_window((0, 0), window=self.contentFrame, anchor="nw")


    def run(self):
        self.root.mainloop()

    def loadContentFrame(self, frame):
        self.content.grid_forget()
        self.content.destroy()
        self.content = frame
        self.content.grid()

    def loadLongContent(self):
        longFrame = Frame(self.contentFrame)
        for i in range(100):
            Label(longFrame, text=i*i).grid(row=0, column=i)
        self.loadContentFrame(longFrame)

if __name__ == "__main__":
    app = MyApp()
    app.run()

图片:
加载新内容之前:

加载新内容后:

稍微调整窗口大小后:

标签: canvastkinterscrollbar

解决方案


我想出了一个可行的解决方案(基于 Helder Sepulvedas 的想法)。
我在 init 中添加了这个:
self.expand = False
这是在 loadFrame 中添加的:

        width = self.root.winfo_width()
        height = self.root.winfo_height()
        if self.expand:
            self.root.geometry('{width}x{height}'.format(width=width + 1, height=height + 1))
            self.expand = False
        else:
            self.root.geometry('{width}x{height}'.format(width=width - 1, height=height - 1))
            self.expand = True

窗口大小不变的解决方案仍然很好。
另外我建议在 init 中设置 root 的位置。


推荐阅读