Create resizable/multiline Tkinter/ttk Labels with word wrap

你说的曾经没有我的故事 提交于 2019-12-05 10:29:15

No, there is no feature built-in to Tk to auto-word-wrap labels. However, it's doable by binding to the <Configure> event of the label and adjusting the wrap length then. This binding will fire every time the label widget is resized.

The other option, as you suggest, is to use a text widget. It is possible to entirely turn off the border if you so desire. This has always been my choice when I want word-wrapped instructional text.

Here is the code:

entry = Label(self, text=text,
    anchor=NW, justify=LEFT,
    relief=RIDGE, bd=2)
def y(event, entry=entry):
  # FIXME: make this a global method, to prevent function object creation
  # for every label.
  pad = 0
  pad += int(str(entry['bd']))
  pad += int(str(entry['padx']))
  pad *= 2
  entry.configure(wraplength = event.width - pad)
entry.bind("<Configure>", y )

Use Message widget:

The Message widget is a variant of the Label, designed to display multiline messages. The message widget can wrap text, and adjust its width to maintain a given aspect ratio.

The tkinter.Message widget suggested by some people does NOT use TTK styling, which means that it's gonna look like garbage inside a TTK (themed) interface.

You could manually apply the background and foreground colors from your TTK theme to the tkinter.Message (by instantiating ttk.Style() and requesting the active themes' TLabel foreground and background colors from that style object), but it's not worth it... because the ancient Message widget has ZERO advantages over TTK's regular ttk.Label.

The tkinter.Message widget has an "aspect ratio" property that defines how many pixels until it wraps.

The ttk.Label instead has a wraplength= property which determines how many pixels until the words wrap. You should also use its anchor= and justify= properties to customize it to your exact desires. With these properties you can make your Label behave as the old Message widget did.

Example: ttk.Label(root, text="foo", wraplength=220, anchor=tkinter.NW, justify=tkinter.LEFT). Creates a beautifully styled label which permanently wraps its text after 220 pixels wide.

As for automatically updating the wraplength? Well, you should attach to the <Configure> event as people have said... However, if you have a completely fluid window (which resizes itself to fit all content), or a grid/frame that is fluid and contains the label, then you can't automatically calculate it that way, because the parent WINDOW/CONTAINER itself will EXPAND whenever the label grows too wide. Which means that the label will always resize itself to the maximum width it would need to fit all text. So, updating wraplength automatically is only possible if the label itself has some constraints on how wide it can grow (either via its parent container being a fixed size/maxsize, or itself being a fixed size/maxsize). In that case, sure, you can use configure to calculate new wrapping numbers to make sure the text always wraps... However, the example code by t7ko is broken and not valid anymore, just fyi.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!