为什么不立即更新 Frame 的自然高度? [英] why isn't the natural height of a Frame updated immediately?

查看:32
本文介绍了为什么不立即更新 Frame 的自然高度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小部件来显示一些文本行(通过 Frame 中的 Label),并且一旦文本高度变大就需要调整字体大小比包含 Frame 的高度.

为了做到这一点,我在文本更新后查询 .winfo_reqheight()LabelFrame,有了减少它并重写文本的想法 - 在循环中,直到它适合(任何更好的想法都受到热烈欢迎)

无论如何,我编写了一个测试脚本来实现该功能,但是我为 Frame 获得的高度与 Label 的高度相比是一次性的(在有更新了文本).

实际上:代码

将 Tkinter 导入为 tk类应用程序():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 = 0def addline(self, event):mylist = 列表()self.counter += 1对于 _ 范围内(self.counter):mylist.append("你好")消息 = '\n'.join(mylist)self.l.configure(text=message, font=('Arial', 30))打印(框架:{0}标签{1}".格式(self.f.winfo_reqheight(),self.l.winfo_reqheight()))App().root.mainloop()

按三下 q 后显示

和输出

frame: 21 标签 51框架:51 标签 96框架:96 标签 141

看看 Frame 的大小是怎么一回事?尽管同时查询了两个小部件,但这种行为的原因是什么?

解决方案

在事件处理程序返回之前,所做的更改不会更新.

但是您可以使用 还提到了 update_idletasks:

<块引用>

获取此小部件的高度,以像素为单位.请注意,如果窗口不由几何管理器管理,此方法返回 1.给你真正的价值,您可能必须先调用update_idletasks.你可以还可以使用 winfo_reqheight 来获取小部件的请求高度(即是,由小部件本身定义的自然"大小基于它的内容).

I am writing a widget to display some lines of text (via a Label in a Frame) and will need to adjust the font size once the text height is larger than the height of the containing Frame.

In order to do so, I am querying .winfo_reqheight() for the Label and the Frame after the text has been updated, with the idea to reducing it and rewriting the text - in a loop, until it fits (any better ideas are warmly welcome)

Anyway, I wrote a test script to implement that feature but the height I get for the Frame is one-off compared to the one of the Label (after having updated the text).

In practical terms: the code

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()

after three presses of q displays

and outputs

frame: 21 label 51
frame: 51 label 96
frame: 96 label 141

See how the size of the Frame is one off? What is the reason for this behavior despite both widgets being queried at the same time?

解决方案

Until event handler returns, changes made there are not updated.

But you can force update using update_idletasks:

self.l.configure(text=message, font=('Arial', 30))
self.l.update_idletasks()

UPDATE

winfo_height() documentation also mentions update_idletasks:

Get the height of this widget, in pixels. Note that if the window isn’t managed by a geometry manager, this method returns 1. To you get the real value, you may have to call update_idletasks first. You can also use winfo_reqheight to get the widget’s requested height (that is, the "natural" size as defined by the widget itself based on it’s contents).

这篇关于为什么不立即更新 Frame 的自然高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆