Python Tkinter string in a font measures differently than same in Text widgit as string grows

a 夏天 提交于 2019-12-10 09:49:46

问题


The Text Object holding a string (in a specified font) seems to give inconsistent results depending on the length of the string. For example:

from Tkinter import *
import tkFont
root=Tk()
t_Font = tkFont.Font(family='Helvetica', size=12, weight='bold')
t_text='New.'
t_frame = Frame(root, bd=0, height=10, width=t_Font.measure(t_text))
t = Text(master=t_frame, height=1, width=len(t_text), bd=1, font=t_Font, padx=0 )
print '\n\nMeasured:',t_Font.measure(t_text),'Frame req:',t_frame.winfo_reqwidth(),'As Text:',t.winfo_reqwidth()

Measured: 38 Frame req: 38 As Text: 38

t_text='New title.'
t_frame = Frame(root, bd=0, height=10, width=t_Font.measure(t_text))
t = Text(master=t_frame, height=1, width=len(t_text), bd=1, font=t_Font, padx=0 )
print '\n\nMeasured:',t_Font.measure(t_text),'Frame req:',t_frame.winfo_reqwidth(),'As Text:',t.winfo_reqwidth()

Measured: 69 Frame req: 69 As Text: 92

The additional 6 characters increased the measured size and frame size by 31 pixels, but the Text object has increased by 54.

What is this due to?


回答1:


I realize its been 7 months, but wanted to answer this for anyone that ends up here like I did.

Short answer: if you were using a fixed-width font, then it would have been a match (e.g. "Courier New"). But Helvetica is a proportional font, so its characters are not all the same width.

The Font.measure() and Frame.winfo_reqwidth() are both using the actual size for those strings of text in that font/weight/size, because their widths are specified in pixels.

The Text widget on the other hand has its width specified in characters.

So its taking the number of characters each time and trying to guess for that font/weight/size how big to make the widget to handle them - but not the exact characters you're using. It uses the zero character, "0", as its average character size.

If you change your second set of t_text, t_frame, t to t_text2, t_frame2, t2, and then pack() everything and start root.mainloop(), you can play around with the 2 widgets created. The first one with "New." typed in doesn't even show the "." because the created field is slightly too small, while the second widget shows "New title." with extra spaces left. Now if you delete those and enter "0000" for the first widget, and "0000000000" for the second, you'll see the widgets filled up exactly.

I found this through reading the Tcl/Tk docs for text -width at https://www.tcl.tk/man/tcl8.6/TkCmd/text.htm#M21



来源:https://stackoverflow.com/questions/26597886/python-tkinter-string-in-a-font-measures-differently-than-same-in-text-widgit-as

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