【问题标题】:Python/tkinter - How do I get the window size including borders on Windows?Python/tkinter - 如何获取窗口大小,包括 Windows 上的边框?
【发布时间】:2016-01-18 19:22:56
【问题描述】:

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

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

我不想硬编码边框粗细,因为它可能会有所不同。

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

【问题讨论】:

  • 可能有更好的解决方案,但也许你可以通过使用 root.attributes('-fullscreen', True) 最大化窗口,获取框架的几何形状和屏幕分辨率然后您应该能够计算窗口边框的大小(我认为..)。我不确定你是否可以在不实际显示在屏幕上的情况下做到这一点。
  • @anderswb 窗口最大化时边框的粗细不一样。顶部边框明显变薄,左、右和下边框消失了。 (这是在 Windows 8 上)
  • 另一个想法。同样,我还没有尝试过,但我认为您必须使用 tkinter 之外的一些东西。像建议here这样的东西怎么样。
  • @anderswb 感谢您的链接,我会考虑的
  • 我认为在使用该方法显示之前可能无法获取窗口大小。不确定这是否有问题。

标签: python windows tkinter tk


【解决方案1】:

正如我们在 cmets 中所讨论的,我怀疑您是否可以使用纯 tkinter 来做到这一点。

我已尝试实施一种解决方案,以使用 win32gui 获取包括边框在内的窗口大小。根据这些信息,您应该能够实现其余的功能。不幸的是,这仅适用于 Windows 平台,需要在 pywin32 上安装。你可以得到它here。如果需要的话,我敢肯定有 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 的结果打印到控制台进行比较。

【讨论】:

    【解决方案2】:

    来自http://wiki.tcl.tk/11291

    wm geometry . 返回 contentsWidthxcontentsHeight+decorationTop+decorationLeftEdge。

    winfo rooty . 返回内容顶部 winfo rootx . 返回 contentsLeftEdge

    从中可以计算出标题栏高度和左边框宽度(通常与右下边框宽度相匹配)。这应该适用于 Windows,但不一定适用于所有平台。正如链接页面所检查的那样,由于 windows 任务栏,在确定可用屏幕区域的总高度和宽度方面也存在问题。

    【讨论】:

    • 哇,你是对的!即使我测试了所有这些方法,我也没有注意到rootyrootx 返回了客户矩形的位置。我现在正在做client_x - window_xclient_y - window_y 来计算边框的大小,并将边框的大小添加到客户端大小以获得窗口大小。像魅力一样工作!
    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多