问题描述
我想创建一个窗口,允许为文件传输输入一对多字段。 我创建了一个可滚动框架,并在运行时添加了 Entry-Text 对。如果我第一次单击该按钮,一切都会顺利。第二次之后,UI 端没有任何反应。第二次点击后它可以完美运行。但是我看到所有对添加成功,只是UI没有显示它。有人知道怎么解决吗?
import tkinter as tk
class VerticalScroolFrame(tk.Frame):
"""A frame with a vertical scroolbar"""
def __init__(self,master,*args,**kwargs):
main_frame = tk.Frame(master)
main_frame.grid()
main_frame.rowconfigure(0,weight=1)
main_frame.columnconfigure(0,weight=1)
self._canvas = tk.Canvas(main_frame)
self._canvas.grid(row=0,column=0,sticky=tk.NSEW)
scrollbar = tk.Scrollbar(main_frame,command=self._canvas.yview)
scrollbar.grid(row=0,column=1,sticky=tk.N+tk.S+tk.W)
self._canvas.configure(yscrollcommand=scrollbar.set)
self._canvas.bind('<Configure>',lambda *_: self.on_configure())
super().__init__(self._canvas,**kwargs)
self._canvas.create_window((0,0),window=self,anchor=tk.NW)
def on_configure(self):
"""update scrollregion after starting 'mainloop'
when all widgets are in self._canvas. And also need to be triggered
whenever a widget added as a child.
"""
self._canvas.configure(scrollregion=self._canvas.bBox('all'))
class AdvancedTransfer:
"""Opens a window that allows you to enter source file list
and targets for them. One-to-many relation.
"""
def __init__(self,root):
self._scroolable_frame = VerticalScroolFrame(root)
self._entry_text_dict = {}
self._button = tk.Button(root,text="Add",command=self.add_item)
self._button.grid()
def add_item(self):
"""Add entry-text widget group"""
row = len(self._entry_text_dict)
entry = tk.Entry(self._scroolable_frame)
entry.insert(0,"row number: {0}".format(row))
entry.grid(row=row,column=0)
text = tk.Text(self._scroolable_frame)
text.grid(row=row,column=1)
self._entry_text_dict[entry] = text
self._scroolable_frame.on_configure()
def main():
root = tk.Tk()
main_frame = tk.Frame(root)
main_frame.grid()
AdvancedTransfer(main_frame)
root.mainloop()
if __name__ == "__main__":
main()
重现步骤:
解决方法
这是因为您在错误的小部件上绑定了 <Configure>
事件。您应该绑定内部框架(即 VerticalScroolFrame
的实例)而不是画布(self._canvas
):
class VerticalScroolFrame(tk.Frame):
"""A frame with a vertical scroolbar"""
def __init__(self,master,*args,**kwargs):
main_frame = tk.Frame(master)
main_frame.grid()
main_frame.rowconfigure(0,weight=1)
main_frame.columnconfigure(0,weight=1)
self._canvas = tk.Canvas(main_frame)
self._canvas.grid(row=0,column=0,sticky=tk.NSEW)
scrollbar = tk.Scrollbar(main_frame,command=self._canvas.yview)
scrollbar.grid(row=0,column=1,sticky=tk.N+tk.S+tk.W)
self._canvas.configure(yscrollcommand=scrollbar.set)
#self._canvas.bind('<Configure>',lambda *_: self.on_configure())
super().__init__(self._canvas,**kwargs)
self._canvas.create_window((0,0),window=self,anchor=tk.NW)
# bind <Configure> event on itself
self.bind('<Configure>',lambda _: self.on_configure())