当前位置: 首页 > 面试题库 >

为什么在Tkinter中计算的字符串宽度和高度(以像素为单位)在平台之间有所不同?

公冶谦
2023-03-14
问题内容

我有一个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,时间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)。那里真的出错了:

mocodo的输出http://grab.by/grabs/f67b951d092dd1f4f490e1469a53bca2.png

(请查看实际尺寸的图像。请注意,用于这些输出的主要字体不是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在计算像素密度方面的差异的更多信息,请参阅Wikipedia上的“每英寸点数”文章。

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

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



 类似资料:
  • 如何在Java中计算的宽度(以像素为单位)?例如,我有一个字符串说“你好世界!它的长度是多少(以像素为单位),还要考虑它的字体系列和大小?

  • 问题内容: 我想在 android中 以像素为单位计算字符串字体宽度。我有字符串数组,我将所有这些数组元素附加到一个字符串中。所以我必须在两个连续的数组元素之间设置固定的间距。我将最后一个字符串放入textview中。最后,我将这个textview添加到tablerow中。简而言之,我想查看带有标题和值的表结构。我在这里看到过很多帖子,但没有得到解决方案。 提前致谢…!!! 问题答案: 似乎上有可

  • 问题内容: 给定特定对象,有没有一种方法可以计算不使用任何GUI组件的字符串的长度(以像素为单位)? 问题答案: 那不使用任何GUI组件? 这取决于您在这里的意思。我假设您的意思是您希望在不收到的情况下进行此操作。 最好的方法是使用。AFAIK,这不会抛出: 除了使用类似的方法,我认为您不能。您需要图形上下文才能创建并提供字体大小信息。

  • 问题内容: 在Java FX 2.2中似乎没有API调用来计算文本字符串的宽度(以像素为单位)。在其他论坛上也有解决方法的建议,但是我创建或查找使用默认字体或其他方式返回String宽度的任何代码的工作都失败了。任何帮助,将不胜感激。 问题答案: 如果仅在不使用CSS的情况下测量默认字体,请执行以下操作: 将要测量的字符串放在Text对象中。 获取Text对象的布局范围的宽度。 如果你需要应用CS

  • 在JavaFX2.2中,似乎没有API调用来计算文本字符串的宽度(以像素为单位)。在其他论坛上也有关于解决方法的建议,但我使用默认字体或其他方式创建或查找返回字符串宽度的代码的努力失败了。任何帮助都将不胜感激。

  • 问题内容: 如何在Java中以像素为单位计算a的宽度? 例如,我有一个字符串说“ Hello World!”。 考虑到其字体系列和大小,它的像素长度是多少? 问题答案: 有多种方法可以实现想要的目标,例如,基于要实现的目标。 但这仅与上下文相关,并且不会转换为屏幕或打印机之类的内容。 但是,只要您具有上下文,就可以实现相同的结果。 显然,此示例使用了为上下文安装的默认字体,如果需要,可以更改…