在使用tkinter的python(2.7.12)中,我尝试实现以下功能:我想动态隐藏和取消隐藏某些文本标签。我尝试使用pack_forget
,然后再次执行pack
。我即将隐藏和取消隐藏的标签位于其他标签之间的固定位置(相对位置)。当标签被隐藏时,它们不会占用空间。
例如,考虑一个标签,其中“not”文字作为句子的一部分出现或消失。句子的其他部分也将形成标签。因此,我不能简单地在{not}标签上使用pack_forget
后跟pack
:pack
不会将标签放在其先前的位置,而是放在装箱单的末尾
因此,为了确保标签保持其相对位置(并避免重新包装所有内容),我执行以下操作:我创建一个框架,将其打包在我的标签应出现/消失的位置,然后放置标签里面。然后,我隐藏/取消隐藏标签,但不隐藏框架。
我的期望是,框架的大小应根据内部标签是否隐藏来自行调整。当然,当标签可见时,框架应足够大以容纳它。但是,在标签上调用pack_forget
后,框架的大小应该再次缩小为零。
然而,这不起作用:最初,框架实际上没有大小。但是,在内部的文本标签可见一次后,框架会保持其大小。在框架内的标签上调用pack_forget
后,标签的文本实际上消失了,但框架不会缩小到零。
我做错了什么?
这是一个完整的代码示例(改编自example by Tony Veijalainen)。在我的系统上至少它显示了行为,文本实际上消失了,但框架保持其宽度(和高度),这不应该是这种情况。
from Tkinter import *
def toggle():
if label.winfo_ismapped():
button['text']='unmap'
label.pack_forget()
else:
button['text']='map'
label.pack()
root = Tk()
button = Button(text="Push me", command=toggle)
button.pack()
labelFrame = Frame()
labelFrame.pack()
label = Label(labelFrame, text="Hello Big Big World")
label.pack()
root.wait_window()
如果您在示例中删除labelFrame
并直接创建label
作为root
的子项,则一切正常:隐藏的标签确实占用零空间。
答案 0 :(得分:1)
当您在容器中的最后一个窗口小部件上调用pack_forget
时,容器会看到它没有子容,因此放弃了管理容器大小的责任。
一个简单的黑客攻击是在容器中打包1x1小部件。这样做会触发pack
调整容器以使其适合,从而导致容器缩小。
pack
具有允许您在其他窗口小部件之前或之后放置它的选项,因此您可以始终在隐藏窗口小部件之后跟踪窗口小部件,以便稍后将其还原到正确的位置。
您也可以切换为使用grid
代替pack
,因为grid
可以记住每个小部件的相对位置。
答案 1 :(得分:0)
说我们有两个框架和一个像这样的根
frame2 |框架1 |根
如果您想隐藏它
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if(m.Msg == 0x0047) { // WM_WINDOWPOSCHANGED = 0x0047
if (SelectionLength != 0) {
SelectionLength = 0;
}
}
}
要调整其他小部件的大小,请执行此操作(lstb位于frame1中)
self.frame2.pack(side='left', fill=tk.Y)
在根中,我也有一个文本
self.frame1.pack(side='left', fill=tk.Y)
self.lstb.pack(fill=tk.Y, expand=1)
当我隐藏frame1时,其他2个(带有列表框的fram1和带有Text的root)将调整自身大小。框架的唯一问题是您不能通过pack()使它们再次可见。您可以使其他小部件再次可见,但是如果您打包_忘记它们,其他小部件将不会调整大小。我还没有找到一种使框架恢复可见性的解决方案。
答案 2 :(得分:0)
更新:毕竟有before
和after
pack()
个选项!我不确定它们在哪个版本的Tkinter上可用,但它们至少在Py3.6和更高版本中可用。我在effbot.org上没有看到此消息,但我根据Bryan Oakley的答案进行了更深入的研究。
原件:
令人失望的是,before
方法没有after
或pack()
选项。但是,如果您决定使用包管理器而不是网格管理器,则可以根据需要pack_forget()
使用所需的窗口小部件。当需要将它们放回原处时,您可以解决打包限制,方法是简单地忘记其余的小部件,然后按所需顺序重新包装所有小部件。这可能不理想,但可以完成工作。