微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Tkinter 在可滚动框架上添加小部件最后一项未显示

如何解决Tkinter 在可滚动框架上添加小部件最后一项未显示

我想创建一个窗口,允许为文件传输输入一对多字段。 我创建了一个可滚动框架,并在运行时添加了 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()

重现步骤:

  1. 运行下面的代码
  2. 点击按钮两次。
  3. 您应该会看到 2 对,但只显示了 1 对。

解决方法

这是因为您在错误的小部件上绑定了 <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())

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。