Tkinter обновить / обновить полосу прокрутки, чтобы соответствовать содержанию холста - PullRequest
1 голос
/ 11 апреля 2020

После загрузки нового кадра на холсте полоса прокрутки не помещается в содержимое.
Если я вручную изменяю размер окна, полоса прокрутки соответствует содержимому.
Как заставить полосу прокрутки соответствовать содержимому при загрузке frame?
Вот код, который воспроизводит мою проблему:

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()

Картинки:
Перед загрузкой нового контента:

После загрузки нового контента:

После изменения размера окна немного:

1 Ответ

0 голосов
/ 12 апреля 2020

Я нашел решение, которое несколько работает (основано на идее Хелдера Сепульведаса).
Я добавил это в 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

Решение, при котором размер окна не изменяется, все равно будет хорошим.
Также я рекомендую установить позицию root в init.

...