You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Tkinter窗口在X轴上的完美居中?

解决Tkinter透明装饰窗口X轴居中偏移问题

问题根源

  1. 浮点数截断误差:你计算的x是浮点数,但geometry()的位置参数要求是整数,用%d格式化会直接丢弃小数部分,导致窗口位置偏离真正的中点。
  2. 预设尺寸与实际渲染差异:使用overrideredirect(True)后,窗口无系统边框,但预设的self.width/height可能和实际渲染的窗口尺寸(受字体、DPI缩放影响)不一致,导致居中计算失效。

修复方案

  1. 对计算出的位置值做四舍五入取整,避免截断误差。
  2. 先创建所有UI部件,再调用update_idletasks()获取窗口实际尺寸,用实际尺寸重新计算居中位置,适配不同DPI环境。

修改后的完整代码

from tkinter import *
from time import strftime

class ClockApp:
    def __init__(self):
        self.root = Tk()
        self.root.overrideredirect(True)
        self.root.configure(bg="black")
        self.root.wm_attributes('-transparentcolor', 'black')
        self.root.wm_attributes('-topmost', False)

        # 先创建UI部件
        self.create_widgets()
        # 更新任务以获取实际窗口尺寸
        self.root.update_idletasks()

        # 获取实际窗口尺寸,替代预设值
        self.width = self.root.winfo_width()
        self.height = self.root.winfo_height()
        screenWidth = self.root.winfo_screenwidth()
        screenHeight = self.root.winfo_screenheight()

        # 四舍五入取整,避免浮点数截断
        x = round((screenWidth - self.width) / 2)
        y = round((screenHeight - self.height) / 3.5)

        self.root.geometry("%dx%d+%d+%d" % (self.width, self.height, x, y))
        self.root.resizable(False, False)

        self.update()
        self.root.mainloop()

    def create_widgets(self):
        self.hrmin_label = Label(self.root, font=("Consolas", 100), fg="white", bg="black")
        self.hrmin_label.grid(row=0, column=0, rowspan=2)

        self.sec_label = Label(self.root, font=("Consolas", 50), fg="white", bg="black")
        self.sec_label.grid(row=1, column=1)

        self.ampm_label = Label(self.root, font=("Consolas", 50), fg="white", bg="black")
        self.ampm_label.grid(row=0, column=1)

        self.day_label = Label(self.root, font=("Consolas", 35), fg="white", bg="black")
        self.day_label.grid(row=3, column=0, columnspan=2)

    def update(self):
        hrmin_string = strftime("%I:%M")
        self.hrmin_label.config(text=hrmin_string)

        sec_string = strftime("%S")
        self.sec_label.config(text=sec_string)

        ampm_string = strftime("%p")
        self.ampm_label.config(text=ampm_string)

        day_string = strftime("%A, %B %d")
        self.day_label.config(text=day_string)

        self.root.after(1000, self.update)

if __name__ == "__main__":
    ClockApp()

关键修改点

  • 把create_widgets()移到update_idletasks()之前,确保能获取到窗口实际渲染后的尺寸。
  • 用self.root.winfo_width()/winfo_height()替代预设的固定尺寸,适配字体、DPI带来的尺寸变化。
  • 用round()对位置值取整,避免浮点数转整数时的截断误差。

内容的提问来源于stack exchange,提问作者Mincrfter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:40:12