Tkinter获取屏幕尺寸与分辨率返回错误值求助
解决Tkinter获取屏幕物理尺寸与分辨率不准的问题
问题原因
Tkinter的winfo_screenmmwidth()、winfo_screenwidth()等方法依赖Windows系统提供的逻辑DPI和缩放后分辨率,而非显示器的真实硬件参数:
- 当Windows缩放设置为125%时,Tkinter默认处于DPI不感知状态,返回的是缩放后的逻辑分辨率(1536x864=1920/1.25 x 1080/1.25)
- 屏幕毫米尺寸是通过
逻辑分辨率 / 系统DPI计算得出的,而系统DPI是基于缩放比例的虚拟值(比如125%缩放对应120DPI=96*1.25),并非显示器真实物理DPI,所以计算出的物理尺寸与实际不符。
解决方案
要获取准确的分辨率和物理尺寸,需要直接读取显示器硬件提供的参数,而非依赖系统的逻辑值。
方法1:使用第三方库screeninfo(推荐)
该库直接读取显示器的EDID硬件信息,能返回准确的物理尺寸和真实分辨率:
- 安装库:
pip install screeninfo
- 示例代码:
from screeninfo import get_monitors # 遍历所有显示器(多屏场景适用) for monitor in get_monitors(): print(f"真实分辨率: {monitor.width}x{monitor.height}") print(f"物理宽度: {monitor.width_mm}mm") print(f"物理高度: {monitor.height_mm}mm")
方法2:调用Windows API(无需第三方库)
通过ctypes调用Windows原生API,先设置进程为高DPI感知,再获取真实分辨率;同时读取注册表中的EDID信息获取物理尺寸:
获取真实分辨率
import ctypes from ctypes import wintypes user32 = ctypes.WinDLL('user32', use_last_error=True) # 设置进程为高DPI感知(绕过系统缩放) PROCESS_PER_MONITOR_DPI_AWARE = 2 user32.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) # 获取真实屏幕分辨率 SM_CXSCREEN = 0 SM_CYSCREEN = 1 real_width = user32.GetSystemMetrics(SM_CXSCREEN) real_height = user32.GetSystemMetrics(SM_CYSCREEN) print(f"真实分辨率: {real_width}x{real_height}")
获取真实物理尺寸(从注册表读取EDID)
import winreg def get_monitor_physical_size(): # 打开显示器注册表路径 reg_path = r"SYSTEM\CurrentControlSet\Enum\DISPLAY" with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_path) as display_key: i = 0 while True: try: monitor_id = winreg.EnumKey(display_key, i) with winreg.OpenKey(display_key, f"{monitor_id}\\0000") as monitor_key: # 读取EDID二进制数据 edid, _ = winreg.QueryValueEx(monitor_key, "EDID") # EDID中第21-22字节是物理宽度(mm),第23-24字节是物理高度(mm) width_mm = edid[21] + (edid[22] << 8) height_mm = edid[23] + (edid[24] << 8) print(f"物理宽度: {width_mm}mm,物理高度: {height_mm}mm") i += 1 except OSError: break get_monitor_physical_size()
验证结果
使用上述方法获取的物理尺寸会与显示器规格一致(比如你的344.2mm),分辨率也会返回真实的1920x1080。
内容的提问来源于stack exchange,提问作者Louis Barboutie
相关产品推荐
相关产品推荐

