检测 Python TkInter 应用程序中的 DPI/比例因子



我希望我的应用程序能够检测它是否在 HiDPI 屏幕上运行,如果是,请自行扩展以便可用。正如这个问题所说,我知道我需要设置一个比例因子,这个因子应该是我的 DPI 除以 72;我的麻烦在于获得我的DPI。这是我所拥有的:

def get_dpi(window):
MM_TO_IN = 1/25.4
pxw = window.master.winfo_screenwidth()
inw = window.master.winfo_screenmmwidth() * MM_TO_IN
return pxw/inw
root = Tk()
root.tk.call('tk', 'scaling', get_dpi(root)/72)

这不起作用(在我的 4k 笔记本电脑屏幕上测试)。经过进一步检查,我意识到get_dpi()返回的是 96.0,而winfo_screenmmwidth()返回的是 1016!(谢天谢地,我的笔记本电脑宽度不超过一米)。

我假设 TkInter 在这里从一些内部检测到的 DPI 计算宽度(以毫米为单位),错误地检测为 96,但我不确定它从哪里得到这个;我目前在 Linux 上,xrdb -query返回的 DPI 为 196,因此它没有从 X 服务器获取 DPI。

有谁知道一种跨平台的方式来获取我的屏幕DPI,或者使TkInter能够正确获取它?或者,更重要的是:如何使 TkInter 在 HiDPI 屏幕上播放良好,并在普通屏幕上正常工作?谢谢!

这个答案来自这个链接,并作为上面的评论留下,但花了几个小时的搜索才找到。我还没有遇到任何问题,但如果它在您的系统上不起作用,请告诉我!

import tkinter
root = tkinter.Tk()
dpi = root.winfo_fpixels('1i')

这方面的文档说:

winfo_fpixels(number)
# Return the number of pixels for the given distance NUMBER (e.g. "3c") as float

距离数字是一个数字,后跟一个单位,所以 3c 表示 3 厘米,该函数给出屏幕 3 厘米上的像素数(如此处所示)。 因此,为了获得 dpi,我们向函数询问 1 英寸屏幕中的像素数("1i")。

我知道我回答这个问题很晚,但我想扩展@Andrew Pye的想法。你是对的,带有tkinter的GUI在具有不同DPI的不同显示器上看起来不同,只要您使用"宽度"或"高度"或"pady"或任何以像素为单位测量的东西。当我在桌面上制作 GUI 时,我注意到了这一点,但后来在我的 4K 笔记本电脑上运行了相同的 GUI(窗口和小部件在笔记本电脑上看起来要小得多)。这就是我为修复它所做的,它对我有用。

from tkinter import *
ORIGINAL_DPI = 240.23645320197045   # This is the DPI of the computer you're making/testing the script on.
def get_dpi():
screen = Tk()
current_dpi = screen.winfo_fpixels('1i')
screen.destroy()
return current_dpi
SCALE = get_dpi()/ORIGINAL_DPI    # Now this is the appropriate scale factor you were mentioning.
# Now every time you use a dimension in pixels, replace it with scaled(*pixel dimension*)
def scaled(original_width):
return round(original_width * SCALE)
if __name__ == '__main__':
root = Tk()
root.geometry(f'{scaled(500)}x{scaled(500)}')    # This window now has the same size across all monitors. Notice that the scaled factor is one if the script is being run on a the same computer with ORIGINAL_DPI. 
root.mainloop()

我使用的是 TclTk,而不是 TkInter,我知道如何做到这一点的唯一方法是从字体指标中计算出来......

% 字体指标 Tk_DefaultFont -上升 30 -下降 8 -线间距 38 -固定 0

线间距约为 DPI 的 0.2 倍(此处当前设置为 192)

最新更新