Home > Software design >  Tkinter How to cut widgets and labels that go beyond frame width?
Tkinter How to cut widgets and labels that go beyond frame width?

Time:10-21

In my Code the user can add text and widgets to a Frame. Sometimes the row ends with a combobox, sometimes with a label. Sometimes these widgets go beyond the Frame. Is there any way to place widgets like Combobox in second row and to cut labels at the end of the frame and place the rest of it also in the second row. Thanks for help! enter image description here

Working minimal code:

from tkinter import *
from tkinter import ttk
import re
import tkinter

root = Tk()
root.resizable(False, True)
bframe = Frame(root, width=300, height=50)
bframe.grid(row=0, column=0, sticky = W)
bframe.grid_propagate(False)

linelist1 = ['some long text 1 as a label', '@combo@Aa Bb Cc Dd', 'some long text 2 as a label', 'some long text 3 as a label', '@combo@Ee Ff Gg Hh', 'some long text 4 as a label']
lines_with_combobox = [e for e, s in enumerate(linelist1) if '@combo@' in s]

for line in range(0, len(linelist1)):
    if line in lines_with_combobox:
        delete_combo_marker = re.split("@combo@", linelist1[line])
        words = delete_combo_marker.pop(0)
        word_as_values = re.split('\s ', delete_combo_marker[0])
        combobox = ttk.Combobox(bframe,width=10, values=word_as_values)
        combobox.grid(row=0, column=line, sticky= W)
    else:
        text = linelist1[line]
        Labeltext = ttk.Label(bframe, justify=LEFT ,text=text, wraplength=730)
        Labeltext.grid(row=0, column=line, sticky = W)

root.mainloop()

CodePudding user response:

In line 12, you are missing in list. So I just add duplicated. I comment out in line 7 and 11. In line 21 and 25 I made minor change. Btw, I am running out time to head home.

from tkinter import *
from tkinter import ttk
import re
import tkinter

root = Tk()
#root.resizable(False, True)
bframe = Frame(root, width=80, height=100)
bframe.grid(row=0, column=0, sticky = W)
#bframe.grid_propagate(False)

linelist1 = ['some long text 1 as a label', '@combo@Aa Bb Cc Dd', 'some long text 2 as a label', '@combo@Aa Bb Cc Dd', 'some long text 3 as a label', '@combo@Ee Ff Gg Hh', 'some long text 4 as a label', '@combo@Aa Bb Cc Dd']
lines_with_combobox = [e for e, s in enumerate(linelist1) if '@combo@' in s]

for line in range(0, len(linelist1)):
    if line in lines_with_combobox:
        delete_combo_marker = re.split("@combo@", linelist1[line])
        words = delete_combo_marker.pop(0)
        word_as_values = re.split('\s ', delete_combo_marker[0])
        combobox = ttk.Combobox(bframe,width=10, values=word_as_values)
        combobox.grid(row=line, column=1, sticky= W)
    else:
        text = linelist1[line]
        Labeltext = ttk.Label(bframe, justify=LEFT ,text=text, wraplength=730)
        Labeltext.grid(row=line, column=0, sticky = W)

root.mainloop()

Btw, I leave it up to u to fix it.

Result:

enter image description here]

CodePudding user response:

A simple solution for putting widgets in a row and having them wrap when they do not fit is to use a text widget to manage the other widgets. A text widget has wrapping features built in.

Here's an example that creates a couple of rows of widgets that need to wrap. Once the UI opens, you can resize it to see the widgets dynamically adjust to the width of the window.

import tkinter as tk

data = """
The cow is of bovine ilk;
One end is moo, the other is milk.
"""

root = tk.Tk()
text = tk.Text(root, wrap="char", background=root.cget("background"))
text.pack(fill="both", expand=True)

for line in data.strip().split("\n"):
    for word in line.split(" "):
        label = tk.Button(text, text=word)
        text.window_create("end", window=label)
    text.insert("end", "\n")
text.configure(state="disabled")

root.mainloop()

screenshot of unwrapped widgets screenshot of wrapped widgets

  • Related