随着字符串的增长,字体中的Tkinter字符串与文本小部件中的Tkinter字符串的度量不同

2022-04-16 00:00:00 python tkinter text frame measurement

问题描述

包含字符串(使用指定字体)的文本对象似乎会根据字符串的长度产生不一致的结果。例如:

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 '

Measured:', 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 '

Measured:', t_Font.measure(t_text), 'Frame req:', 
      t_frame.winfo_reqwidth(), 'As Text:', t.winfo_reqwidth()

Measured: 69 Frame req: 69 As Text: 92

额外的6个字符使测量大小和框架大小增加了31个像素,但文本对象增加了54个。

是什么原因造成的?


解决方案

我知道已经7个月了,但我想为像我一样最终来到这里的任何人回答这个问题。

tl;dr:如果您使用的是固定宽度字体,则应该是匹配项(例如";Courier New&qot;)。但Helvetica是一种比例字体,因此其字符的宽度并不完全相同。

tkFont.measure()Frame.winfo_reqwidth()都使用该字体/粗细/大小中的文本字符串的实际大小,因为它们的宽度是以像素为单位指定的。

另一方面,Text小部件的宽度以字符指定。

因此,它获取每次的字符数,并尝试猜测该字体/粗细/大小的大小,以使小部件能够处理它们--但不是您正在使用的确切字符。它使用零字符"0"作为其平均字符大小。

如果您将第二组t_textt_framet更改为t_text2t_frame2t2,然后pack()全部更改并开始root.mainloop(),您就可以使用创建的两个小部件了。第一个输入"New."的小部件甚至没有显示".",因为创建的字段略小,而第二个小部件显示"New title.",留有额外的空格。现在,如果您删除它们,并为第一个小部件输入"0000",为第二个小部件输入"0000000000",您将看到这些小部件完全填满了。

我是通过阅读text manual pageTk内置命令的text -width的TCL/Tk文档发现的。

相关文章