【问题标题】:How to display newly added tkinter widgets如何显示新添加的 tkinter 小部件
【发布时间】:2022-01-03 10:27:05
【问题描述】:

我正在使用 python3 tkinter。我正在尝试更新表格以动态添加新的条目小部件行。 布局如下:

  1. frame_canvas 包括一个画布和一个滚动条
  2. frame_entries 位于画布上,仅显示 5x7 窗口
  3. frame_entries 包含一个二维条目表

我想在 Entry 表上动态添加新行,因此,在 frame_entries 框架上添加新的 Entry 行。 现在的问题是这些新小部件的添加不会更新小部件显示,它只会替换屏幕上条目表的最后一行。 (数据在后台正确更新,只是显示更新的问题)

我尝试调用 canvas.update() 和 frame_entries.update() 但没有用。滚动条也不反映更新的条目表。

我更新了sn-p代码,大家可以下载试试。

import tkinter as tk

total_columns = 5
total_rows = 18
tbl = []

def add_row_table():
    global total_rows

    new_row: list[Entry] = [tk.Entry() for _ in range(total_columns)]
    for j in range(total_columns):
        new_row[j] = tk.Entry(frame_entries, width=20)
        new_row[j].grid(row=total_rows, column=j, sticky="news")
        new_row[j].insert(tk.END, total_rows)
    total_rows += 1

    # canvas.update_idletasks()
    # frame_entries.update_idletasks()
    tbl.append(new_row)

root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)

frame_main = tk.Frame(root, bg="gray")
frame_main.grid(sticky='news')

button2 = tk.Button(frame_main, text="Add Row", fg="green", command=add_row_table)
button2.grid(row=0, column=1, pady=(5, 0), sticky='nw')

frame_canvas = tk.Frame(frame_main)
frame_canvas.grid(row=2, column=0, pady=(5, 0), sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
# Set grid_propagate to False to allow table resizing later
frame_canvas.grid_propagate(False)

canvas = tk.Canvas(frame_canvas, bg="yellow")
canvas.grid(row=0, column=0, sticky="news")

vsb = tk.Scrollbar(frame_canvas, orient="vertical",         command=canvas.yview)
vsb.grid(row=0, column=1, sticky='ns')
canvas.configure(yscrollcommand=vsb.set)

frame_entries = tk.Frame(canvas, bg="blue")
canvas.create_window((0, 0), window=frame_entries, anchor='nw')

for i in range(total_rows):
    line = [tk.Entry() for j in range(total_columns)]
    for j in range(total_columns):
        line[j] = tk.Entry(frame_entries, width=20)
        line[j].grid(row=i, column=j, sticky="news")
        line[j].insert(tk.END, i)

    tbl.append(line)

frame_entries.update_idletasks()

columns_width = sum([tbl[0][j].winfo_width() for j in range(total_columns)])
rows_height = sum([tbl[i][0].winfo_height() for i in range(5)])
frame_canvas.config(width=columns_width + vsb.winfo_width(),
                height=rows_height+150)

canvas.config(scrollregion=canvas.bbox("all"))
root.mainloop()

【问题讨论】:

  • 什么是tablesentry_lineline?您没有对新创建的条目调用任何布局函数,因此它们将不可见。最好提供minimal reproducible example
  • 嗨,acw1668,非常感谢您的建议。第一次在这里发帖。我已经更新了完整的 sn-p

标签: python tkinter canvas scrollbar


【解决方案1】:

frame_entries添加条目后,您需要更新scrollregion of canvas

...
# function to be called whenever frame_entries is resized
def frame_entries_resized(event):
    # update canvas scrollregion
    canvas.config(scrollregion=canvas.bbox('all'))
...
frame_entries = tk.Frame(canvas, bg="blue")
# monitor size of frame_entries
frame_entries.bind('<Configure>', frame_entries_resized)
canvas.create_window((0, 0), window=frame_entries, anchor='nw')
...

请注意,您创建了重复的条目集:

for i in range(total_rows):
    # initialise with entries into 'line'
    line = [tk.Entry() for j in range(total_columns)]
    # then assign new entry into 'line' again
    for j in range(total_columns):
        line[j] = tk.Entry(frame_entries, width=20)
        line[j].grid(row=i, column=j, sticky="news")
        line[j].insert(tk.END, i)

    tbl.append(line)

您可以将line 初始化为None 的列表:

line = [None for j in range(total_columns)]

add_row_table() 内部同样的问题:

def add_row_table():
    global total_rows

    # should initialise new_row as list of None instead
    new_row: list[Entry] = [tk.Entry() for _ in range(total_columns)]
    for j in range(total_columns):
        new_row[j] = tk.Entry(frame_entries, width=20)
        new_row[j].grid(row=total_rows, column=j, sticky="news")
        new_row[j].insert(tk.END, total_rows)
    total_rows += 1

    # canvas.update_idletasks()
    # frame_entries.update_idletasks()
    tbl.append(new_row)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-25
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    相关资源
    最近更新 更多