Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
641 views
in Technique[技术] by (71.8m points)

python - TkInter Label Change Font Size by Text Length

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

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

1 Reply

0 votes
by (71.8m points)

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()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...