Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Good morning,

I have a Tkinter label with a fixed width. In this label I have set a dynamic text. I need to change the font size (decrease or increase) when the text width is longer than label width. This is an example: enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
651 views
Welcome To Ask or Share your Answers For Others

1 Answer

To do this you need to give the label a unique font, and then use the measure method of the font to compute how much space is needed for a given string in that font. Then you just need to keep increasing or decreasing the font size until it fits in the label.

A simple way to create a label with a custom font looks something like this (for python 2.x; for 3.x the imports will be a little different):

import Tkinter as tk
import tkFont

label = tk.Label(...)
original_font = tkFont.nametofont(label.cget("font"))
custom_font = tkFont.Font()
custom_font.configure(**original_font.configure())
label.configure(font=custom_font)

Now you can use custom_font.measure(...) to figure out how many pixels you need for the label at the current font size. If the number of pixels is too big, change the size of the font and measure again. Repeat, until the font is just big enough to hold the text.

When you change the size of the font, the label will automatically redraw the text in the new font size.

Here's a complete working example that illustrates the technique:

import Tkinter as tk
import tkFont

class DynamicLabel(tk.Label):
    def __init__(self, *args, **kwargs):
        tk.Label.__init__(self, *args, **kwargs)

        # clone the font, so we can dynamically change
        # it to fit the label width
        font = self.cget("font")
        base_font = tkFont.nametofont(self.cget("font"))
        self.font = tkFont.Font()
        self.font.configure(**base_font.configure())
        self.configure(font=self.font)

        self.bind("<Configure>", self._on_configure)

    def _on_configure(self, event):
        text = self.cget("text")

        # first, grow the font until the text is too big,
        size = self.font.actual("size")
        while size < event.width:
            size += 1
            self.font.configure(size=size)

        # ... then shrink it until it fits
        while size > 1 and self.font.measure(text) > event.width:
            size -= 1
            self.font.configure(size=size)

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.label = DynamicLabel(self, text="Resize the window to see the font change", width=20)
        self.label.pack(fill="both", expand=True, padx=20, pady=20)

        parent.geometry("300x200")

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...