为什么Frame的自然高度没有立即更新?
我正在写一个小工具,用来显示一些文本行(通过一个Label
放在一个Frame
里),当文本的高度超过包含它的Frame
的高度时,我需要调整字体大小。
为此,我在文本更新后,会查询Label
和Frame
的高度,使用.winfo_reqheight()
这个方法,想要把字体大小调小,然后重新写入文本,重复这个过程,直到文本适合为止(如果有更好的主意,我非常欢迎)。
总之,我写了一个测试脚本来实现这个功能,但我发现更新文本后,Frame
的高度和Label
的高度比起来差了一点。
具体来说:这段代码
import Tkinter as tk
class App():
def __init__(self):
self.root = tk.Tk()
self.root.geometry("200x200")
self.f = tk.Frame(self.root)
self.f.pack(expand=True, fill=tk.BOTH)
self.l = tk.Label(self.f)
self.l.pack(expand=True, fill=tk.BOTH)
self.root.bind("q", func=self.addline)
self.counter = 0
def addline(self, event):
mylist = list()
self.counter += 1
for _ in range(self.counter):
mylist.append("hello")
message = '\n'.join(mylist)
self.l.configure(text=message, font=('Arial', 30))
print("frame: {0} label {1}".format(self.f.winfo_reqheight(), self.l.winfo_reqheight()))
App().root.mainloop()
在按了三次q
后显示的效果是
并且输出是
frame: 21 label 51
frame: 51 label 96
frame: 96 label 141
你看Frame
的大小差了一点吗?尽管这两个小部件是同时查询的,为什么会出现这种情况呢?
1 个回答
1
在事件处理程序返回之前,里面所做的更改是不会更新的。
不过,你可以通过使用 update_idletasks
来强制更新:
self.l.configure(text=message, font=('Arial', 30))
self.l.update_idletasks()
更新
winfo_height()
的文档也提到了 update_idletasks
:
获取这个小部件的高度,单位是像素。注意,如果这个窗口没有被几何管理器管理,这个方法会返回1。 要获取真实的值,你可能需要先调用
update_idletasks
。你也可以使用winfo_reqheight
来获取小部件请求的高度(也就是根据小部件内容定义的“自然”大小)。