如何使CustomTkinter窗口和Toplevel在任意分辨率与缩放比例下居中
解决CustomTkinter主窗口与Toplevel窗口在Windows缩放环境下的居中问题
Windows的DPI缩放会导致Tkinter(CustomTkinter基于此)的屏幕分辨率获取方法返回虚拟缩放值,直接用winfo_screenwidth()/winfo_height()结合窗口尺寸计算居中坐标会出现偏移。核心解决思路是先让进程启用DPI感知,确保屏幕分辨率与窗口尺寸使用统一的逻辑单位,再计算居中坐标。
实现步骤与代码示例
1. 启用DPI感知
在创建CustomTkinter窗口前,调用Windows API设置进程的DPI感知模式,确保Tkinter获取的屏幕参数与缩放比例匹配:
import ctypes # 启用系统级DPI感知(适配全局缩放),若需多显示器不同缩放,替换为2 ctypes.windll.shcore.SetProcessDpiAwareness(1)
2. 主窗口居中实现
import customtkinter as ctk import ctypes # 必须在窗口创建前调用 ctypes.windll.shcore.SetProcessDpiAwareness(1) class CenteredMainWindow(ctk.CTk): def __init__(self): super().__init__() self.title("居中主窗口") self.geometry("600x400") # 设置窗口逻辑尺寸 self.center_window() def center_window(self): # 更新窗口任务,确保获取真实尺寸 self.update_idletasks() # 获取屏幕逻辑分辨率 screen_w = self.winfo_screenwidth() screen_h = self.winfo_screenheight() # 获取窗口逻辑尺寸 window_w = self.winfo_width() window_h = self.winfo_height() # 计算居中坐标 pos_x = int((screen_w - window_w) / 2) pos_y = int((screen_h - window_h) / 2) # 应用位置 self.geometry(f"{window_w}x{window_h}+{pos_x}+{pos_y}") if __name__ == "__main__": app = CenteredMainWindow() app.mainloop()
3. Toplevel窗口居中实现
Toplevel窗口的居中逻辑与主窗口一致,只需继承ctk.CTkToplevel并复用居中方法:
class CenteredToplevel(ctk.CTkToplevel): def __init__(self, parent): super().__init__(parent) self.title("居中Toplevel") self.geometry("400x300") self.center_window() def center_window(self): self.update_idletasks() screen_w = self.winfo_screenwidth() screen_h = self.winfo_screenheight() window_w = self.winfo_width() window_h = self.winfo_height() pos_x = int((screen_w - window_w) / 2) pos_y = int((screen_h - window_h) / 2) self.geometry(f"{window_w}x{window_h}+{pos_x}+{pos_y}") # 在主窗口中调用示例 # app = CenteredMainWindow() # top_win = CenteredToplevel(app) # app.mainloop()
关键说明
- 为什么之前的方法无效:未启用DPI感知时,
winfo_screenwidth()返回的是Windows缩放后的虚拟分辨率,而窗口尺寸是逻辑像素,两者单位不匹配,导致坐标计算偏移。 - DPI感知模式选择:
- 1:系统DPI感知,适配全局统一缩放比例
- 2:每显示器DPI感知,适合多显示器不同缩放比例的场景
- update_idletasks()的作用:确保窗口完成布局计算,避免
winfo_width()返回初始默认值(如1)导致计算错误。
内容的提问来源于stack exchange,提问作者Matias Riquelme
相关产品推荐
相关产品推荐

