3 回答

TA貢獻1829條經(jīng)驗 獲得超7個贊
最簡單(但可能不準確)的方法是使用tk :: PlaceWindow,該方法將頂級窗口的ID作為參數(shù)。
使窗口居中的一般方法是為窗口的左上像素計算適當?shù)钠聊蛔鴺耍?/p>
x = (screen_width / 2) - (window_width / 2)
y = (screen_height / 2) - (window_height / 2)
使用tkinter時,您總是希望 在檢索任何幾何圖形之前直接調(diào)用該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),或者更具體地使用某些時窗口管理器,因為窗口的寬度和高度由返回任何方法將不包括最外層框架,與該標題和最小/最大/關(guān)閉按鈕。它還不包括菜單欄 (帶有文件,編輯等)。幸運的是,有一種方法可以找到這些尺寸。
首先,您需要了解該方法使用的幾何字符串geometry()。
前半部分是窗口的寬度和高度(不包括外部框架),
后半部分是外部框架的左上角x和y坐標。
有四種方法可以讓我們確定外框的尺寸。
winfo_rootx()將為我們提供窗口的左上角x坐標,外框除外。
winfo_x()將為我們提供外框的左上角x坐標。
它們的區(qū)別在于外框的寬度。
frm_width = win.winfo_rootx() - win.winfo_x()
win_width = win.winfo_width() + (2*frm_width)
winfo_rooty()和之間的區(qū)別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具有智能位置,該位置可以并排放置窗口,直到屏幕滿為止。也可以將其設置為使所有窗口居中,在這種情況下,您將不會看到窗口移動的問題(如上所述)。

TA貢獻1812條經(jīng)驗 獲得超5個贊
Tk提供了一個輔助功能,可以像tk :: PlaceWindow一樣執(zhí)行此操作,但我不認為它已在Tkinter中作為包裝方法公開。您可以使用以下命令將小部件居中:
from tkinter import *
app = Tk()
app.eval('tk::PlaceWindow %s center' % app.winfo_pathname(app.winfo_id()))
app.mainloop()
此功能也應正確處理多個顯示。它還具有使另一個控件居中或相對于指針居中的選項(用于放置彈出菜單),以使它們不會從屏幕上掉落。
添加回答
舉報