为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Tkinter中将窗口居中放置在屏幕上?

如何在Tkinter中将窗口居中放置在屏幕上?

函数式编程 2019-12-27 12:52:25
我正在尝试将tkinter窗口居中。我知道我可以以编程方式获取窗口的大小和屏幕的大小,并使用它来设置几何形状,但是我想知道是否有更简单的方法来将窗口居中放置在屏幕上。
查看完整描述

3 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

最简单(但可能不准确)的方法是使用tk :: PlaceWindow,该方法将顶级窗口的ID作为参数。


使窗口居中的一般方法是为窗口的左上像素计算适当的屏幕坐标:


x = (screen_width / 2) - (window_width / 2)  

y = (screen_height / 2) - (window_height / 2)

使用tkinter时,您总是希望 在检索任何几何图形之前直接调用该update_idletasks()方法

,以确保返回的值是准确的。


例如:


def center(win):

    win.update_idletasks()

    width = win.winfo_width()

    height = win.winfo_height()

    x = (win.winfo_screenwidth() // 2) - (width // 2)

    y = (win.winfo_screenheight() // 2) - (height // 2)

    win.geometry('{}x{}+{}+{}'.format(width, height, x, y))

另请参阅:winfo_reqwidth(),winfo_reqheight()


然而,这是不足够准确在某些平台上为中心的Tkinter的窗口(例如,Windows 7),或者更具体地使用某些时窗口管理器,因为窗口的宽度和高度由返回任何方法将不包括最外层框架,与该标题和最小/最大/关闭按钮。它还不包括菜单栏 (带有文件,编辑等)。幸运的是,有一种方法可以找到这些尺寸。


首先,您需要了解该方法使用的几何字符串geometry()。

前半部分是窗口的宽度和高度(不包括外部框架),

后半部分是外部框架的左上角x和y坐标。


有四种方法可以让我们确定外框的尺寸。

winfo_rootx()将为我们提供窗口的左上角x坐标,外框除外。

winfo_x()将为我们提供外框的左上角x坐标。

它们的区别在于外框的宽度。


frm_width = win.winfo_rootx() - win.winfo_x()

win_width = win.winfo_width() + (2*frm_width)

winfo_rooty()和之间的区别winfo_y()是标题栏/菜单栏的高度。


titlebar_height = win.winfo_rooty() - win.winfo_y()

win_height = win.winfo_height() + (titlebar_height + frm_width)

在一个有效的示例中,这是完整的功能:


import tkinter  # Python 3


def center(win):

    """

    centers a tkinter window

    :param win: the root or Toplevel window to center

    """

    win.update_idletasks()

    width = win.winfo_width()

    frm_width = win.winfo_rootx() - win.winfo_x()

    win_width = width + 2 * frm_width

    height = win.winfo_height()

    titlebar_height = win.winfo_rooty() - win.winfo_y()

    win_height = height + titlebar_height + frm_width

    x = win.winfo_screenwidth() // 2 - win_width // 2

    y = win.winfo_screenheight() // 2 - win_height // 2

    win.geometry('{}x{}+{}+{}'.format(width, height, x, y))

    win.deiconify()


if __name__ == '__main__':

    root = tkinter.Tk()

    root.attributes('-alpha', 0.0)

    menubar = tkinter.Menu(root)

    filemenu = tkinter.Menu(menubar, tearoff=0)

    filemenu.add_command(label="Exit", command=root.destroy)

    menubar.add_cascade(label="File", menu=filemenu)

    root.config(menu=menubar)

    frm = tkinter.Frame(root, bd=4, relief='raised')

    frm.pack(fill='x')

    lab = tkinter.Label(frm, text='Hello World!', bd=4, relief='sunken')

    lab.pack(ipadx=4, padx=4, ipady=4, pady=4, fill='both')

    center(root)

    root.attributes('-alpha', 1.0)

    root.mainloop()

一种防止看到窗口在屏幕上移动的方法是 .attributes('-alpha', 0.0)使窗口完全透明,然后将其设置1.0为居中后。为此,在Windows 7上,使用withdraw()或iconify()稍后再使用deiconify()似乎不太理想,请注意,我将deiconify()以此作为激活窗口的技巧。


您可能需要考虑向用户提供标记和/或选项来使窗口居中,而不是默认居中;否则,您的代码可能会干扰窗口管理器的功能。例如,xfwm4具有智能位置,该位置可以并排放置窗口,直到屏幕满为止。也可以将其设置为使所有窗口居中,在这种情况下,您将不会看到窗口移动的问题(如上所述)。


查看完整回答
反对 回复 2019-12-27
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

Tk提供了一个辅助功能,可以像tk :: PlaceWindow一样执行此操作,但我不认为它已在Tkinter中作为包装方法公开。您可以使用以下命令将小部件居中:


from tkinter import *


app = Tk()

app.eval('tk::PlaceWindow %s center' % app.winfo_pathname(app.winfo_id()))

app.mainloop()

此功能也应正确处理多个显示。它还具有使另一个控件居中或相对于指针居中的选项(用于放置弹出菜单),以使它们不会从屏幕上掉落。


查看完整回答
反对 回复 2019-12-27
  • 3 回答
  • 0 关注
  • 1879 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信