我试图弄清楚如何获得 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()
Run Code Online (Sandbox Code Playgroud)
测试代码结果:
root.winfo_x() = 100
root.winfo_y() = 100
root.geometry() = 250x250+100+100
Run Code Online (Sandbox Code Playgroud)
使用屏幕标尺应用程序测量的窗口高度为:
x=102, y=286
Run Code Online (Sandbox Code Playgroud)
标题栏(默认)是系统设置。据我所知,它取决于很多因素。(系统缩放比例、不同的操作系统、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()
Run Code Online (Sandbox Code Playgroud)
请参阅:MSDN 文档:GetSystemMetrics,DPI 意识(DPI 意识的价值)。
我终于明白了这一点。为了获得标题栏的高度,我首先向窗口添加了一个框架并设置窗口几何形状('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()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1455 次 |
最近记录: |