删除内容后如何在 tkinter 中缩小框架?
How to shrink a frame in tkinter after removing contents?
我遇到的大多数主题都涉及如何 不 缩小 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()
到目前为止,我应该在 window:
中看到这个
Hello!
My name is Foo
Bye!
太好了,但我想根据需要保持中间层可互换和隐藏。所以如果我破坏里面的lbl2
:
lbl2.destroy()
我想看:
Hello!
Bye!
但我看到的是:
Hello!
███████
Bye!
我想缩小 frm
到基本上不存在,因为 我想保持主要小部件的顺序不变。理想情况下,我想要 运行 frm.pack(fill=tk.BOTH, expand=True)
以便我的内部小部件可以相应地缩放。然而,如果这干扰了缩小,我可以没有 fill/expand
.
我尝试了以下方法:
pack_propagate(0)
:这实际上根本不会扩展框架超过 pack()
。
- Re-运行
frm.pack()
: 但这破坏了我的主要小部件的顺序。
.geometry('')
:这仅适用于 root
window - Frame
不存在。
frm.config(height=0)
:奇怪的是,这似乎根本没有改变任何东西。
frm.pack_forget()
:From this answer,但它并没有把它带回来。
它留给我的唯一选择是使用 grid
管理器,我想它可以工作,但不是我正在寻找的东西...所以我想知道是否有其他方法可以做到这一点。
当您销毁框架内的最后一个小部件时,框架大小不再由 pack
或 grid
管理。因此,pack
和 grid
都不知道应该缩小框架。
一个简单的解决方法是在框架中添加一个小的 1 x 1 像素 window,这样 pack
仍然认为它负责框架的大小。
这是一个基于问题中代码的示例:
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()
Question: Shrink a Frame
after removing the last widget?
绑定到 <'Expose'>
事件和 .configure(height=1)
如果没有 children。
参考:
- Expose
An Expose event is generated whenever all or part of a widget should be redrawn
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()
Question: Re-run frm.pack()
: but this ruins the order of my main widgets.
frm.pack_forget()
, however it doesn't bring it back.
Pack
有选项 before=
和 after
。这允许相对于其他小部件打包小部件。
参考:
- -before
Use its master as the master for the slaves, and insert the slaves just before other in the packing order.
示例使用 before=
和 self.lbl3
作为锚点。如果没有 children,则使用 .pack_forget()
删除 Frame
,并在包装顺序中的同一位置重新包装。
Note: I show only the relevant parts!
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
我遇到的大多数主题都涉及如何 不 缩小 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()
到目前为止,我应该在 window:
中看到这个Hello!
My name is Foo
Bye!
太好了,但我想根据需要保持中间层可互换和隐藏。所以如果我破坏里面的lbl2
:
lbl2.destroy()
我想看:
Hello!
Bye!
但我看到的是:
Hello!
███████
Bye!
我想缩小 frm
到基本上不存在,因为 我想保持主要小部件的顺序不变。理想情况下,我想要 运行 frm.pack(fill=tk.BOTH, expand=True)
以便我的内部小部件可以相应地缩放。然而,如果这干扰了缩小,我可以没有 fill/expand
.
我尝试了以下方法:
pack_propagate(0)
:这实际上根本不会扩展框架超过pack()
。- Re-运行
frm.pack()
: 但这破坏了我的主要小部件的顺序。 .geometry('')
:这仅适用于root
window -Frame
不存在。frm.config(height=0)
:奇怪的是,这似乎根本没有改变任何东西。frm.pack_forget()
:From this answer,但它并没有把它带回来。
它留给我的唯一选择是使用 grid
管理器,我想它可以工作,但不是我正在寻找的东西...所以我想知道是否有其他方法可以做到这一点。
当您销毁框架内的最后一个小部件时,框架大小不再由 pack
或 grid
管理。因此,pack
和 grid
都不知道应该缩小框架。
一个简单的解决方法是在框架中添加一个小的 1 x 1 像素 window,这样 pack
仍然认为它负责框架的大小。
这是一个基于问题中代码的示例:
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()
Question: Shrink a
Frame
after removing the last widget?
绑定到 <'Expose'>
事件和 .configure(height=1)
如果没有 children。
参考:
- Expose
An Expose event is generated whenever all or part of a widget should be redrawn
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()
Question: Re-run
frm.pack()
: but this ruins the order of my main widgets.
frm.pack_forget()
, however it doesn't bring it back.
Pack
有选项 before=
和 after
。这允许相对于其他小部件打包小部件。
参考:
- -before
Use its master as the master for the slaves, and insert the slaves just before other in the packing order.
示例使用 before=
和 self.lbl3
作为锚点。如果没有 children,则使用 .pack_forget()
删除 Frame
,并在包装顺序中的同一位置重新包装。
Note: I show only the relevant parts!
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