Comment centrer une fenêtre sur L'écran en Tkinter?

j'essaie de centrer une fenêtre tkinter. Je sais que je peux programmatiquement obtenir la taille de la fenêtre et la taille de l'écran et l'utiliser pour définir la géométrie, mais je me demande s'il y a une façon plus simple de centrer la fenêtre sur l'écran.

40
demandé sur nbro 2010-07-28 16:41:49

7 réponses

Vous pouvez essayer d'utiliser la méthode winfo_screenwidth et winfo_screenheight, qui renvoient respectivement la largeur et la hauteur (en pixels) de votre Tk exemple (fenêtre), et avec quelques notions de mathématiques de base, vous pouvez centrer votre fenêtre:

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 __name__ == '__main__':
    root = tk.Tk()
    root.title("Not centered")

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

    root.mainloop()

je fais appel update_idletasks méthode avant de récupérer la largeur et la hauteur de la fenêtre afin de s'assurer que les valeurs retournées sont exactes.

Tkinter ne voit pas s'il y a 2 ou plusieurs moniteurs étendus horizontalement ou vertical. Ainsi, vous obtiendrez la résolution totale de tous les écrans et votre fenêtre finira quelque part au milieu des écrans.

PyQt d'un autre côté, ne voit pas non plus d'environnement multi-moniteurs, mais il n'obtiendra que la résolution du moniteur en haut à gauche (imaginez 4 moniteurs, 2 en haut et 2 en bas faisant un carré). Donc, il fait le travail en mettant la fenêtre au centre de l'écran. Si vous ne voulez pas utiliser les deux, PyQt et Tkinter, peut-être serait-il préférable d'utiliser PyQt dès le départ.

60
répondu Wayne Werner 2018-07-26 10:01:28

l'approche générale pour centrer une fenêtre est de calculer les coordonnées appropriées de l'écran pour le pixel le plus à gauche de la fenêtre:

x = (screen_width / 2) - (window_width / 2)  
y = (screen_height / 2) - (window_height / 2)

Toutefois, c'est suffisant pour avec précision centrage d'une fenêtre tkinter (sur Windows 7 au moins);

parce que la largeur et la hauteur de la fenêtre sont retournées de la méthode n'inclura pas le cadre extérieur, avec le titre et les boutons min/max/close. Il ne sera également pas inclure un barre de menu (Fichier, Edition, etc.). Heureusement il y a un moyen pour trouver les dimensions de ceux-ci.

Voici la fonction la plus élémentaire, qui ne tient pas compte de la question susmentionnée:

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

Solutions: winfo_reqwidth(),winfo_reqheight()

tout d'Abord, et avant tout, nous voulons appeler la fenêtre update_idletasks() méthode

directement avant de récupérer la géométrie, pour s'assurer que les valeurs retournées sont exactes.

il est important de comprendre le géométrie chaînes de caractères utilisé avec l' geometry() méthode.

La première moitié est la largeur et la hauteur de la fenêtre hors l'extérieur-cadre,

et la seconde moitié est la partie supérieure gauche des coordonnées x et Y.

il y a quatre méthodes qui nous permettront de déterminer le cadre extérieur dimension.

winfo_rootx() nous donnera la coordonnée x en haut à gauche de la fenêtre, hors le cadre extérieur.

winfo_x() nous donnera la coordonnée x supérieure gauche du cadre extérieur.

Leur différence est la largeur du cadre extérieur.

frm_width = win.winfo_rootx() - win.winfo_x()
win_width = win.winfo_width() + (2*frm_width)

La différence entre winfo_rooty() et winfo_y() sera la hauteur de notre barre de titre / barre de menu.

titlebar_height = win.winfo_rooty() - win.winfo_y()
win_height = win.winfo_height() + (titlebar_height + frm_width)

Voici la fonction complète, dans un travail exemple:

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

Un moyen pour éviter de voir la fenêtre déplacer à travers l'écran est d'utiliser .attributes('-alpha', 0.0) pour rendre la fenêtre complètement transparente et la mettre à 1.0 après la fenêtre a été centré. En utilisant withdraw() ou iconify() plus tard suivi de deiconify() ne semble pas fonctionner correctement, à cet effet, sur Windows 7. Notez que j'utilise deiconify() comme une astuce pour activer la fenêtre.

32
répondu Honest Abe 2016-02-27 02:06:19

Tk fournit une fonction d'aide qui peut faire ceci comme tk::PlaceWindow, mais je ne crois pas qu'il ait été exposé comme une méthode enveloppée dans Tkinter. Vous devez centrer un widget en utilisant ce qui suit:

from tkinter import *

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

cette fonction devrait traiter les affichages multiples correctement aussi bien. Il a également des options pour centrer sur un autre widget ou relatif au pointeur (utilisé pour placer les menus popup), de sorte qu'ils ne tombent pas de l'écran.

17
répondu patthoyts 2015-05-04 01:31:00

j'ai trouvé une solution pour la même question sur ce site

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

bien sûr, je l'ai changé en conséquence à mes fins, il fonctionne.

2
répondu Ievgen S. 2017-10-20 17:29:09

j'utilise l'option frame et expand. Très simple. Je veux des boutons au milieu de l'écran. Redimensionnez la fenêtre et le bouton rester au milieu. C'est ma solution.

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
répondu easyScript 2016-11-10 09:01:53

Utilisation:

import tkinter as tk

if __name__ == '__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()
0
répondu Hoseong Jeon 2018-04-21 11:01:16

Cette réponse, c'est mieux pour la compréhension de débutant

#
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()
0
répondu Sandeep Prasad Kushwaha 2018-05-30 05:33:19