首页 > 解决方案 > Python - Tkinter Frame 的 XY 滚动无法有效加载小部件

问题描述

我有当前代码(从原始代码中删减) - 此代码段也可在此处获得。

import tkinter as tk
import tkinter.ttk as ttk
class ScrolledFrame(tk.Frame):
    def __init__(self, master, **kw):
        tk.Frame.__init__(self, master, **kw)
        vsb = tk.Scrollbar(self, orient='vertical')
        vsb.grid(column=1, row=0, sticky='ns')
        hsb = tk.Scrollbar(self, orient='horizontal')
        hsb.grid(column=0, row=1, sticky='ew')

        self.canvas = canvas = tk.Canvas(self, bd=0, highlightthickness=0,
                        yscrollcommand=vsb.set, xscrollcommand=hsb.set)
        canvas.grid(row=0, column=0, sticky='nsew')
        #canvas.configure(scrollregion=canvas.bbox('all'))
        vsb.config(command=canvas.yview)
        hsb.config(command=canvas.xview)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        # reset the view
        canvas.xview_moveto(0)
        canvas.yview_moveto(0)

        self.interior = interior = tk.Frame(canvas)
        interior_id = canvas.create_window(0, 0, window=interior,
                                           anchor='nw')

        def _configure_interior(event):
            size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
            canvas.config(scrollregion="0 0 %s %s" % size)
            if interior.winfo_reqwidth() != canvas.winfo_width():
                canvas.config(width=interior.winfo_reqwidth())
        interior.bind('<Configure>', _configure_interior)

        def _configure_canvas(event):
            if interior.winfo_reqwidth() != canvas.winfo_width():
                canvas.itemconfigure(interior_id, width=canvas.winfo_width())
        canvas.bind('<Configure>', _configure_canvas)

if __name__ == '__main__':
    root = tk.Tk()
    main_frame = ScrolledFrame(root)
    main_frame.grid(row=0, column=0, sticky='nsew')
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
    for i in range(100): tk.Button(main_frame.interior, text=f'test {i}').grid(row=0, column=i)
    root.geometry('360x240')
    root.mainloop()

代码的目的也是有一个可以通过 x 和 y 轴滚动的框架;但是,出现了一个问题,在 x 轴上滚动会导致项目不被绘制: 它不工作的例子

然而,y 轴似乎工作得很好——我试图用不同的scrollregion=设置(即'all')改变程序但没有成功,它似乎完全删除了 x 轴的功能。

标签: pythonpython-3.xtkinter

解决方案


您明确将内部框架的宽度设置为与画布的宽度相同。例如,当程序启动时,画布将略小于 360 像素宽,因此您将内部框架设置为该大小。在我的机器上最终是 309 像素。因此,当您滚动时,您将只能看到 309 像素的按钮。

滚动的全部意义在于您试图看到比窗口更大的东西,但是您人为地使内部框架与窗口大小相同。

您应该停止强制内部框架与画布大小相同,或者至少停止强制它小于画布。它必须是它的自然大小。


推荐阅读