如何准确保存与恢复Tkinter主窗口的尺寸和位置
精准保存并恢复Tkinter窗口位置的问题(Ubuntu GNOME环境)
我尝试使用Tkinter保存并恢复主窗口的位置,但遇到了问题:保存geometry()返回的几何值(以及其他获取位置的方法)无法得到准确结果。恢复窗口时,位置会比之前的位置稍微偏左上;其他获取位置的方法返回的x值正确,但y值会偏移标题栏的高度。我的运行环境是Ubuntu(Pop!_OS),使用GNOME桌面。
以下是我的代码:
from tkinter import * from os.path import exists import json settings = {} SettingFile = "mysettings.json" class MyRoot(Tk): def __init__(self): super().__init__() wndCfg = { 'Size': [400, 400], 'Pos': [100, 100]} if 'MainWnd' in settings: wndCfg = settings['MainWnd'] else: settings['MainWnd'] = wndCfg s = wndCfg['Size'] p = wndCfg['Pos'] self.geometry(f"{s[0]}x{s[1]}+{p[0]}+{p[1]}") def destroy(self): wndGeometry = self.geometry() parts = wndGeometry.split('+') wndPos = [int(parts[1]), int(parts[2])] parts = parts[0].split('x') wndSize = [int(parts[0]), int(parts[1])] # Various other options for getting the window position, x is correct, # y is off by the height of the title bar pos0 = [self.winfo_x(), self.winfo_y()] pos1 = [self.winfo_rootx(), self.winfo_rooty()] settings['MainWnd']['Pos'] = wndPos # pos0 pos1 settings['MainWnd']['Size'] = wndSize super().destroy() if __name__ == '__main__': if exists(SettingFile): with open(SettingFile, 'r') as cfgFile: settings = json.load(cfgFile) root = MyRoot() root.mainloop() with open(SettingFile, 'w') as cfgFile: json.dump(settings, cfgFile, indent=2)
后续测试更新
- 尝试运行计算窗口装饰区域的代码,得到标题栏高度为65,但实际通过截图测量的标题栏高度是37。在原代码中使用
winfo_x()和winfo_y()-37保存位置,恢复效果完美。 - 运行另一篇获取标题栏高度的代码,得到的高度为137,结果明显不准确。
- 尝试延迟设置
geometry直到第一个Map事件发布后执行,和原代码效果无差异。进一步测试发现:只有移动窗口后退出再重启,才会出现位置偏移;如果不移动窗口,多次重启应用,窗口都会出现在同一位置。
内容的提问来源于stack exchange,提问作者Murrgon
相关产品推荐
相关产品推荐

