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

2024-02-25

我有一个 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 0SX,乘以 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 http://grab.by/grabs/d24a5035cce0d8032ea4e04cb8c85959.png

经过 Ned Batchelder 的提及,我发现不同平台的字体大小有所不同。只要您坚持使用 Tkinter,它可能不会破坏交易,因为它与自身保持一致。但我的完整的程序 http://code.google.com/p/mocodo/ does not使用 Tkinter 执行实际绘图:它仅依靠其字体大小计算来生成输出(以 SVG 形式或作为要发送到的 Python 脚本)Nodebox http://nodebox.net/)。正是在那里,事情变得非常糟糕:

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

(请看实际尺寸的图像 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 提供准确的数字来进行计算。

从历史上看,无论实际显示如何,苹果和微软都对 72ppi 和 96ppi 进行了标准化,因此数字总是会有所不同。有关 Mac 和 Windows 计算像素密度的差异的更多信息,请参阅每英寸点数 http://en.wikipedia.org/wiki/Dots_per_inch#Computer_monitor_DPI_standards维基百科上的文章。

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

最后,您可以在小示例代码中添加的一件事是打印出font.actual()命令——您可能会看到 Windows 和 Mac 机器之间存在一些不同,这可以解释其中的差异。这会准确告诉您 Tk 使用的是哪种字体。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 为什么 Kotlin lang 只允许项目中只有一个 main 函数?

    这是否剥夺了 java 中具有多个主入口点的特性 这些入口点可以在需要时调用 UPDATE Kotlin 的最新版本允许多个main即使在同一个包中也可以运行 如果它们位于不同的文件中 项目中可以有多个主函数 但每个主函数只能有一个pack
  • 纯 CSS 使字体大小根据动态字符数量进行响应

    我知道用 Javascript 可以很容易地解决这个问题 但我只对纯 CSS 解决方案感兴趣 我想要一种动态调整文本大小的方法 以便它始终适合固定的 div 这是示例标记 div style width 200px height 1em p
  • JavaScript 跨浏览器:将字符串视为数组是否安全?

    这段代码在所有主流浏览器中都安全吗 var string 123 alert string 1 2 should alert true 不 这不安全 Internet Explorer 7 不支持按索引访问字符串 你必须使用charAt兼容
  • 如何在 swiftui 中添加自定义圆形滑动操作?

    在我的 SwiftUI 应用程序中 我想在 ListView 中设计圆形滑动操作 如以下示例所示 天气应用程序 iOS 15 我知道您可以添加这样的自定义操作 List Text Pepperoni pizza swipeActions B
  • PHP 或 MySQL 中的业务逻辑?

    在具有合理流量的网站上 如果将应用程序 业务逻辑编写为存储过程 触发器和视图 而不是编写在 PHP 代码本身中 这会重要吗 牢记可扩展性的最佳方法是什么 我无法向您提供统计数据 但除非您计划将来将 PHP 更改为另一种语言 否则我可以说将业
  • 使用 graph api 2.2 从 android 中的 facebook sdk 4.0.1 获取好友列表

    我在进行一些搜索后用于获取列表的代码如下 GraphRequestBatch batch new GraphRequestBatch GraphRequest newMyFriendsRequest accessToken new Grap
  • pg_dump 忽略表顺序?

    我最近一直在玩 PostgreSQL 并且无法理解如何备份和恢复单个表 我使用 pgadmin3 备份数据库中的单个表 以便将其复制到不同的服务器 当我尝试对文件执行 pg restore 时 收到错误消息 指出该序列不存在 pg rest
  • XmlHttpRequest.onload 未调用

    我正在玩这个XmlHttpRequest事物 在一些教程和书籍中 它是onload请求完成时调用的函数 在我的小实验中 这个函数从未被调用 这是我的代码 window onload function var url http www goo
  • 渐变剪切似乎在“无”上窒息

    我正在尝试向我的图表添加渐变裁剪 我使用了这里推荐的方法 如何在tensorflow中有效应用梯度裁剪 https stackoverflow com questions 36498127 how to effectively apply
  • Django 官方教程第 1 部分:运行时错误:cmp 中超出最大递归深度

    根据 django 教程 我创建了项目并执行了manage py runserver 如教程中所述 并且我收到错误 RuntimeError cmp 中超出了最大递归深度 有什么办法可以纠正这个问题吗 我得到这个错误 Validating
  • GoLang - 内存分配 - []byte 与 string

    在下面的代码中 c fool d byte fool fmt Printf c T d n c unsafe Sizeof c 16 bytes fmt Printf d T d n d unsafe Sizeof d 24 bytes 为
  • 非被动滚动事件处理程序的控制台警告

    当我使用 bootstrap vue 中的 Form Select 时 出现此控制台错误 我正在使用谷歌浏览器 违规 向滚动阻塞 鼠标滚轮 事件添加了非被动事件侦听器 考虑将事件处理程序标记为 被动 以使页面响应更快 我使用 axios 从
  • indexpath.row 从 1 而不是 0 开始

    我面临着 uitableview 的问题 有时 当我的表的 datasource numberofrowsinsection 有 3 个值时 cellforowatindexpath 从 0 1 而不是 0 0 开始 有人可以帮我找出发生此
  • 在 Swing 中使图像按钮看起来被按下/单击

    我创建了一个 JButton 其中有一个图像设置为代表该按钮的图标 现在 我已经设置了 setContentAreaFilled false setBorderPainted false setOpaque false 这些属性使图像按钮看
  • 多行字符串文字的语法突出显示

    我有一种自定义语言 我想在 Visual Studio Code 中为其提供语法突出显示 在这种语言中 字符串文字以双引号或单引号开头和结尾 以双引号开头的字符串文字可以包含单引号 反之亦然 不会发生任何其他引号转义 但无论起始引号类型如何
  • 将菜单项添加到 Quickbooks

    是否可以使用 QBSDK 将菜单项添加到 Quickbooks 我发现了一些我无法工作的旧例子 我已经为我的公司创建了一个自定义应用程序 并尝试通过在 Quickbooks 中创建一个菜单项来简化它 任何帮助将不胜感激 这是我到目前为止所尝
  • 替换嵌套括号中的内容

    Input ABCDEF 3 abcdef GHIJKLMN 4 5 Value OPQRSTUVW 4 5 Value 3 预期输出 ABCDEF GHIJKLMN OPQRSTUVW 到目前为止尝试过 Output Input repl
  • 单元测试 - 如何测试仅插入日志消息的“void”方法(Serilog)

    我需要测试类型的方法void 它只是使用 LOG 框架在我的 LOG 变量上插入一条消息 Serilog https serilog net 参见实现示例 public class MyClass public MyClass ILogge
  • 如何在cloudfoundry上使用kafka和storm?

    我想知道是否可以将 kafka 作为云原生应用程序运行 以及我是否可以在 Pivotal Web Services 上创建一个 kafka 集群作为服务 我不仅仅想要客户端集成 我想运行 kafka 集群 服务本身 谢谢 阿尼尔 我可以向您
  • 为什么 Tkinter 中计算的字符串宽度和高度(以像素为单位)在不同平台上有所不同?

    我有一个 Python 脚本 需要计算以任意字体显示的任意字符串的确切大小 以便生成简单的图表 我可以使用 Tkinter 轻松做到这一点 import Tkinter as tk import tkFont root tk Tk canv