为什么 Tkinter 中字符串的计算宽度和高度(以像素为单位)因平台而异? [英] Why does the calculated width and height in pixel of a string in Tkinter differ between platforms?

查看:31
本文介绍了为什么 Tkinter 中字符串的计算宽度和高度(以像素为单位)因平台而异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Python script which needs to calculate the exact size of arbitrary strings displayed in arbitrary fonts in order to generate simple diagrams. I can easily do it with 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 的版本和/或系统:

The results seem to depend on the version of Python and/or the system:

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

Ned Batchelder 提到后,我发现字体的大小因平台而异.只要你坚持使用 Tkinter,它可能不会破坏交易,它与自身保持一致.但是我的完整程序使用 Tkinter 来执行实际绘图:它仅依靠其字体大小计算来生成输出(在 SVG 中或作为 Python 脚本发送到 Nodebox).事情真的出错了:

After Ned Batchelder mentioned it, I discovered that the size of fonts differs from platform to platform. It may not be a deal breaker as long as you stick with Tkinter, which remains consistent with itself. But my complete program does not use Tkinter to perform the actual drawing: it just relies on its font size calculations to generate an output (in SVG or as a Python script to be sent to Nodebox). And it's there that things go really wrong:

mocodo 的输出 http://grab.by/grabs/f67b951d092dd1f4f490a3bca

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

(请查看实际大小的图像.请注意这些使用的主要字体输出不是 Times,而是 Trebuchet MS.)

(Please look at the image in real size. Note that the main font used for these outputs is not Times, but Trebuchet MS.)

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

I now suspect that such discrepancies can't be avoided with Tkinter. Which other cross-platform solution would you recommend?

推荐答案

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

You have two problems. Let's tackle them one at a time

1:python 2.5 和 2.6 同平台同字体的区别

1: the difference between python 2.5 and 2.6 on the same platform with the same font

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

These two versions of python use different versions of tk. On my mac box, 2.5 uses tk version 8.4.19 and 2.6 uses 8.5.7. In version 8.5.2 of tk were some changes to the font measurement features of tk. Assuming that the changes were improvements, I think it's safe to assume that the numbers you get from python 2.6 are more accurate than the ones from 2.5.

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

2: the difference between python 2.6 on the mac and 2.6 on the PC.

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

Obviously, from the screenshots you include, the PC is using a larger font and thus you get larger numbers for the measurement. The question is, why? You are specifying the font size in points (1/72 of an inch). In order for Tk (or any rendering system) to render the font, it needs to know how many pixels are in an inch on the actual display. This will vary on different systems, and Tk isn't always given an accurate number by the underlying OS in order to do its calculations.

从历史上看,无论实际显示如何,Apple 和 Microsoft 都将 72ppi 和 96ppi 标准化,因此数字总是会有所不同.有关 Mac 和 Windows 计算像素密度差异的更多信息,请参阅每英寸点数 维基百科上的文章.

Historically, Apple and Microsoft have standardized on 72ppi and 96ppi regardless of the actual display, so the numbers are always going to be different. For more information about the differences in how the mac and windows calculate pixel density see the Dots Per Inch article on wikipedia.

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

You might try solving this by specifying a font in pixels rather than in points. You can do this by using negative numbers for the font size.

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

Finally, one thing you might add to your little example code is to print out the result of the font.actual() command -- you might see something different between your windows and mac boxes, which would explain the differences there. This tells you exactly which font is being used by Tk.

这篇关于为什么 Tkinter 中字符串的计算宽度和高度(以像素为单位)因平台而异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆