Reputation: 1217
I'm trying to figure out how to get the height of a tkInter window title bar but can't seem to find any info on how it's done.
I have tried using root.geometry()
and it seems that root.geometry()
only returns the size of the window content and not the total size of the window with title bar and border sizes. I have seen other people say that you need to ask the OS for those things. I was hoping to avoid this because it will make it harder to make the code platform independent. There must be a way to do this without going to the OS for this. Anyone know what it is I must do to get this info?
My system:
OS: Linux
KDE Plasma: 5.16.4
KDE Frameworks: 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()
Test code results:
root.winfo_x() = 100
root.winfo_y() = 100
root.geometry() = 250x250+100+100
The height of the window when measured with a screen ruler app is:
x=102, y=286
Upvotes: 9
Views: 4174
Reputation: 1
Get the difference between the rooty and the y coordinate as such:
title_bar_height = root.winfo_rooty() - root.winfo_y()
outer_window_height = root.winfo_height() + title_bar_height
Upvotes: 0
Reputation: 119
Simpler way is just testing how self.winfo_y() changes after setting geometry first time and then correct for this change.
Upvotes: 0
Reputation: 1217
I have figured this out finally. In order to get the height of the title bar I first added a frame to the window and set the window geometry('1x1'). I also had to use update_idletasks() to update tkinter internal data. After doing this I got the correct height. Seems strange to have to do it this way but it worked. Below is the code I used to get the height. Tested and works in Windows and Linux. If anyone knows of a more correct way to do this I would sure like to know. Also if anyone is using apple please let me know if the code below works.
UPDATE: I have updated the code and it's been tested in (Linux, Windows and MacOS) to give the correct title bar height. I think this is the best way to do this because you don't need to make OS dependent system calls.But I don't know whether it could work for any zoom level.
Update:now could work for any zoom level.(Test passed in 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()
Upvotes: 3
Reputation: 12672
Title bar(default) is a system setting.As far as I know,it depends on many factors.(System zoom ratio,different OS,DPI awareness and so on).
In windows,change the zoom ratio will get different value of height.
About the question: tkinter will be recognized a old software in windows,you need to set DPI awareness to make it have the system normal height(fit the system zoom ratio if your system zoom ratio is not 100%).
Normally,the height of system title bar are same:but some exception(I am not really know about winapi
),different DPI awareness will show you the different height of title bar:
The same:
To make them same and get the normal height of title bar:
import tkinter
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(2)
print(ctypes.windll.user32.GetSystemMetrics(4))
root = tkinter.Tk()
root.mainloop()
Refer: MSDN doc:GetSystemMetrics,DPI awareness(value of DPI awareness).
Upvotes: 8