python – 为什么Tkinter中字符串像素的计算宽度和高度在平台之间有所不同?

我有一个Python脚本,需要计算以任意字体显示的任意字符串的确切大小,以生成简单的图表.我可以轻松地使用Tkinter.

import Tkinter as tk
import tkFont
root = tk.Tk()
canvas = tk.Canvas(root, width=300, height=200)
canvas.pack()
(x,y) = (5,5)
text = "yellow world"
fonts = []
for (family,size) in [("times",12),("times",24)]:
    font = tkFont.Font(family=family, size=size)
    (w,h) = (font.measure(text),font.metrics("linespace"))
    print "%s %s: (%s,%s)" % (family,size,w,h)
    canvas.create_rectangle(x,y,x+w,y+h)
    canvas.create_text(x,y,text=text,font=font,anchor=tk.NW)
    fonts.append(font) # save object from garbage collecting
    y += h+5
tk.mainloop()

结果似乎取决于Python和/或系统的版本:

Python 2.5 Mac 0S X, times 12: (63,12), times 24: (128,24). Python 2.6 Mac OS X, times 12: (64,14), times 24: (127,27). Python 2.6 Windows XP, times 12: (78,19), times 24: (169,36) http://grab.by/grabs/d24a5035cce0d8032ea4e04cb8c85959.png

在Ned Batchelder提到它之后,我发现字体的大小因平台而异.只要你坚持与自己保持一致的Tkinter,它可能不是一个交易破坏者.但我的complete program不使用Tkinter来执行实际绘图:它只依赖于其字体大小计算来生成输出(在SVG中或作为Python脚本发送到Nodebox).事情就是这样:

Output of mocodo http://grab.by/grabs/f67b951d092dd1f4f490e1469a53bca2.png

(请查看image in real size.请注意,用于这些输出的主要字体不是Times,而是Trebuchet MS.)

我现在怀疑Tkinter无法避免这种差异.您会推荐哪种其他跨平台解决方案?

解决方法:

你有两个问题.让我们一次解决一个问题

1:python 2.5和2.6在同一平台上使用相同字体的区别

这两个版本的python使用不同版本的tk.在我的Mac机上,2.5使用tk版本8.4.19,2.6使用8.5.7.在tk的8.5.2版本中,对tk的字体测量功能进行了一些更改.假设改变是改进的,我认为可以安全地假设从python 2.6获得的数字比2.5中的数字更准确.

2:mac上的python 2.6和PC上的2.6之间的区别.

显然,从您提供的屏幕截图中,PC使用的是更大的字体,因此您可以获得更大的测量数字.问题是,为什么?您以磅为单位指定字体大小(1/72英寸).为了让Tk(或任何渲染系统)渲染字体,它需要知道实际显示器上一英寸的像素数.这在不同的系统上会有所不同,并且底层操作系统并不总是给Tk提供准确的数字以进行计算.

从历史上看,无论实际显示如何,Apple和Microsoft都已将72ppi和96ppi标准化,因此数字总是不同的.有关mac和windows如何计算像素密度差异的更多信息,请参阅*上的Dots Per Inch文章.

您可以尝试通过指定字体而不是点来解决此问题.您可以使用字母大小的负数来执行此操作.

最后,您可以添加到您的小示例代码中的一件事是打印出font.actual()命令的结果 – 您可能会在Windows和Mac框之间看到不同的内容,这可以解释其中的差异.这告诉您Tk使用的确切字体.

上一篇:java – 在jdialog框中格式化文本


下一篇:javascript – 获取Web字体以在HTML5 Windows Phone应用程序上运行?