代码之家  ›  专栏  ›  技术社区  ›  r.ook jpp

如何在删除内容后缩小tkinter中的帧?

  •  0
  • r.ook jpp  · 技术社区  · 5 年前

    收缩 Frame

    import tkinter as tk
    root = tk.Tk()
    lbl1 = tk.Label(root, text='Hello!')
    lbl1.pack()
    frm = tk.Frame(root, bg='black')
    frm.pack()
    lbl3 = tk.Label(root, text='Bye!')
    lbl3.pack()
    lbl2 = tk.Label(frm, text='My name is Foo')
    lbl2.pack()
    

    到目前为止,我应该在我的窗口看到:

    Hello!
    My name is Foo
    Bye!
    

    这很好,但是我想根据需要保持中间层的可互换性和隐藏性。所以如果我毁了 lbl2 内部:

    lbl2.destroy()
    

    我想看:

    Hello!
    Bye!
    

    Hello!
    ███████
    Bye!
    

    我想收缩 frm 我想保持我的主要部件的秩序完好无损 frm.pack(fill=tk.BOTH, expand=True) fill/expand .

    我试过以下方法:

    1. pack_propagate(0) pack() .
    2. 重新运行 frm.pack()
    3. .geometry('') root 框架 s。
    4. frm.config(height=0)
    5. frm.pack_forget() From this answer 然而,它并没有把它带回来。

    它留给我的唯一选择就是使用 grid 经理,我想这很管用,但不完全是我要找的。。。所以我很想知道有没有别的方法可以达到这个目的。

    0 回复  |  直到 5 年前
        1
  •  3
  •   Community Dan Abramov    4 年前

    问题 :收缩a Frame 拆下后 最后的 小装置?

    <'Expose'> 事件和 .configure(height=1) 如果没有孩子。


    :


    import tkinter as tk
    
    class App(tk.Tk):
        def __init__(self):
            super().__init__()
    
            tk.Label(self, text='Hello!').pack()
            self.frm = frm = tk.Frame(self, bg='black')
            frm.pack()
            tk.Label(self, text='Bye!').pack()
            tk.Label(frm, text='My name is Foo').pack()
    
            self.menubar = tk.Menu()
            self.config(menu=self.menubar)
            self.menubar.add_command(label='delete', command=self.do_destroy)
            self.menubar.add_command(label='add', command=self.do_add)
    
            frm.bind('<Expose>', self.on_expose)
    
        def do_add(self):
            tk.Label(self.frm, text='My name is Foo').pack()
            
        def do_destroy(self):
            w = self.frm
            if w.children:
                child = list(w.children).pop(0)
                w.children[child].destroy()
    
        def on_expose(self, event):
            w = event.widget
            if not w.children:
                w.configure(height=1)
            
                                
    if __name__ == "__main__":
        App().mainloop()
    

    问题 :重新运行 frm.pack() :但这会破坏我的主要小部件的顺序。
    frm.pack_forget()

    Pack 有选择吗 before= after . 这允许打包相对于其他小部件的小部件。


    参考 :


    示例使用 之前= self.lbl3 使用删除 .pack_forget() 如果没有孩子,在包装单上的同一个地方重新包装。

    
    class App(tk.Tk):
        def __init__(self):
            ...
            self.frm = frm = tk.Frame(self, bg='black')
            frm.pack()
            self.lbl3 = tk.Label(self, text='Bye!')
            self.lbl3.pack()
            ...
    
        def on_add(self):
            try:
                self.frm.pack_info()
            except:
                self.frm.pack(before=self.lbl3, fill=tk.BOTH, expand=True)
    
            tk.Label(self.frm, text='My name is Foo').pack()
    
        def on_expose(self, event):
            w = event.widget
            if not w.children:
                w.pack_forget()
    

    使用Python测试:3.5-'TclVersion':8.6'TkVersion':8.6

        2
  •  2
  •   Bryan Oakley    5 年前

    当您销毁框架中的最后一个小部件时,框架大小不再由管理 pack grid 包装 也不是

    一个简单的解决方法是在帧中添加一个1像素乘1像素的小窗口,以便 包装 仍然认为这是造成框架尺寸的原因。

    import tkinter as tk
    root = tk.Tk()
    lbl1 = tk.Label(root, text='Hello!')
    lbl1.pack()
    frm = tk.Frame(root, bg='black')
    frm.pack()
    lbl3 = tk.Label(root, text='Bye!')
    lbl3.pack()
    lbl2 = tk.Label(frm, text='My name is Foo')
    lbl2.pack()
    
    def delete_the_label():
        lbl2.destroy()
        if len(frm.winfo_children()) == 0:
            tmp = tk.Frame(frm, width=1, height=1, borderwidth=0, highlightthickness=0)
            tmp.pack()
            root.update_idletasks()
            tmp.destroy()
    
    button = tk.Button(root, text="Delete the label", command=delete_the_label)
    button.pack()
    
    
    root.mainloop()