Tkinter Canvas 滚动条框架标签扩展

Tkinter Canvas Scrollbar Frame Label Expansion

我发现了针对此问题的多个建议解决方案,但下面建议的函数的所有变体要么不起作用,要么在应用于我的代码时导致错误。如前所述,我希望 canvas 框架中的元素向左和向右扩展,问题似乎与 canvas_configure() 函数有关。这是我正在使用的脚本的最小化版本:

from tkinter import *

# Master frame
app = Tk()
app.columnconfigure(0, weight=1)
app.rowconfigure(0, weight=1)


def load_files():

    # Do stuff which gives list of company names
    companies_list = [x for x in range(0, 30)]

    # Generates Tkinter elements
    y = 0
    for x in companies_list:
        y += 1
        old_co = Entry(frame)
        old_co.insert(0, x)
        old_co.grid(row=y, column=0, sticky=E+W)

        new_co = Entry(frame)
        new_co.grid(row=y, column=1, sticky=E+W)

        prefix = Entry(frame)
        prefix.grid(row=y, column=2, sticky=E+W)


# Sub-Frame
company_header_frame = LabelFrame(app, text='Company Name')
company_header_frame.grid(row=0, column=0, sticky=N+S+E+W)
company_header_frame.columnconfigure(0, weight=1)
company_header_frame.rowconfigure(0, weight=1)

# Canvas
canvas = Canvas(company_header_frame, height=100)
canvas.grid(row=0, column=0, sticky=N+S+E+W)

# Canvas Frame
frame = Frame(canvas)
canvas.create_window((0, 0), window=frame, anchor='nw')

# Sidebar
scroll_y = Scrollbar(company_header_frame, orient="vertical")
scroll_y.grid(row=0, column=1, sticky=N+S)
scroll_y.config(command=canvas.yview)


def canvas_configure(event):
    canvas_width = event.width
    event.itemconfig(frame, width=canvas_width)


def config_frame(_):
    canvas.configure(scrollregion=canvas.bbox('all'), yscrollcommand=scroll_y.set)


canvas.bind('<Configure>', canvas_configure)
frame.bind('<Configure>', config_frame)


load_files()


app.mainloop()

这会导致以下错误:

AttributeError: 'Event' object has no attribute 'itemconfig'

我尝试调整函数以使用 .winfo_width() 代替 width,用实际的 canvas 替换事件,但类似的属性错误结果与宽度或 itemconfig 有关。任何建议将不胜感激。

该错误准确地告诉您出了什么问题:Event 对象没有 itemconfig 方法。 canvas 小部件可以,但是,Event 对象可以为您提供 canvas 小部件:

def canvas_configure(event):
    canvas_width = event.width
    event.widget.itemconfig(frame, width=canvas_width)
    #    ^^^^^^^

与所问的具体问题无关,您还需要将有效的项目 ID 传递给 itemconfig -- 您不能传递框架本身。

您需要保存从 create_window 返回的值,或者您需要给 window 一个标签。

例如:

canvas.create_window(..., tags=("inner_frame",))
...
def canvas_configure(event):
    canvas_width = event.width
    event.widget.itemconfigure("inner_frame", width=canvas_width)