如何动态地将文本换行在 tkinter 标签中?

问题描述 投票:0回答:2

当超过参数

wraplength
中给出的限制时,tkinter 中标签中的文本可以换行为多行。

但是,这是一些像素,但我想为此使用完整的窗口宽度,并且每当用户更改窗口大小时,环绕长度都应该更改。

一种方法可能是手动更新参数,如下所示:

def update_wraplength(id, root):
    id.configure(wraplength=root.winfo_width())
    root.after(10, lambda: update_wraplength(id,root))

还有另一种方法可以做到这一点,也许是我不知道的参数?

python python-3.x tkinter
2个回答
11
投票

每次窗口大小发生变化时,您都必须更新环绕长度。您可以通过

"<Configure>"
事件检测窗口大小何时发生变化。

my_label.bind('<Configure>', update_wraplength)

请记住,只有当您将标签设置为扩展到所有可用空间时,它才有效。

让我们看看您是否能理解这段代码:

import Tkinter as tk

class WrappingLabel(tk.Label):
    '''a type of Label that automatically adjusts the wrap to the size'''
    def __init__(self, master=None, **kwargs):
        tk.Label.__init__(self, master, **kwargs)
        self.bind('<Configure>', lambda e: self.config(wraplength=self.winfo_width()))

def main():
    root = tk.Tk()
    root.geometry('200x200')
    win = WrappingLabel(root, text="As in, you have a line of text in a Tkinter window, a Label. As the user drags the window narrower, the text remains unchanged until the window width means that the text gets cut off, at which point the text should wrap.")
    win.pack(expand=True, fill=tk.X)
    root.mainloop()

if __name__ == '__main__':
    main()

0
投票

WrappingLabel
布局中使用 @rmb 的
grid
的多个实例时,我遇到了一些性能问题。

在网格中,

WrappingLabel
会导致布局频繁调整大小,这似乎会重复触发
<Configure>
事件并导致明显的滞后。

为了提高性能,我创建了一个变体,引入了调整大小限制,这有助于减少调整大小期间的更新数量。

在此分享更新版本以供参考:

class CtkWrappingLabel(tk.Label):
    def __init__(self, master=None, height=0, width=0, justify=ctk.LEFT, **kwargs):
        super().__init__(master, height=height, width=width, justify=justify, **kwargs)
        self._last_wrap_length: int = 0
        self._resize_after_id = None
        self.bind('<Configure>', self._on_resize)

    def _on_resize(self, event):
        new_wrap_length = int(event.width // 2)

        if new_wrap_length == self._last_wrap_length:
            return
        self._last_wrap_length = new_wrap_length

        # Cancel previous
        if self._resize_after_id is not None:
            self.after_cancel(self._resize_after_id)
        self._resize_after_id = self.after(1000, self._update_wrap_length)

    def _update_wrap_length(self):
        self.configure(wraplength=self._last_wrap_length)
        self._resize_after_id = None
© www.soinside.com 2019 - 2024. All rights reserved.