Python - Tkinter 框架的 Configure 事件不断触发,回调不断被调用

Python - Tkinter frame's Configure event constantly firing, callback constantly being called

我对 Tkinter 还很陌生,我正在尝试构建一个包含 table 可滚动 canvas 数据的应用程序。我设计了一个 Table class,其中包含一个 Canvas 小部件,该小部件又包含一个包含 table 内容的框架。

但是,在尝试使 Canvas 可滚动时,我 运行 遇到了问题。我已将 table 内容的 Configure 事件绑定到设置滚动区域的回调。但是,当我 运行 我的应用程序在无限循环中永远调用此回调时,我不确定为什么。我不明白为什么 Configure 事件会不断触发。

此外,当尝试在选项卡之间切换时,我的应用程序会冻结,大概是因为应用程序卡在回调调用循环中。

下面是我尝试在我的应用程序中执行的操作的简化示例。谁能帮我弄清楚如何解决这个问题,同时还允许 table 内容可以滚动?

import tkinter as tk
from tkinter import ttk


class Table(ttk.Frame):
    def __init__(self, parent):
        ttk.Frame.__init__(self, parent)

        self.table_canvas = tk.Canvas(self, bg='cyan')
        table_scrollbar = ttk.Scrollbar(
            self.table_canvas,
            orient='vertical',
            command=self.table_canvas.yview)

        self.table_content = ttk.Frame(self.table_canvas)
        self.table_content.bind('<Configure>', self.on_configure)

        self.table_canvas.create_window(
            (0, 0),
            window=self.table_content,
            anchor='nw')

        self.table_canvas.configure(yscrollcommand=table_scrollbar.set)

        for _ in range(10):
            table_row = ttk.Frame(self.table_content)
            ttk.Label(
                table_row,
                text='left text'
            ).grid(column=0, row=0, sticky='w')
            ttk.Label(
                table_row,
                text='right text'
            ).grid(column=1, row=0, sticky='e')
            table_row.columnconfigure(0, weight=1, uniform='same')
            table_row.columnconfigure(1, weight=1, uniform='same')
            table_row.pack(fill='x')

        self.table_canvas.pack(side='left', fill='both', expand=True)
        table_scrollbar.pack(side='right', fill='y')

    def on_configure(self, event):
        print('on configure triggered')
        self.table_canvas.configure(scrollregion=self.table_canvas.bbox('all'))


app = tk.Tk()
app.geometry('600x600')

notebook = ttk.Notebook(app)

tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)

container1 = ttk.Frame(tab1)

label_container1 = ttk.Frame(container1)
ttk.Label(label_container1, text='Tab One').pack(side='left')
label_container1.pack(fill='x')

table1 = Table(container1)
table1.pack(fill='both', expand=True)

container1.pack(fill='both', expand=True)

container2 = ttk.Frame(tab2)

label_container2 = ttk.Frame(container2)
ttk.Label(label_container2, text='Tab Two').pack(side='left')
label_container2.pack(fill='x')

table2 = Table(container2)
table2.pack(fill='both', expand=True)

container2.pack(fill='both', expand=True)

notebook.add(tab1, text='One')
notebook.add(tab2, text='Two')

notebook.pack(fill='both', expand=True)

app.mainloop()

我不是 100% 确定为什么会这样,但根本原因似乎是您将滚动条放在 canvas 内。根据经验,滚动条不应该是它正在滚动的对象的子项。

如果将滚动条移动到框架 (self) 而不是 canvas 的子框架,问题就会消失。

table_scrollbar = ttk.Scrollbar(
    self,
    orient='vertical',
    command=self.table_canvas.yview)