Tkinter label height to fit content

Bart Kastermans bkasterm at gmail.com
Tue Sep 6 18:00:51 EDT 2011


rantingrick <rantingrick at gmail.com> writes:

> Hmm, i can replace all that code with this...

Because I stupidly forgot to repeat the original problem I had, and my
code doesn't show it (and doesn't show the correct use of the function I
wrote).  The code shows that I now know how to compute the number of
lines and item will have; in the actual program I am developing I will
take the max of these numbers and make all items that height.

This means the code I should have shown is as follows (here I first
compute the maximum height needed for any item, and then show all items
using this height).  Also in the actual program there will be scrolling
options to change the item shown by the different labels.

import Tkinter as Tk
import tkFont
import random
import sys

def genstr (j):
    rno = random.randint(4,50)
    ret_val = str(j) + ":"
    for i in range (0, rno):
        ret_val += "hello" + str(i)
    return ret_val

def gendata (lh):
    ret_val = []
    for i in range(0,lh):
        ret_val.append (genstr (i))
    return ret_val

data = gendata (100)

root = Tk.Tk()
font = tkFont.Font(family='times', size=13)

class lines:
    def __init__ (self):
        self.lastct = 1   # remember where the cutoff was last work from there

    def count (self, text, cutoff = 400):
        global font
        no_lines = 1
        start_idx = 0
        idx = self.lastct

        while True:
            if idx > len (text):
                idx = len (text)

            # shrink from guessed value
            while font.measure (text[start_idx:idx - 1]) > cutoff:
                if idx <= start_idx:
                    print "error"
                    sys.exit ()
                else:
                    idx -= 1
                    self.lastct = idx - start_idx # adjust since was too big

            # increase from guessed value (note: if first shrunk then done)
            while (idx < len (text)
                   and font.measure (text[start_idx:idx]) < cutoff):
                idx += 1
                self.lastct = idx - start_idx     # adjust since was too small

            # next line has been determined
            print "*" + text[start_idx:idx-1] + "*"
            if idx == len(text) and font.measure (text[start_idx:]) < cutoff:
                return no_lines
            elif idx == len(text):
                return no_lines + 1
            else:
                no_lines += 1
                start_idx = idx - 1
                idx = start_idx + self.lastct

lin = lines()

max_ht = 0
for i in range(0,len(data)):
    ct = lin.count(data[i], 450)
    if ct > max_ht:
        max_ht = ct

for i in range(0,min(len(data),5)):
    l = Tk.Label(root)
    l.pack()
    l['text'] = data[i]
    l['width'] = 50
    l['justify'] = Tk.LEFT
    l['anchor'] = 'w'
    l['wraplength'] = 450
    l['padx']=10
    l['pady'] = 5
    l['height'] = max_ht
    l['font'] = font
    if i % 2 == 0:
        l['background'] = 'grey80'
    else:
        l['background'] = 'grey70'

root.mainloop()



>
> #
> # Easy_as.py
> #
> import Tkinter as tk
> from ScrolledText import ScrolledText
> import tkFont
> import random
> # Create some puesdo data.
> data = [
>     '{0}.{1}'.format(x, 'blah'*random.randint(4, 50))
>     for x in range(100)
>     ]
> ##print data
> # Create the main window and a scrolled text widget.
> root = tk.Tk()
> font = tkFont.Font(family='times', size=13)
> textbox = ScrolledText(
>     root,
>     width=60,
>     height=20,
>     font=('Times', 10),
>     wrap=tk.WORD,
>     )
> textbox.pack(
>     fill=tk.BOTH,
>     expand=True,
>     padx=5,
>     pady=5,
>     )
> textbox.insert(1.0, '\n\n'.join(data))
> # Start the event loop.
> root.mainloop()
> #
> # End
> #



More information about the Python-list mailing list