Can't prevent label from extending the main window

Viewed 112

Example

(mimics the relevant parts of the layout in my real code)

import Tkinter as tk
import ttk

# set up root
root = tk.Tk()
root.minsize(300, 50)
frame = ttk.Frame(root)
frame.grid(row=0, column=0, sticky=tk.EW)

# set up buttons that insert a short or a long string
textvar = tk.StringVar(value='foo')

def insert_short():
    textvar.set('foo')

def insert_long():
    textvar.set('foo'*30)

button_short = ttk.Button(frame, text='short', command=insert_short)
button_short.grid(row=0, column=0)
button_long = ttk.Button(frame, text='long', command=insert_long)
button_short.grid(row=0, column=0)
button_long.grid(row=0, column=1)

# set up label

# border for label to see its size
style = ttk.Style()
style.configure(
    'Bordered.TLabel', foreground='black', borderwidth=1, relief='solid')

# make label extend to the right
frame.columnconfigure(2, weight=1)

# place label
label = ttk.Label(frame, textvariable=textvar, style='Bordered.TLabel')
label.grid(row=0, column=2, sticky=tk.EW)

# place some other widget under label to mimic my real code
ttk.Button(frame, text='some other widget').grid(row=1, column=2)

# TRIED, NOT WORKING:
#root.resizable(False, False)
#frame.propagate(False)
#frame.grid_propagate(False)
#label.propagate(False)
#label.grid_propagate(False)

root.mainloop()

Output

Question

How do I prevent label from extending the main window?

(Bonus question, but not important: is there a way to make the label scrollable if it gets too long?)

Attempts

I tried the following commands:

root.resizable(False, False)
frame.propagate(False)
frame.grid_propagate(False)
label.propagate(False)
label.grid_propagate(False)
2 Answers

You can create a scrollable label using an Entry in a read-only state and by using scrolling it will prevent the widget from extending the main window.

Try replacing your label definition with the following code:

child_frm = ttk.Frame(frame)
label = ttk.Entry(child_frm, textvariable=textvar, style='Bordered.TLabel', state='readonly')
scroll = ttk.Scrollbar(child_frm, orient='horizontal', command=label.xview)
label.config(xscrollcommand=scroll.set)
label.grid(row=0, sticky=tk.EW)
scroll.grid(row=1, sticky=tk.EW)
child_frm.grid(row=0, column=2)

By default, the width of a Label is calculated based on its contents. You can override this behavior by specifying a value for width when creating the Label.

label = ttk.Label(frame, textvariable=textvar, style='Bordered.TLabel', width=1)

Much to my surprise, when I update your code with this, the label doesn't shrink to a size suitable for displaying exactly one character. It appears that the sticky=tk.EW argument of your grid call ensures that the label stays as wide as the widest element in the column.

enter image description here

Related