如何获取tkinter窗口标题栏的高度

时间:2019-09-01 00:32:12

标签: python tkinter

我试图找出如何获取tkInter窗口标题栏的高度,但似乎找不到有关其完成方式的任何信息。

我尝试使用root.geometry(),看来root.geometry()仅返回窗口内容的大小,而不返回带有标题栏和边框大小的窗口的总大小。我见过其他人说,您需要向操作系统询问这些内容。我希望避免这种情况,因为这会使使代码平台独立变得更加困难。必须有一种方法可以做到这一点,而无需为此而进入操作系统。有人知道我必须做什么才能获得此信息?

我的系统:

操作系统:Linux

KDE等离子体: 5.16.4

KDE框架: 5.61.0


import tkinter

root = tkinter.Tk()
root.geometry("250x250+100+100")
root.update_idletasks()

print('root.winfo_x() = ', root.winfo_x())
print('root.winfo_y() = ', root.winfo_y())
print('root.geometry() = ', root.geometry())

root.mainloop()

测试代码结果:

    root.winfo_x() =  100
    root.winfo_y() =  100
    root.geometry() =  250x250+100+100

使用屏幕标尺应用测量时,窗口的高度为:

x=102, y=286

3 个答案:

答案 0 :(得分:6)

标题栏(默认)是系统设置。据我所知,它取决于许多因素。(系统缩放比例,不同的OS,DPI感知度等)。

在Windows中,更改缩放比例将获得不同的高度值。


关于此问题: tkinter将在Windows中被识别为旧软件,您需要设置DPI感知使其具有系统正常的高度(如果您的系统缩放比例不是100%,则适合系统缩放比例)。

通常,系统标题栏的高度是相同的:但是有些例外(我对winapi并不了解),不同的DPI意识会为您显示标题栏的不同高度: enter image description here 相同: enter image description here

要使它们相同并获得标题栏的正常高度:

import tkinter
import ctypes

ctypes.windll.shcore.SetProcessDpiAwareness(2)
print(ctypes.windll.user32.GetSystemMetrics(4))
root = tkinter.Tk()

root.mainloop()

结果: enter image description here enter image description here

参考: MSDN文档:GetSystemMetricsDPI awarenessvalue of DPI awareness)。

答案 1 :(得分:3)

我终于弄清楚了。为了获得标题栏的高度,我首先在窗口中添加了一个框架并设置了窗口几何形状('1x1')。我还必须使用update_idletasks()更新tkinter内部数据。完成此操作后,我得到了正确的高度。似乎很奇怪,以这种方式必须这样做,但它确实有效。下面是我用来获取高度的代码。经过测试,可在Windows和Linux中使用。如果有人知道更正确的方法,我当然想知道。另外,如果有人使用苹果,请告诉我下面的代码是否有效。

更新:我已经更新了代码,并且已经在(Linux,Windows和MacOS)上进行了测试,以提供正确的标题栏高度。我认为这是最好的方法,因为您不需要进行依赖于操作系统的系统调用。但是我不知道它是否可以在任何缩放级别上工作。


更新:现在可以在任何缩放级别上使用。(测试已在Windows 10,Windows 7中通过)

import tkinter as tk
from sys import platform


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        tk.Frame(self).update_idletasks()
        self.geometry('350x200+100+100')
        self.update_idletasks()

        offset_y = 0
        if platform in ('win32', 'darwin'):
            import ctypes
            try: # >= win 8.1
                ctypes.windll.shcore.SetProcessDpiAwareness(2)
            except: # win 8.0 or less
                ctypes.windll.user32.SetProcessDPIAware()
            offset_y = int(self.geometry().rsplit('+', 1)[-1])

        bar_height = self.winfo_rooty() - offset_y
        print(f'Height: {bar_height}\nPlatform: {platform}')
        #  self.destroy()


def main():
    app = App()
    app.mainloop()


if __name__ == '__main__':
    main()

答案 2 :(得分:0)

更简单的方法是测试 self.winfo_y() 在第一次设置几何体后如何变化,然后纠正这个变化。