python - 为什么在 Tkinter 中计算的字符串的宽度和高度(以像素为单位)因平台而异?

标签 python fonts cross-platform size 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 中或作为要发送到 Nodebox 的 Python 脚本)。事情就真的出问题了:

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上python 2.6的区别。

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

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

您可以尝试通过以像素而不是点为单位指定字体来解决此问题。您可以通过使用负数作为字体大小来做到这一点。

最后,您可以添加到您的小示例代码中的一件事是打印出 font.actual() 命令的结果——您可能会在 windows 和 mac 框之间看到一些不同的东西,这将解释那里的差异。这会准确告诉您 Tk 正在使用哪种字体。

关于python - 为什么在 Tkinter 中计算的字符串的宽度和高度(以像素为单位)因平台而异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2922295/

相关文章:

java - 如何在 Java 应用程序中显示卡纳达语(印度语)字体

css @font-face 不会在所有浏览器中垂直对齐文本

python - 从 Flask 导入 Flask ImportError : No module named Flask

python - 为什么简单回归的 TensorFlow 结果与其输入相差甚远?

objective-c - 自定义字体在属性文本模式下不适用于 UILabel

java - 为什么这个 TextArea 不返回非粗体格式,或者 Font.PLAIN 就像 "add-on"一样?

c# - 使用 CrossSimpleAudioPlayer 播放声音 - Xamarin Forms

android - Flutter - 多个图标改变了每个图标的颜色

python - 用python检测网页更新

python - 在 Scrapy 的 csvexports 中使用附加模式导出项目时过滤重复条目