web-dev-qa-db-ja.com

Tkinterの画面の中央にウィンドウを配置する方法は?

私はtkinterウィンドウを中央にしようとしています。私はプログラムでウィンドウのサイズと画面のサイズを取得し、それを使用してジオメトリを設定できることを知っていますが、ウィンドウを画面の中央に置く簡単な方法があるのだろうかと思います。

45
psicopoo

メソッドwinfo_screenwidthおよびwinfo_screenheightの使用を試みることができます。これらはそれぞれTkインスタンス(ウィンドウ)の幅と高さ(ピクセル単位)を返し、いくつかの基本的な数学でウィンドウを中央に配置します。

import tkinter as tk
from PyQt4 import QtGui    # or PySide

def center(toplevel):
    toplevel.update_idletasks()

    # Tkinter way to find the screen resolution
    # screen_width = toplevel.winfo_screenwidth()
    # screen_height = toplevel.winfo_screenheight()

    # PyQt way to find the screen resolution
    app = QtGui.QApplication([])
    screen_width = app.desktop().screenGeometry().width()
    screen_height = app.desktop().screenGeometry().height()

    size = Tuple(int(_) for _ in toplevel.geometry().split('+')[0].split('x'))
    x = screen_width/2 - size[0]/2
    y = screen_height/2 - size[1]/2

    toplevel.geometry("+%d+%d" % (x, y))
    toplevel.title("Centered!")    

if __== '__main__':
    root = tk.Tk()
    root.title("Not centered")

    win = tk.Toplevel(root)
    center(win)

    root.mainloop()

返される値が正確であることを確認するために、ウィンドウの幅と高さを取得する前にupdate_idletasksメソッドを呼び出しています。

Tkinterは、2つ以上のモニターが水平または垂直に拡張されているかどうかを確認しません。したがって、すべての画面の合計解像度を取得すると、ウィンドウは画面の中央のどこかに表示されます。

PyQt一方、マルチモニター環境も表示されませんが、左上モニターの解像度のみを取得します(4つのモニター、2つのアップと2つのダウンが正方形になることを想像してください) 。そのため、ウィンドウをその画面の中央に配置することで作業を行います。 PyQtTkinterの両方を使用したくない場合は、最初からPyQtを使用する方が良いでしょう。

62
Wayne Werner

ウィンドウを中央に配置する一般的な方法は、ウィンドウの左上のピクセルの適切な画面座標を計算することです。

_x = (screen_width / 2) - (window_width / 2)  
y = (screen_height / 2) - (window_height / 2)
_

ただし、これはnot正確に正確にtkinterウィンドウを中心に配置するには(少なくともWindows 7では)十分ではありません。
anyメソッドによって返されるウィンドウの幅と高さには、タイトルと最小/最大/閉じるボタンのある最も外側のフレームが含まれないためです。また、 メニューバー (ファイル、編集など)も含まれません。幸いなことに、これらの次元を見つける方法があります。

上記の問題を考慮しない最も基本的な機能は次のとおりです。

_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()

何よりもまず、ウィンドウの update_idletasks() メソッドを呼び出したい
ジオメトリを取得する直前に、返される値が正確であることを確認します。

geometry() メソッドで使用される ジオメトリ文字列 を理解することが重要です。
前半はウィンドウの幅と高さを除く外枠、
そして後半は外枠の左上のxとy座標です。

外枠の寸法を決定できる4つの方法があります。
winfo_rootx()は、ウィンドウの左上x座標、externalを提供します。
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 __== '__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()
_

ウィンドウが画面上を移動するのを防ぐ1つの方法は、 .attributes('-alpha', 0.0) を使用してウィンドウを完全に透明にし、ウィンドウが中央に配置された後に_1.0_に設定することです。 。 Windows 7では、withdraw()またはiconify()に続いてdeiconify()を使用してもうまく機能しないようです。このため、deiconify()ウィンドウをアクティブにするトリックとして。

37
Honest Abe

Tkはtk::PlaceWindowとしてこれを実行できるヘルパー関数を提供しますが、Tkinterでラップされたメソッドとして公開されているとは思わない。次を使用してウィジェットを中央に配置します。

from tkinter import *

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

この関数は、複数のディスプレイも正しく処理する必要があります。また、別のウィジェットの中央に配置するオプションや、ポップアップメニューを配置するために使用されるポインターを基準にして、画面から落ちないようにするオプションもあります。

18
patthoyts

私は同じ質問の解決策を見つけました このサイトで

from tkinter import Tk
from tkinter.ttk import Label
root = Tk()
Label(root, text="Hello world").pack()

# Apparently a common hack to get the window size. Temporarily hide the
# window to avoid update_idletasks() drawing the window in the wrong
# position.
root.withdraw()
root.update_idletasks()  # Update "requested size" from geometry manager

x = (root.winfo_screenwidth() - root.winfo_reqwidth()) / 2
y = (root.winfo_screenheight() - root.winfo_reqheight()) / 2
root.geometry("+%d+%d" % (x, y))

# This seems to draw the window frame immediately, so only call deiconify()
# after setting correct window position
root.deiconify()
root.mainloop()

確かに、私は自分の目的に応じてそれを変更しました、それは動作します。

8
Ievgen S.

この答えは初心者を理解するのに適しています

import tkinter as tk

win = tk.Tk()  # Creating instance of Tk class
win.title("Centering windows")
win.resizable(False, False)  # This code helps to disable windows from resizing

window_height = 500
window_width = 900

screen_width = win.winfo_screenwidth()
screen_height = win.winfo_screenheight()

x_cordinate = int((screen_width/2) - (window_width/2))
y_cordinate = int((screen_height/2) - (window_height/2))

win.geometry("{}x{}+{}+{}".format(window_width, window_height, x_cordinate, y_cordinate))

win.mainloop()

フレームを使用してオプションを展開します。とても簡単です。画面の中央にいくつかのボタンが必要です。ウィンドウとボタンのサイズを中央のままにします。これが私の解決策です。

frame = Frame(parent_window)
Button(frame, text='button1', command=command_1).pack(fill=X)
Button(frame, text='button2', command=command_2).pack(fill=X)
Button(frame, text='button3', command=command_3).pack(fill=X)
frame.pack(anchor=CENTER, expand=1)
1
easyScript

つかいます:

import tkinter as tk

if __== '__main__':
    root = tk.Tk()
    root.title('Centered!')

    w = 800
    h = 650

    ws = root.winfo_screenwidth()
    hs = root.winfo_screenheight()
    x = (ws/2) - (w/2)
    y = (hs/2) - (h/2)

    root.geometry('%dx%d+%d+%d' % (w, h, x, y))

    root.mainloop()
1
Hoseong Jeon