Fitting text into a rectangle (width x by height y) with tkinter

佐手、 提交于 2019-12-12 02:34:18

问题


I'm trying to make a program which will fit text into a rectangle (x by y) depending on the text, the font and the font size

Here is the code

def fit_text(screen, width, height, text, font):
    measure_frame = Frame(screen) # frame
    measure_frame.pack()
    measure_frame.pack_forget()
    measure = Label(measure_frame, font = font) # make a blank label
    measure.grid(row = 0, column = 0) # put it in the frame

    ##########################################################
    # make a certain number of lines
    ##########################################################

    words = text.split(" ")
    lines = []
    num = 0
    previous = 0
    while num <= len(words):                
        measure.config(text = " ".join(words[previous:num])) # change text
        line_width = measure.winfo_width() # get the width
        print(line_width)
        if line_width >= width: # if the line is now too long
            lines.append(" ".join(words[previous:num - 1])) # add the last vsion which wasn't too long
            previous = num - 1 # previous is now different
        num = num + 1 # next word
    lines.append(" ".join(words[previous:])) # add the rest of it
    return "\n".join(lines)

from tkinter import *    
window = Tk()
screen = Canvas(window)
screen.pack()
text = fit_text(screen, 200, 80, "i want to fit this text into a rectangle which is 200 pixels by 80 pixels", ("Purisa", 12))
screen.create_rectangle(100, 100, 300, 180)
screen.create_text(105, 105, text = text, font = ("Purisa", 12), anchor = "nw")

The problem with this is no matter what text is in the label the result from measure.winfo_width() is always 1. Here is where I found this from but it doesn't seem to work for me


回答1:


The problem with your code is that you're using the width of a widget, but the width will be 1 until the widget is actually laid out on the screen and made visible, since the actual width depends on a number of factors that aren't present until that happens.

You don't need to put the text in a widget in order to measure it. You can pass a string to font.measure() and it will return the amount of space required to render that string in the given font.

For python 3.x you can import the Font class like this:

from tkinter.font import Font

For python 2.x you import it from the tkFont module:

from tkFont import Font

You can then create an instance of Font so that you can get information about that font:

font = Font(family="Purisa", size=18)
length = font.measure("Hello, world")
print "result:", length

You can also get the height of a line in a given font with the font.metrics() method, giving it the argument "linespace":

height = font.metrics("linespace")



回答2:


The widget will not have a width until it is packed. You need to put the label into the frame, then pack it, then forget it.




回答3:


I've actually stumbled across a way of doing this through trial and error

By using measure.update_idletasks() it calculates the width properly and it works! Bryan Oakley definitely has a more efficient way of doing it though but I think this method will be useful in other situations

P.S. I wouldn't mind some votes to get a nice, shiny, bronze, self-learner badge ;)



来源:https://stackoverflow.com/questions/39311244/fitting-text-into-a-rectangle-width-x-by-height-y-with-tkinter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!