我试图找出如何获取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
答案 0 :(得分:6)
标题栏(默认)是系统设置。据我所知,它取决于许多因素。(系统缩放比例,不同的OS,DPI感知度等)。
在Windows中,更改缩放比例将获得不同的高度值。
关于此问题: tkinter将在Windows中被识别为旧软件,您需要设置DPI感知使其具有系统正常的高度(如果您的系统缩放比例不是100%,则适合系统缩放比例)。
通常,系统标题栏的高度是相同的:但是有些例外(我对winapi
并不了解),不同的DPI意识会为您显示标题栏的不同高度:
相同:
要使它们相同并获得标题栏的正常高度:
import tkinter
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(2)
print(ctypes.windll.user32.GetSystemMetrics(4))
root = tkinter.Tk()
root.mainloop()
参考: MSDN文档:GetSystemMetrics,DPI awareness(value 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() 在第一次设置几何体后如何变化,然后纠正这个变化。