Python/tkinter - 如何在Windows上获取包括边框的窗口大小?

7
我正在尝试根据窗口的宽度和高度来定位我的窗口。在Windows上,wm_geometrywinfo_widthwinfo_height报告的窗口大小是客户端区域的大小,即没有边框的窗口大小。窗口的位置,由wm_geometrywinfo_xwinfo_y报告,并使用wm_geometry设置的位置是窗口左上角点的位置,包括边框。

这意味着当我尝试将窗口居中于屏幕时,其位置在屏幕上明显太低。

我不想硬编码边框厚度,因为它可能会有所变化。

是否可以使用Python/tkinter获取或推断Windows上窗口边框的大小?


可能存在更好的解决方案,但也许你可以通过使用 root.attributes('-fullscreen', True) 最大化窗口,获取框架和屏幕分辨率的几何属性,然后应该可以计算出窗口边框的大小(我想是这样的..)。不过我不确定是否可以在不实际显示窗口的情况下完成此操作。 - anderswb
@anderswb 当窗口最大化时,边框的厚度不一样。顶部边框明显更薄,左、右和底部边框消失了。(这是在Windows 8上) - Hubro
1
另一个想法。我还没有尝试过,但我认为你需要使用一些来自tkinter之外的东西。那么像这里建议的这样的东西怎么样? - anderswb
@anderswb 感谢提供链接,我会考虑的。 - Hubro
@anderswb 窗口已经打开了,这不是问题。我只是想弄清楚在内容发生变化后,将窗口移动到哪个精确的坐标位置,以保持窗口的中心位置不变。 - Hubro
显示剩余2条评论
3个回答

6

http://wiki.tcl.tk/11291

wm geometry .返回的是内容宽度x内容高度+装饰顶部+装饰左边缘。

winfo rooty .返回的是内容顶部,winfo rootx .返回的是内容左边缘。

通过这些信息,您可以计算出标题栏高度和左边框宽度(通常与右边框宽度相匹配)。这在Windows上应该有效,但不一定适用于所有平台。正如链接页面所述,还存在确定由于Windows任务栏而可用的屏幕区域的总高度和宽度的问题。


哇,你说得对!尽管我测试了所有这些方法,但我没有注意到 rootyrootx 返回的是客户端矩形的位置。现在我正在执行 client_x - window_xclient_y - window_y 来计算边框的大小,并将边框大小添加到客户端大小以获取窗口大小。运行得非常好! - Hubro

0

正如我们在评论中讨论的那样,我怀疑你无法使用纯tkinter来完成它。

我尝试使用win32gui实现获取包括边框的窗口大小的解决方案。从这些信息中,您应该能够实现其余的功能。不幸的是,这仅适用于Windows平台,并需要在pywin32上进行安装。您可以在此处获取它。如果有要求,我相信Mac和Linux也有类似的解决方案。

这是我在Python 3.4中测试的解决方案:

import tkinter as tk
import win32gui

class TestApp:
    def __init__(self, master):
        frame = tk.Frame(master)
        frame.pack()

        self.master = master

        label = tk.Label(text='Test Label')
        label.pack()
        b1 = tk.Button(text='test', command=self.pressed)
        b1.pack()

    def pressed(self):
        win32gui.EnumWindows(self.callback, None)
        x = root.winfo_x()
        y = root.winfo_y()
        w = self.master.winfo_width()
        h = self.master.winfo_height()
        print('tkinter location: ({},{})'.format(x, y))
        print('tkinter size: ({},{})'.format(w, h))


    def callback(self, hwnd, extra):
        if "Test title" in win32gui.GetWindowText(hwnd):
            rect = win32gui.GetWindowRect(hwnd)
            x = rect[0]
            y = rect[1]
            w = rect[2] - x
            h = rect[3] - y
            print('Window location: ({},{})'.format(x, y))
            print('Window size: ({},{})'.format(w, h))

root = tk.Tk()
root.title("Test title")
app = TestApp(root)
root.mainloop()

我正在使用win32gui.EnumWindows()来遍历所有可用的窗口,以定位具有正确标题的窗口。然后,我可以使用win32gui.GetWindowRect()获取其大小。
我将打印win32gui和tkinter的结果到控制台进行比较。

0
下面你可以使用tkinter的geometry函数来提取tkinter gui的坐标。
geometry_info = root.geometry()
#geometry_info format: "widthxheight + x + y"
#convert into a list of individual coordinates
delimiters = 'x+'
position_info = re.split('[' + delimiters + ']', geometry_info)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接