原因
Windows高分屏(125%/150%缩放),tkinter默认没有开启DPI感知,Windows直接把窗口位图拉伸,所以文字、界面模糊。
解决方案1(推荐)
注意:ctypes 代码 必须放在import tkinter之前!
import ctypes
# 开启DPI感知,必须在tkinter导入前面
try:
ctypes.windll.shcore.SetProcessDpiAwareness(1)
except Exception:
pass
import tkinter as tk
root = tk.Tk()
# 获取缩放因子,修正tk内部缩放
scale = ctypes.windll.shcore.GetScaleFactorForDevice(0)
root.tk.call('tk', 'scaling', scale / 75)
root.title("清晰窗口")
root.geometry("400x200")
tk.Label(root, text="文字不再模糊", font=("微软雅黑",12)).pack(pady=30)
root.mainloop()
解释
SetProcessDpiAwareness(1) = 系统DPI感知
值可以是 0、1、2
0(默认值)
值默认是 0,不感知(默认):Windows拉伸画面 → 模糊
1(系统感知)
- 程序启动时读取主显示器的缩放比例,全程固定这个缩放
- ✅ 单显示器完全够用
- ❌ 多屏场景:窗口拖到缩放不一样的副屏,界面大小 / 文字会出错,不会自动适配副屏 DPI
2(每显示器感知 Per-Monitor)
- 窗口移动到不同显示器,Windows 会通知程序当前屏幕 DPI
- 程序可以动态重新计算界面大小、字体
- ✅ 多显示器、缩放不一致场景
- ⚠️ tkinter 原生不支持动态响应 DPI 变化
坑:
即使写 SetProcessDpiAwareness(2),tkinter 不会自动跟着窗口移动重绘。
窗口从 150% 屏拖到 100% 屏,界面不会自动适配,大小错乱。
所以tkinter 一般用 1 就足够,不推荐写 2。
解决方案2:系统手动设置
适用于打包exe后常用,不用改代码,步骤:
- 找到
pythonw.exe(或者打包后的exe) - 右键 → 属性 → 兼容性
- 点击【更改高DPI设置】
- 勾选 替代高DPI缩放行为,下拉选 应用程序
- 确定,重启程序即可变清晰
解决方案3:第三方库
pip install tkinter-unblur
from tkinter_unblur import Tk
root = Tk()
root.title("清晰窗口")
root.mainloop()
补充
- Python版本建议 ≥3.9,内置Tcl/Tk版本更新,DPI适配更好
- 图片模糊:上面代码只能解决文字控件;图片(PhotoImage)本身是位图,高分屏依然会糊,要用PIL缩放图片
- Linux/mac一般不会出现这个模糊问题,只Windows高分屏特有
打包exe
用pyinstaller打包后,ctypes代码依然有效;也可以给exe单独设置兼容性DPI替代。