删除内容后如何在Tkinter中缩小帧? [英] How to shrink a frame in tkinter after removing contents?
问题描述
我遇到的大多数主题都涉及如何不缩小内容的Frame
,但是我感兴趣的是在破坏了所述内容后将其缩小.这是一个示例:
Most of the topics I came across deals with how to not shrink the Frame
with contents, but I'm interested in shrinking it back after the destruction of said contents. Here's an example:
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()
到目前为止,我应该在我的窗口中看到它:
So far I should see this in my window:
Hello!
My name is Foo
Bye!
那太好了,但是我想根据需要保持中间层的可互换性和隐藏性.因此,如果我破坏其中的lbl2
:
That's great, but I want to keep the middle layer interchangeable and hidden based on needs. So if I destroy the lbl2
inside:
lbl2.destroy()
我想看:
Hello!
Bye!
但是我看到的却是:
Hello!
███████
Bye!
我想将frm
缩小到基本上不存在,因为我想保持我的主要小部件的顺序不变.理想情况下,我想运行frm.pack(fill=tk.BOTH, expand=True)
以便我的小部件可以相应缩放.但是,如果这妨碍了收缩,我可以不用fill/expand
生存.
I want to shrink frm
back to basically non-existence because I want to keep the order of my main widgets intact. Ideally, I want to run frm.pack(fill=tk.BOTH, expand=True)
so that my widgets inside can scale accordingly. However if this interferes with the shrinking, I can live without fill/expand
.
我尝试了以下操作:
-
pack_propagate(0)
:实际上,这完全不会扩展帧到pack()
之后. - 重新运行
frm.pack()
:但是这破坏了我的主要小部件的顺序. -
.geometry('')
:仅在root
窗口上有效-对于Frame
不存在. -
frm.config(height=0)
:奇怪的是,这似乎并没有改变任何东西. -
frm.pack_forget()
:来自这个答案,但是并没有带回来.
pack_propagate(0)
: This actually doesn't expand the frame at all pastpack()
.- Re-run
frm.pack()
: but this ruins the order of my main widgets. .geometry('')
: This only works on theroot
window - doesn't exist forFrame
s.frm.config(height=0)
: Oddly, this doesn't seem to change anything at all.frm.pack_forget()
: From this answer, however it doesn't bring it back.
它给我留下的唯一选择是使用grid
管理器,我认为它可以工作,但不完全是我想要的...,所以我很想知道是否还有另一种方法可以实现这一目标./p>
The only option it leaves me is using a grid
manager, which works I suppose, but not exactly what I'm looking for... so I'm interested to know if there's another way to achieve this.
推荐答案
问题:删除最后小部件后缩小
Frame
?
Question: Shrink a
Frame
after removing the last widget?
绑定到<'Expose'>
事件,如果没有孩子,则绑定.configure(height=1)
.
Bind to the <'Expose'>
event and .configure(height=1)
if no 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()
问题:重新运行
frm.pack()
:但是这破坏了我的主要小部件的顺序.
frm.pack_forget()
,但是它并没有带回来.
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
.这样可以打包相对于其他窗口小部件的窗口小部件.
Pack
has the options before=
and after
. This allows to pack a widget relative to other widgets.
参考:
将其主服务器用作从属服务器的主服务器,并在打包顺序中将其他从服务器插入其他服务器之前.
Use its master as the master for the slaves, and insert the slaves just before other in the packing order.
使用before=
和self.lbl3
作为锚点的示例.如果没有子级,请使用.pack_forget()
删除Frame
,并在装箱单中的同一位置重新包装.
Example using before=
and self.lbl3
as anchor. The Frame
are removed using .pack_forget()
if no children and get repacked at the same place in the packing order.
注意:我只显示相关部分!
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
这篇关于删除内容后如何在Tkinter中缩小帧?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!