Как переместить кнопку в tkinter
Перейти к содержимому

Как переместить кнопку в tkinter

  • автор:

Метод place

В конце курса рассмотрим третий и последний менеджер геометрии библиотеки tk – Place, который размещает виджеты по координатам. В tkinter использование данного управляющего размещением реализуется через метод place виджетов.

Методом place виджету указывается его положение либо в абсолютных значениях (в пикселях), либо в долях родительского окна, то есть относительно. Также абсолютно и относительно можно задавать размер самого виджета.

Основными параметрами place являются:

  • anchor (якорь) – определяет часть виджета, для которой задаются координаты. Принимает значения N, NE, E, SE, SW, W, NW или CENTER. По умолчанию NW (верхний левый угол).
  • relwidth , relheight (относительные ширина и высота) – определяют размер виджета в долях его родителя.
  • relx , rely – определяют относительную позицию в родительском виджете. Координата (0; 0) – у левого верхнего угла, (1; 1) – у правого нижнего.
  • width , height – абсолютный размер виджета в пикселях. Значения по умолчанию (когда данные опции опущены) приравниваются к естественному размеру виджета, то есть к тому, который определяется при его создании и конфигурировании.
  • x , y – абсолютная позиция в пикселях. Значения по умолчанию приравниваются к нулю.

Схема с указанием относительных координат:

Сетка относительных координат метода place

Для лучшего понимания разницы между абсолютным и относительным позиционированием рассмотрим пример:

from tkinter import * root = Tk() root.geometry('150x150') Button(bg='red').place(x=75, y=20) Button(bg='green').place(relx=0.3, rely=0.5) root.mainloop()

Абсолютные и относительные координаты виджета

Кнопка, позиция которой была жестко задана, не изменяет своего положения, когда окно раздвигается. Кнопка с относительными координатами смещается. Опции relx и rely для нее по-прежнему 0.3 и 0.5, но уже относительно нового размера окна.

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

… Label(bg='white').place(x=10, y=10, width=50, height=30) Label(bg='green').place(x=10, y=50, relwidth=0.3, relheight=0.15)

Абсолютные и относительные размеры виджета

Комбинируя различные варианты позиционирования и установки размеров, можно добиться интересных эффектов, а также неожиданных спецэффектов. Поэтому методом place следует пользоваться с осторожностью, хорошо понимая, что вы делаете.

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

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

За рамками данного курса было оставлено несколько классов пакета tkinter . Среди них PhotoImage , позволяющий использовать в программе внешние изображения форматов GIF и PGM. Экземпляры PhotoImage можно размещать на различных виджетах через опцию image .

… img = PhotoImage(file='smile.gif') l=Label(image=img)

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

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

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

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

Как переместить кнопку в tkinter

Одним из наиболее используемых компонентов в графических программах является кнопка. В tkinter кнопки представлены классом Button . Основные параметры виджета Button:

  • command : функция, которая вызывается при нажатии на кнопку
  • compund : устанавливает расположение картинки и текста относительно друг друга
  • cursor : курсор указателя мыши при наведении на метку
  • image : ссылка на изображение, которое отображается на метке
  • pading : отступы от границ вилжета до его текста
  • state : состояние кнопки
  • text : устанавливает текст метки
  • textvariable : устанавливает привязку к элементу StringVar
  • underline : указывает на номер символа в тексте кнопки, который подчеркивается. По умолчанию значение -1, то есть никакой символ не подчеркивается
  • width : ширина виджета

Добавим в окно обычную кнопку из пакета ttk:

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") # стандартная кнопка btn = ttk.Button(text="Button") btn.pack() root.mainloop()

Для создания кнопки используется конструктор Button() . В этом конструкторе с помощью параметра text можно установить текст кнопки.

Чтобы разместить виджет в контейнере (главном окне), у него вызывается метод pack() . На ОС Windows мы получим следующую кнопку:

Кнопка в tkinter в Python

Конструктор Button определяет различные параметры, которые позволяют настроить поведение и внешний вид кнопки. Однако конкретный набор параметров зависит от того, используем ли мы кнопки из пакета tkinter или из пакета tkinter.ttk.

Обработка нажатия на кнопку

Для обработки нажатия на кнопку необходимо установить в конструкторе параметр command , присвоив ему ссылку на функцию, которая будет срабатывать при нажатии:

from tkinter import * from tkinter import ttk clicks = 0 def click_button(): global clicks clicks += 1 # изменяем текст на кнопке btn["text"] = f"Clicks " root = Tk() root.title("METANIT.COM") root.geometry("250x150") btn = ttk.Button(text="Click Me", command=click_button) btn.pack() root.mainloop()

Здесь в качестве обработчика нажатия устанавливается функция click_button. В этой функции изменяется глобальная переменная clicks, которая хранит число кликов. Кроме того, изменяем текст кнопки, чтобы визуально было видно сколько нажатий произведено. Таким образом, при каждом нажатии кнопки будет срабатывать функция click_button, и количество кликов будет увеличиваться:

Обработка нажатия кнопки в tkinter и Python

Отключение кнопки

Для ttk-кнопки мы можем установить отключенное состояние с помощью метода state() , передав ему значение «disabled». С такой кнопкой пользователь не сможет взаимодействовать:

from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click Me", state=["disabled"]) btn.pack() root.mainloop()

При этом в метод state мы можем передать набор состояний, поэтому значение «disabled» передается внутри списка.

События

Обычно, чтобы приложение с графическим интерфейсом что-то делало, должны происходить те или иные события, чаще всего представляющие собой воздействие человека на элементы GUI.

Можно выделить три основных типа событий: производимые мышью, нажатиями клавиш на клавиатуре, а также события, возникающие в результате изменения виджетов. Нередко обрабатываются сочетания. Например, клик мышью с зажатой клавишей на клавиатуре.

Типы событий

При вызове метода bind событие передается в качестве первого аргумента.

Передача события в метод bind

Название события заключается в кавычки, а также в угловые скобки < и >. События описывается с помощью зарезервированных ключевых слов.

Часто используемые события, производимые мышью:

  • – клик левой кнопкой мыши
  • – клик средней кнопкой мыши
  • – клик правой кнопкой мыши
  • – двойной клик левой кнопкой мыши
  • – движение мыши
  • и т. д.
from tkinter import * def b1(event): root.title("Левая кнопка мыши") def b3(event): root.title("Правая кнопка мыши") def move(event): x = event.x y = event.y s = "Движение мышью <>x<>".format(x, y) root.title(s) root = Tk() root.minsize(width=500, height=400) root.bind('', b1) root.bind('', b3) root.bind('', move) root.mainloop()

В этой программе меняется надпись в заголовке главного окна в зависимости от того, двигается мышь, щелкают левой или правой кнопкой.

Событие ( Event ) – это один из объектов tkinter . У событий есть атрибуты, как и у многих других объектов. В примере в функции move извлекаются значения атрибутов x и y объекта event , в которых хранятся координаты местоположения курсора мыши в пределах виджета, по отношению к которому было сгенерировано событие. В данном случае виджетом является главное окно, а событием – , т. е. перемещение мыши.

В программе ниже выводится информация об экземпляре Event и некоторым его свойствам. Все атрибуты можно посмотреть с помощью команды dir(event) . У разных событий они одни и те же, меняются только значения. Для тех или иных событий часть атрибутов не имеет смысла, такие свойства имеют значения по умолчанию.

В примере хотя обрабатывается событие нажатия клавиши клавиатуры, в поля x , y , x_root , y_root сохраняются координаты положения на экране курсора мыши.

from tkinter import * def event_info(event): print(type(event)) print(event) print(event.time) print(event.x_root) print(event.y_root) root = Tk() root.bind('a', event_info) root.mainloop()

Пример выполнения программы:

  1853276 505 402

Для событий с клавиатуры буквенные клавиши можно записывать без угловых скобок (например, ‘a’ ).

Для неалфавитных клавиш существуют специальные зарезервированные слова. Например, — нажатие клавиши Enter , — пробел. (Заметим, что есть событие , которое не имеет отношения к нажатию клавиши Enter , а происходит, когда курсор заходит в пределы виджета.)

События Enter и Leave

from tkinter import * def enter_leave(event): if event.type == '7': event.widget['text'] = 'In' elif event.type == '8': event.widget['text'] = 'Out' root = Tk() lab1 = Label(width=20, height=3, bg='white') lab1.pack() lab1.bind('', enter_leave) lab1.bind('', enter_leave) lab2 = Label(width=20, height=3, bg='black', fg='white') lab2.pack() lab2.bind('', enter_leave) lab2.bind('', enter_leave) root.mainloop()

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

Функция, в зависимости от того, по отношению к какому виджету было зафиксировано событие, изменяет свойства только этого виджета. Как изменяет, зависит от произошедшего события.

Свойство event.widget содержит ссылку на виджет, сгенерировавший событие. Свойство event.type описывает, что это было за событие. У каждого события есть имя и номер. С помощью выражения print(repr(event.type)) можно посмотреть его полное описание. При этом на одних платформах str(event.type) возвращает имя события (например, ‘Enter’), на других – строковое представление номера события (например, ‘7’).

Вернемся к событиям клавиатуры. Сочетания клавиш пишутся через тире. В случае использования так называемого модификатора, он указывается первым, детали на третьем месте. Например, — одновременное нажатие клавиш Shift и стрелки вверх, – движение мышью с зажатой левой кнопкой и клавишей Ctrl .

from tkinter import * def exit_win(event): root.destroy() def to_label(event): t = ent.get() lbl.configure(text=t) def select_all(event): def select_all2(widget): widget.selection_range(0, END) widget.icursor(END) # курсор в конец root.after(10, select_all2, event.widget) root = Tk() ent = Entry(width=40) ent.focus_set() ent.pack() lbl = Label(height=3, fg='orange', bg='darkgreen', font="Verdana 24") lbl.pack(fill=X) ent.bind('', to_label) ent.bind('', select_all) root.bind('', exit_win) root.mainloop()

Пример программы, обрабатывающей события

Здесь сочетание клавиш Ctrl+a выделяет текст в поле. Без root.after() выделение не работает. Метод after выполняет функцию, указанную во втором аргументе, через промежуток времени, указанный в первом аргументе. В третьем аргументе передается значение атрибута widget объекта event . В данном случае им будет поле ent . Именно оно будет передано как аргумент в функцию select_all2 и присвоено параметру widget .

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

Напишите программу по описанию. Размеры многострочного текстового поля определяются значениями, введенными в однострочные текстовые поля. Изменение размера происходит при нажатии мышью на кнопку, а также при нажатии клавиши Enter .

Цвет фона экземпляра Text светлосерый ( lightgrey ), когда поле не в фокусе, и белый, когда имеет фокус.

Событие получения фокуса обозначается как , потери – как .

Для справки: фокус перемещается по виджетам при нажатии Tab , Ctrl+Tab , Shift+Tab , а также при клике по ним мышью (к кнопкам последнее не относится).

GUI программы

Курс с примерами решений практических работ: 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)

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

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