Create mutable / multi-line Tkinter / ttk word wrap labels

Is it possible to create a multi-line word wrap shortcut that changes according to the width of its parent element? In other words, the phrase "Notepad" when changing the width of the NotePad window.

A use case is a dialog box in which you need to present a block of multiline text (instructions) as a whole, without trimming the text or resorting to scrollbars. There will be enough vertical space in the parent container to accommodate a narrow width.

I experimented with Tkinter Label and Message widgets and ttk Label widgets without success. It seems I need to hardcode the pixel value wraplength vs. they have these automatic wordwrap words when their text reaches the right edge of their containers. Of course, can Tkinters geometry managers help me automatically resize my labels and update their wapplength values ​​accordingly?

Should I search for the Text widget? If so, is it possible to hide the border of the Text widget so that I can use it as a multi-line label with a word?

Here is a prototype of how I could do what I described above. This was inspired by Brian Oakley's advice to use the Text widget and the following entry in Stackoverflow: In tkinter python, how can I create a shortcut so you can select text with the mouse?

from Tkinter import * master = Tk() text = """ If tkinter is 8.5 or above you'll want the selection background to appear like it does when the widget is activated. Comment this out for older versions of Tkinter. This is even more text. The final line of our auto-wrapping label that supports clipboard copy. """.strip() frameLabel = Frame( master, padx=20, pady=20 ) frameLabel.pack() w = Text( frameLabel, wrap='word', font='Arial 12 italic' ) w.insert( 1.0, text ) w.pack() # - have selection background appear like it does when the widget is activated (Tkinter 8.5+) # - have label background color match its parent background color via .cget('bg') # - set relief='flat' to hide Text control borders # - set state='disabled' to block changes to text (while still allowing selection/clipboard copy) w.configure( bg=master.cget('bg'), relief='flat', state='disabled' ) mainloop() 
+4
source share
4 answers

No, there is no Tk built-in for word wrap shortcuts. However, this can be done by attaching labels to the <Configure> event and then adjusting the length of the wrapper. This snap will fire every time the shortcut widget changes.

Another option you think is to use a text widget. If you want this, you can completely disable the border. This has always been my choice when I want text text with text.

+1
source

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 ) 
+2
source

Use the Message widget :

The Message widget is a Label option for displaying multi-line messages. A message widget can wrap text and adjust its width to maintain a given aspect ratio.

+2
source

The tkinter.Message widget, proposed by some people, DOES NOT use TTK styling, which means that it will look like garbage in the TTK (theme) interface.

You can manually apply the background and foreground colors from your TTK theme, but it's not worth it ... because the ancient Message widget has zero advantages over the regular TTK ttk.Label .

The tkinter.Message widget has an aspect ratio property that determines the number of pixels before it is transferred.

Instead, ttk.Label has a wraplength= property, which determines how many pixels there are before word wraplength= . You should also use its anchor= and justify= properties to customize it to your desires.

Example: ttk.Label(root, wraplength=220, anchor=tkinter.NW, justify=tkinter.LEFT) . Creates a beautifully designed label that constantly wraps text after a width of 220 pixels.

Regarding automatic length updates? Well, you should join the <Configure> event, as people have said ... However, if you have a fully resizable window (which resizes to fit all the content), or a grid / frame that is fluid and contains a label, then you cannot automatically calculate it this way, because the parent WINDOW / CONTAINER expands itself whenever the label gets too wide. This means that the size of the label will always change to the maximum width necessary to accommodate all the text. Thus, automatic updating of the length of the wrapper is possible only if the label itself has some restrictions on how wide it can grow (either because the parent container has a fixed size / maximum size, or the fixed size / maximum size). In this case, of course, you can use configure to calculate new hyphenation numbers to ensure that the text is always hyphenated ... However, the code example from t7ko does not work and is no longer valid, just fyi.

0
source

All Articles