Tkinter как сделать окно по центру
Перейти к содержимому

Tkinter как сделать окно по центру

  • автор:

Окна в tkinter

В этом уроке рассмотрим основные настройки окон, в которых располагаются виджеты. Обычные окна в Tkinter порождаются не только от класса Tk , но и Toplevel . От Tk принято создавать главное окно. Если создается многооконное приложение, то остальные окна создаются от Toplevel. Методы обоих классов схожи.

Размер и положение окна

По умолчанию окно приложения появляется в верхнем левом углу экрана. Его размер (ширина и высота) определяется совокупностью размеров расположенных в нем виджетов. В случае если окно пустое, то tkinter устанавливает его размер в 200 на 200 пикселей.

С помощью метода geometry можно изменить как размер окна, так и его положение. Метод принимает строку определенного формата.

from tkinter import * root = Tk() root.geometry('600x400+200+100') root.mainloop()

Первые два числа в строке-аргументе geometry задают ширину и высоту окна. Вторая пара чисел обозначает смещение на экране по осям x и y . В примере окно размерностью 600 на 400 будет смещено от верхней левой точки экрана на 200 пикселей вправо и на 100 пикселей вниз.

Если перед обоими смещениями вместо плюса указывается минус, то расчет происходит от нижних правых углов экрана и окна. Так выражение root.geometry(‘600×400-0-0’) заставит окно появиться в нижнем правом углу.

В аргументе метода geometry можно не указывать либо размер, либо смещение. Например, чтобы сместить окно, но не менять его размер, следует написать root.geometry(‘+200+100’) .

Бывает удобно, чтобы окно появлялось в центре экрана. Методы winfo_screenwidth и winfo_screenheight возвращают количество пикселей экрана, на котором появляется окно. Рассмотрим, как поместить окно в центр, если размер окна известен:

from tkinter import * root = Tk() w = root.winfo_screenwidth() h = root.winfo_screenheight() w = w // 2 # середина экрана h = h // 2 w = w - 200 # смещение от середины h = h - 200 root.geometry(f'400x400++') root.mainloop()

Здесь мы вычитаем половину ширины и высоты окна (по 200 пикселей). Иначе в центре экрана окажется верхний левый угол окна, а не его середина.

Если размер окна неизвестен, то его можно получить с помощью того же метода geometry , но без аргументов. В этом случае метод возвращает строку, содержащую сведения о размерах и смещении, из которой можно извлечь ширину и высоту окна.

from tkinter import * root = Tk() Button(text="Button", width=20).pack() Label(text="Label", width=20, height=3).pack() Button(text="Button", width=20).pack() root.update_idletasks() s = root.geometry() s = s.split('+') s = s[0].split('x') width_root = int(s[0]) height_root = int(s[1]) w = root.winfo_screenwidth() h = root.winfo_screenheight() w = w // 2 h = h // 2 w = w - width_root // 2 h = h - height_root // 2 root.geometry('+<>+<>'.format(w, h)) root.mainloop()

Метод update_idletasks позволяет перезагрузить данные об окне после размещения на нем виджетов. Иначе geometry вернет строку, где ширина и высота равняются по одному пикселю. Видимо таковы параметры на момент запуска приложения.

По умолчанию пользователь может разворачивать окно на весь экран, а также изменять его размер, раздвигая границы. Эти возможности можно отключить с помощью метода resizable . Так root.resizable(False, False) запретит изменение размеров главного окна как по горизонтали, так и вертикали. Развернуть на весь экран его также будет невозможно, при этом соответствующая кнопка разворота исчезает.

resizable.png

Заголовок окна

По умолчанию в заголовке окна находится надпись «tk». Для установки собственного названия используется метод title .

… root.title("Главное окно")

root_title.png

Если необходимо, заголовок окна можно вообще убрать. В программе ниже второе окно ( Toplevel ) открывается при клике на кнопку, оно не имеет заголовка, так как к нему был применен метод overrideredirect с аргументом True . Через пять секунд данное окно закрывается методом destroy .

from tkinter import * def about(): a = Toplevel() a.geometry('200x150') a['bg'] = 'grey' a.overrideredirect(True) Label(a, text="About this").pack(expand=1) a.after(5000, lambda: a.destroy()) root = Tk() root.title("Главное окно") Button(text="Button", width=20).pack() Label(text="Label", width=20, height=3).pack() Button(text="About", width=20, command=about).pack() root.mainloop()

overrideredirect

Практическая работа

Напишите программу, в которой на главном окне находятся холст и кнопка «Добавить фигуру». Кнопка открывает второе окно, включающее четыре поля для ввода координат и две радиокнопки для выбора, рисовать ли на холсте прямоугольник или овал. Здесь же находится кнопка «Нарисовать», при клике на которую соответствующая фигура добавляется на холст, а второе окно закрывается. Проверку корректности ввода в поля можно опустить.

Программа на tkinter

Курс с примерами решений практических работ: pdf-версия

X Скрыть Наверх

Tkinter. Программирование GUI на Python

Tkinter как сделать окно по центру

Для позиционирования виджетов в контейнере применяются различные способы. Один из них представляет вызов у виджета метода pack() . Этот метод принимает следующие параметры:

  • expand : если равно True, то виджет заполняет все пространство контейнера.
  • fill : определяет, будет ли виджет растягиваться, чтобы заполнить свободное пространство вокруг. Этот параметр может принимать следующие значения: NONE (по умолчанию, элемент не растягивается), X (элемент растягивается только по горизонтали), Y (элемент растягивается только по вертикали) и BOTH (элемент растягивается по вертикали и горизонтали).
  • anchor : помещает виджет в определенной части контейнера. Может принимать значения n, e, s, w, ne, nw, se, sw, c, которые являются сокращениями от Noth(север — вверх), South (юг — низ), East (восток — правая сторона), West (запад — левая сторона) и Center (по центру). Например, значение nw указывает на верхний левый угол
  • side : выравнивает виджет по одной из сторон контейнера. Может принимать значения: TOP (по умолчанию, выравнивается по верхней стороне контейнера), BOTTOM (выравнивание по нижней стороне), LEFT (выравнивание по левой стороне), RIGHT (выравнивание по правой стороне).
  • ipadx : устанавливает отступ содержимого виджета от его границы по горизонтали.
  • ipady : устанавливают отступ содержимого виджета от его границы по вертикали.
  • padx : устанавливает отступ виджета от границ контейнера по горизонтали.
  • pady : устанавливает отступ виджета от границ контейнера по вертикали.

Растяжение виджета

Для растяжения виджета применяется параметру expand передается значение True (или соответствующее число). Причем при отсутствии других параметров позиционирования значение expand=True позволяет поместить виджет по центру:

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(expand=True) root.mainloop()

позиционирование виджета по центру в tkinter и python

Anchor

Параметр anchor помещает виджет в определенной части контейнера. Может принимать следующие значения:

  • n : положение вверху по центру
  • e : положение в правой части контейнера по центру
  • s : положение внизу по центру
  • w : положение в левой части контейнера по центру
  • nw : положение в верхнем левом углу
  • ne : положение в верхнем правом углу
  • se : положение в нижнем правом углу
  • sw : положение в нижнем левом углу
  • center : положение центру

Схематически это выглядит следующим образом:

позиционирование виджета в tkinter и python

Стоит отметить, что значение в кавычках для параметра anchor передается в нижнем регистре, без кавычек — в верхнем регистре

btn.pack(anchor="nw") btn.pack(anchor=NW)

Также стоит отметить, что для некоторых сценариев (например, помещение в нижней части контейнера) может потребоваться указать для параметра expand значение True. Например, поместим кнопку в верхнем левом углу:

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(anchor="nw") root.mainloop()

позиционирование виджета в контейнере в tkinter и python

Заполнение контейнера

Параметр fill позволяет заполнить пространство контейнер по горизонтали (значение X), по вертикали (значение Y) или по обеим сторонам (значение BOTH). По умолчанию значение NONE, при котором заполнение контейнера отсутствует. Например, заполним все пространство контейнера по горизонтали

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(fill=X) root.mainloop()

Метод pack и fill в tkinter Python

Для заполнения контейнера по всем сторонам также требуется установить параметр expand = True

btn.pack(fill=BOTH, expand=True)

Отступы

Параметры padx и pady позволяют указать отступы виджета от границ контейнера:

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(anchor="nw", padx=20, pady=30) root.mainloop()

Здесь кнопка смещена относительно верхнего левого угла на 20 единиц вправо и на 30 единиц вниз

Метод pack и внешние отступы виджета в tkinter Python

Выше устанавливался общий отступ от левой и правой стороны и общий отступ от верхней и нижней кромки контейнера. Поскольку кнопка позиционировалась в верхнем левом углу и имеела небольшие размеры, отступ от нижней и правой кромки контейнера нас не особо интересовали. Однако при желании мы можем задать отдельно два отступа от правой и левой границы и отдельно два отступа от верхней и нижней границ:

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(fill=X, padx=[20, 60], pady=30) root.mainloop()

В данном случае отступ слева — 20 единиц, а справа — 60 единиц

 внешние отступы виджета в tkinter Python

Параметры ipadx и ipady позволяют указать отступы содержимого виджета от границ виджета по горизонтали и вертикали соответственно:

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(expand=True, ipadx=10, ipady=10) root.mainloop()

 внутренние отступы виджета в tkinter Python

Позиционирование по стороне

Используем параметр side :

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn1 = ttk.Button(text="BOTTOM") btn1.pack(side=BOTTOM) btn2 = ttk.Button(text="RIGHT") btn2.pack(side=RIGHT) btn3 = ttk.Button(text="LEFT") btn3.pack(side=LEFT) btn4 = ttk.Button(text="TOP") btn4.pack(side=TOP) root.mainloop()

Параметр side в методе pack в Python

Комбинируя параметры side и fill, можно растянуть элемент по вертикали:

btn1 = ttk.Button(text="CLICK ME") btn1.pack(side=LEFT, fill=Y)

Отобразить форму по центру экрана по его высоте

Выставить форму по центру экрана и запретить изменение размера
Подскажите пожалуйста, как в лазарусе сделать так, чтобы форма в программе была всегда по центру и.

Как выводить Application.MessageBox по-центру приложения, а не по-центру экрана
сабж. на stackoverflow нашел вариант, как показывать это сообщение по центру приложения для.

Используя ООП, определить объект ЛУНА. Отобразить его в центре экрана
Используя ООП, определить объект ЛУНА. Отобразить его в центре экрана. (При этом использовать.

1525 / 494 / 58
Регистрация: 10.04.2009
Сообщений: 8,326
подскажите, если сделать так:

root.geometry(f'x') # ширина формыxвысота формы

почему-то отступ сверху и слева примерно на 3 см от края экрана, как сделать отображение формы по всему экрану

1525 / 494 / 58
Регистрация: 10.04.2009
Сообщений: 8,326
нечто, ноли имеют значение.

root.geometry(f'x++')

теперь почему-то отступ слева примерно на 3 мм от края экрана, как сделать отображение формы по всему экрану??
спс

Костыли любой сложности
201 / 146 / 36
Регистрация: 27.10.2019
Сообщений: 843

Ципихович Эндрю, это формат —geometry из linux (и что я замечу он нефига не интуитифно понятный). Всё что помню про это оно задаёт xy и ширину и высоту, то есть ‘+’ там можно заменить на ‘-‘ .

Но три мм это скорее всего ширина рамки фрейма, можешь попробовать так
x-3+0

1525 / 494 / 58
Регистрация: 10.04.2009
Сообщений: 8,326

ЦитатаСообщение от user-ganz Посмотреть сообщение

шикардос, гадание на кофейной гуще, это отсюда:

ЦитатаСообщение от Ципихович Эндрю Посмотреть сообщение

теперь почему-то отступ слева примерно на 3 мм от края экрана

from win32api import GetSystemMetrics w.resize(GetSystemMetrics(0), GetSystemMetrics(1))

тоже самое, тут как править без кофе можно?

Добавлено через 4 минуты

ЦитатаСообщение от Ципихович Эндрю Посмотреть сообщение

опробовал — не катит

ЦитатаСообщение от Ципихович Эндрю Посмотреть сообщение

Как в Tkinter отцентровать окно внутри другого окна?

У меня есть некое окно с кнопками. Одна из кнопок открывает еще одно окно. Как можно сделать так, чтобы второе окно, которое открывается по кнопке, открывалось по центру первого окна? Или хотя бы не выходило за его пределы.
В гугле не нашел ничего похожего кроме того как в целом можно отцентровать окно, но как связать окна между собой не ясно. Буквально вчера начал изучать python по этому пока не могу даже наводящими поисковыми запросами вырулить в нужное направление.

  • Вопрос задан 01 июн.
  • 85 просмотров

1 комментарий

Простой 1 комментарий

TosterModerator

Модератор @TosterModerator

Не надо ставить как можно больше тэгов. Лучше оставить один, но конкретный, с которым проблема.
См.п.3.1 Регламента.
Если нет кода python, не ставьте тэг python . Если есть тэг более конкретный, чем python (т.е. Tkinter ) не ставьте тэг python .

Решения вопроса 0
Ответы на вопрос 1

Nicelogin

Nicelogin @Nicelogin Автор вопроса

Решил вот таким способом, отцентровав окна по отдельности. В целом удовлетворительно, так как окна открываются не абы где а примерно по центру. Так как первое окно больше, а второе меньше создается ощущение что они связаны и второе открывается внутри первого. Но это не совсем решение так как если изменить настройки открытия первого второе не потянется за ним и не будет открываться внутри.

w = root.winfo_screenwidth() h = root.winfo_screenheight() w = w//2 # середина экрана h = h//2 w = w - 200 # смещение от середины h = h - 200 root.geometry('400x400+<>+<>'.format(w, h))

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *