Перейти к содержимому

Как сделать кнопку в питоне

  • автор:

Как сделать кнопку в питоне

Одним из наиболее используемых компонентов в графических программах является кнопка. В 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» передается внутри списка.

Создание надстройки Python в виде кнопки

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

Этот раздел поможет вам создать новую кнопку на новой панели инструментов, используя мастер надстроек Python . Прежде, чем начать этот процесс, убедитесь, что вы создали проект надстройки ArcMap и указали параметры проекта. Более подробная информация доступна в разделе Создание проекта надстройки. Хотя здесь демонстрируется процесс создания кнопки для ArcMap, таким же образом вы можете добавить кнопку в любое другое приложение ArcGIS Desktop . В этом разделе будет рассмотрен процесс создания простой кнопки для приближения к выбранным объектам. После этого класс Python, созданный мастером надстроек, будет рассмотрен более подробно с целью исследовать свойства и методы, которые обеспечивают функциональность вашей кнопки.

Создание надстройки в виде кнопки состоит из следующих этапов:

Иллюстрация установки свойств кнопки

  1. Создание панели инструментов или меню После того, как вы ввели все необходимые настройки проекта, нажмите на закладку Содержимое надстройки (Add-In Contents) и определите функциональность, которую изменит ваша надстройка. Кнопка может находиться на панели инструментов или в меню. В этом примере будет создана новая панель инструментов, которая будет выступать в качестве контейнера для кнопки. Более подробная информация о создании собственной панели инструментов доступна в разделе Создание надстройки в виде панели инструментов.
  2. Создание кнопки После того, как вы ввели настройки панели инструментов, вы можете создать новую кнопку. Нажмите правой кнопкой мыши на панели инструментов под названием «Toolbar» и выберите Новая кнопка (New Button) . Кнопка имеет ряд параметров, которые необходимо ввести. Ниже представлен список всех параметров с описанием каждого из них. Эти свойства сохраняются в файле config.xml вашего проекта.

Свойство Описание
Название (обязательный) Определяет название кнопки. Следующая иллюстрация показывает, как название используется в менеджере надстроек ArcGIS для определения доступных видов изменения функционала (тип надстройки обозначен в скобках): Иллюстрация параметров кнопки в менеджер надстроекСледующая иллюстрация показывает, как название используется в качестве текстовой метки, которая позволяет найти кнопку на панели инструментов. Иллюстрация заголовка кнопки на панели инструментов
Класс (обязательный) Класс Python, который выполняется при нажатии на кнопку в настольном приложении. Вся бизнес-логика вашей кнопки находится в классе Python. При создании своего класса используйте способ наименования, принятый в Python, при котором каждое слово начинается с большой буквы (например, «ZoomToSelectedFeatures», а не «zoomtoselectedfeatures»).
ID (обязательный) Уникальное название, которое поможет идентифицировать кнопку. Вы можете создать более одной кнопки в проекте, и этот идентификатор позволит вам отличать кнопки друг от друга. Желательно заменить идентификатор по умолчанию на более понятное значение. Идентификатор не должен содержать пробелов. Вы можете использовать символ подчеркивания для того, чтобы соединять слова. Нельзя использовать ключевые слова Python. Список зарезервированных слов доступен в документации Python.
Всплывающая подсказка (дополнительный) Краткое описание, которое появляется, когда курсор мыши оказывается над кнопкой в приложении.
Сообщение (дополнительный) Подробное описание того, какие функции выполняет кнопка. Это сообщение появляется под всплывающей подсказкой (ToolTip), когда курсор мыши оказывается над кнопкой.
Изображение (дополнительный) Здесь может быть изображение размером 16 х 16 пикселей, обозначающее вашу кнопку. Изображение должно быть в одном из популярных форматов (то есть .bmp , .jpg и так далее). Изображение будет скопировано в папку Images, созданную в проекте надстройки.

Последняя секция настроек кнопки — это заголовок и содержание справки. Эти свойства позволяют вам предоставить информацию, которая отобразится, когда пользователь запустит контекстно-зависимую справку. Контекстно-зависимая справка представляет собой всплывающие сообщения, которые остаются на экране, пока пользователь не нажмет на другой объект. Секция контекстно-зависимой справки состоит из следующих параметров:

Свойство Описание
Заголовок (дополнительный) Описывает тематику раздела справки.
Содержание (дополнительный)
  1. Отредактируйте скрипт Python, находящийся в папке Install , расположенной в рабочей папке, которую вы создали при помощи мастера. В скрипте будет находиться класс с названием, которое вы указали в параметре Class выше. Не изменяйте название этого класса, поскольку это название содержится в файле config.xml . Описание каждой функции и каждого свойства класса доступно в разделе Класс кнопки.
  2. Добавьте следующий код в функцию onClick(self) . Этот код добавляет функциональность, которая позволяет приближать выбранные объекты.
# Implementation of OnClick method of Button's class def onClick(self): # Get the current map document and the first data frame. mxd = arcpy.mapping.MapDocument('current') df = arcpy.mapping.ListDataFrames(mxd)[0] # Call the zoomToSelectedFeatures() method of the data frame class df.zoomToSelectedFeatures() 

Tkinter, раскрытие потенциала. + Игра на рабочем столе

Tkinter — это та библиотека, с которой на начальных этапах изучения языка python знакомились все, но обходили стороной по разным причинам. Сейчас я предлагаю вернуться назад, немного поностальгировать и открыть для себя в разы больше фич библиотеки.

ВАЖНО! Tkinter — не лучшее решение для создания больших приложений. И по большей части эта статья нацелена на начинающих программистов, которые уже имеют представление о библиотеке и хотят рыть дальше.

Улучшаем кнопки tkinter.Button

Пройдёмся по параметры кнопок, которые нам пригодятся:

  • bg — фон кнопки (background color)
  • fg — цвет текста кнопки (foreground color)
  • bd — ширина обводи
  • text — сам текст
  • command — функция исполняющаяся при нажатии
  • font — шрифт
  • relief — стиль обводки (tk.GROOVE , tk.SUNKEN , tk.RAISED , tk.RIDGE , tk.FLAT)
  • state — состояние кнопки (tk.ACTIVE , tk.DISABLED)
  • underline — подчёркнутый символ текста (>-1)
  • padx , pady — отступы по горизонтали , вертикали
  • width , height — ширина , высота (!В СТРОЧКАХ)
  • activebackground — фон кнопки при активации
  • activeforeground — цвет текста кнопки при активации
  • cursor — курсор (https://docs.huihoo.com/tkinter/tkinter-reference-a-gui-for-python/cursors.html)

Предлагаю сделать «кнопку ссылку», которая при нажатии будет перекидывать нас на какой-нибудь сайт. Библиотека webbrowser — встроенная, её не нужно устанавливать.

import tkinter as tk import webbrowser FORM = tk.Tk() # Создаём окно FORM .geometry('500x500') # Задаём размер def link(e = None): # !ОБРАТИТЕ ВНИМАНИЕ на e = None webbrowser.open('https://www.youtube.com/watch?v=dQw4w9WgXcQ') # Открываем браузер button = tk.Button(FORM,command = link,padx = 5,pady = 5,text = 'Link',bd = 0, fg = '#fff', bg = '#08f',underline = 0 , activebackground = '#fff', activeforeground = '#fff',cursor = 'hand2') # Инициализация кнопки button.pack(expand = 1) # Размещение кнопки по центру окна # Сюда мы ещё добавим код FORM.mainloop()

Выглядит уже неплохо. Предлагаю добавить смену цвета кнопки при наведении курсором мыши.

def focus_in(e = None): button.configure(fg = '#08f') # Задаём кнопке нужные цвета button.configure(bg = '#fff') def focus_out(e = None): button.configure(bg = '#08f') button.configure(fg = '#fff') button.bind('', focus_in) # При входе курсора в область кнопки выполняем focus_in button.bind('', focus_out) # При выходе курсора из области кнопки выполняем focus_out_out

Улучшаем окно программы

Начнём с добавления переключения на полноэкранного режима (верхней панели окна не видно) по клавише F11:

def fullscreen(e = None): if FORM.attributes('-fullscreen'): # Проверяем режим окна FORM.attributes('-fullscreen',False) # Меняем режим окна else: FORM.attributes('-fullscreen',True) # Меняем режим окна FORM.bind('',fullscreen) # Биндим окно

Теперь нужно сделать так, что бы пользователь не мог не нажать на ту самую ссылку. Давайте сделаем выход из приложения невозможным (возможным только через диспетчер задач (ctrl+shift+esc)).

def on_close(e = None): pass # Мы просто ничего не делаем # Может быть любой код # Можно так же спрашивать пользователя ВЫ ТОЧНО ХОТИТЕ ЗАКРЫТЬ ОКНО ? FORM.protocol("WM_DELETE_WINDOW", on_close) # Перехватываем событие выхода из приложения

Реализуем ка мы также и «приоритетный» режим, окно будет отображаться поверх остальных. Здесь я рекомендую использовать библиотеку keyboard (pip install keyboard), так как bind tkintera работает только если окно находиться в фокусе. Keyboard же никак не зависит от tkintera и расположения окон.

def topmost(e = None): if FORM.attributes('-topmost'): # Проверяем режим окна FORM.attributes('-topmost',False)# Меняем режим окна else: FORM.attributes('-topmost',True)# Меняем режим окна keyboard.add_hotkey('ctrl+1',topmost) # Привязываем событие к функции

Проблема окон, которые находятся поверх всех — что бы что-то под ними увидеть, нужно их передвигать, а это иногда бывает не удобно. Да бы избежать неудобств пользователя, мы можем добавить окну 50% прозрачности. Когда пользователь наводит курсор на окно, оно становится непрозрачным.

FORM.attributes('-alpha',0.5) # Задаём изначальное значение прозрачности def form_focus_in(e = None): FORM.attributes('-alpha',1) def form_focus_out(e = None): FORM.attributes('-alpha',0.5) FORM.bind('', form_focus_in) # При входе курсора в область окна выполняем form_focus_in FORM.bind('', form_focus_out)# При входе курсора в область окна выполняем form_focus_out 

Поэкспериментировав с выше показанным, я думаю, вы в скором времени зададитесь вопросом «Можно ли убрать верхнюю панель у окна ?». Да, можно, но вам придётся самостоятельно реализовывать передвижение и если хотите, изменение размеров окна. Плюсы своего окна начинаются и заканчиваются том, что вы полностью контролируете внешний вид и логику окна. Также есть огромный минус — пока окно открыто, оно не отображается в панели задач, по этому ему желательно давать приоритетный режим, что бы пользователь не потерял окно под другими.

from tkinter import * # Объявляем основные цвета BGCL = '#000000' CANCELCL = '#800000' CANCELHOVCL = '#400000' INFOCL = '#000080' INFOHOVCL = '#000040' BARCL = '#004000' # Если число больше min, возвращает minrep, если число больше max, возвращает maxrep def barrier(val,min = 0, max = None,minrep = None,maxrep = None): if minrep is None:minrep = min if maxrep is None: maxrep = max if not min is None and val < min:return minrep elif not max is None and val >max: return maxrep else:return val # Просто пустая функция def empty(*args,**kwargs):pass # Класс усовершенстованого окна class Form(Tk): def __init__(self,resizeable = True,exitfunc = empty,onresizefunc = empty): Tk.__init__(self) self['bg'] = BGCL self.resizeable = resizeable self.exitfunc = exitfunc self.onresizefunc = onresizefunc self.overrideredirect(True) # убираем у окна панельку self.wm_attributes('-topmost',True) # приоритетный режим self.bar = Frame(self,bg = BARCL) # Создаём свою панельку, как отдельный виджет self.bar.place(x = 0 ,y = 0,relwidth = 1,height = 24) self.closebtn = Button(self,bg = CANCELCL,fg = BGCL,relief = FLAT,command = self.Exit,bd=0,activebackground = BGCL) self.closebtn.place(width =24,height = 24,x = self.winfo_reqwidth()-24) self.wrapbtn = Button(self,bg = INFOCL,fg = BGCL,relief = FLAT,command = self.Wrap,bd=0,activebackground = BGCL) self.wrapbtn.place(width =24,height = 24,x = self.winfo_reqwidth()-48) # Здесь биндятся функции, передвигающие окно self.bar.bind("", self.StartMove) self.bar.bind("", self.StopMove) self.bar.bind("", self.OnMotion) # Обеспечиваем hover эффект кнопкам на нашей панельке self.closebtn.bind("",self.__closebtne) self.closebtn.bind("",self.__closebtnl) self.wrapbtn.bind("",self.__wrapbtne) self.wrapbtn.bind("",self.__wrapbtnl) # Запоминаем ширину и высоту окна self.width = self.winfo_reqwidth() self.height = self.winfo_reqheight() # В этом framе создавайте новые виджеты self.content = Frame(self,bg = BGCL,highlightthickness = 0) self.content.place(x=0,y = 24, width = self.width,height = self.height-24) if resizeable: # создаём кнопку изменения размера self.resizebtn = Button(self,bg = BARCL,fg = BGCL,relief = FLAT,bd=0,activebackground = BGCL,text = '=',font = ('Fixedsys',11),cursor = 'tcross') self.resizebtn.place(width =12,height = 12,x = self.winfo_reqwidth()-12,y = self.winfo_reqheight()-12) # Её hover эффект self.resizebtn.bind("",self.__resizebtne) self.resizebtn.bind("",self.__resizebtnl) # Здесь биндятся функции, меняющие размер окна self.resizebtn.bind("", self.StartResize) self.resizebtn.bind("", self.StopResize) self.resizebtn.bind("", self.OnResize) # Событие развёртывания окна (Редкое) self.bind('',self.Show) # функции hover эффектов def __closebtne(self,event = None): self.closebtn['bg'] = CANCELHOVCL def __closebtnl(self,event = None): self.closebtn['bg'] = CANCELCL def __resizebtne(self,event = None): self.resizebtn['bg'] = BGCL self.resizebtn['fg'] = BARCL def __resizebtnl(self,event = None): self.resizebtn['bg'] = BARCL self.resizebtn['fg'] = BGCL def __wrapbtne(self,event = None): self.wrapbtn['bg'] = INFOHOVCL def __wrapbtnl(self,event = None): self.wrapbtn['bg'] = INFOCL # Передвижение окна def StartMove(self, event = None): self.dragx = event.x self.dragy = event.y def StopMove(self, event = None): self.dragx = None self.dragy = None def OnMotion(self, event = None): deltax = event.x - self.dragx deltay = event.y - self.dragy x = self.winfo_x() + deltax y = self.winfo_y() + deltay self.geometry("+%s+%s" % (x, y)) # Изменение размера окна def StartResize(self, event = None): self.resizex = event.x self.resizey = event.y def StopResize(self, event = None): self.resizex = None self.resizey = None def OnResize(self, event = None): deltax = event.x - self.resizex deltay = event.y - self.resizey x = self.width + deltax y = self.height + deltay self.width =barrier(x,min=self.minsize()[0]) self.height = barrier(y,min=self.minsize()[1]) self.geometry("%sx%s" % (self.width,self.height)) self.Resize() # Функция вызывается после изменения размера, что бы заного разместить все кнопки. def Resize(self,event = None): # onresizefunc - вы можете передать функцию при инициализации, она будет выполнятся здесь self.onresizefunc(self.width,self.height) if self.resizeable: self.resizebtn.place_configure(x = self.width-12,y = self.height-12) self.closebtn.place_configure(y=0,x = self.width-24) self.wrapbtn.place_configure(y=0,x = self.width-48) self.content.place_configure(width = self.width,height = self.height-24) # Выполняется после нажатия красной кнопки def Exit(self,event = None): # exitfunc - вы можете передать функцию при инициализации, она будет выполнятся здесь self.exitfunc() self.destroy() # Сворачивает окно def Wrap(self,event = None): self.withdraw() # скрытие окна self.overrideredirect(False) # возвращаем ему панельку self.wm_state('iconic') # сворачиваем def Show(self,event = None): # Окно уже развёрнуто self.overrideredirect(True) #Просто обратно забираем панельку FORM = Form() # Создаём объект Form (изменённый Tk) FORM.minsize(200,200) #Задаём минимальный размер FORM.mainloop()

Вкратце опишу произошедшее выше. Мы создаём класс Form на основе класса Tk, то есть Form это модифицированный Tk. При инициализации объекта мы добавляем ему кнопки закрытия, сворачивания, изменения размера и два фрейма, панелька и контент. Делаем ховер эффект для каждой кнопки. Дальше реализуем перемещение окна. По нажатию на клавишу мыши координаты сохраняются, затем по мере движения мыши в соответствии с сохранёнными координатами меняется положение окна. С изменениями размера система та же, но при изменениях размера меняется также положение кнопок и. т. п.

Результат

Необычная игра

Скептик скажет «Питон не для игр, а tkinter так уж тем более». И я с этим скептиком от части согласен, tkinter НЕ для игр, для игр лучше pygame, а вот для «десктопных» игр это самое простое и единственное мне известное решение. Под «десктопной» игрой я подразумеваю игру, которая отрисовывается поверх всех окон, прямо на рабочем столе. В этом примере пиксельный человечек прыгает по окнам, это просто пример.

Как работает отрисовка поверх экрана в tkinter? Создаётся полноэкранное белое окно, на нём создаётся белый canvas, на canvase отрисовывается графика и всё белое заменяется прозрачным. Цвет не обязательно должен быть белым. В подобных играх также следует использовать keyboard, а именно функцию is_pressed() для проверки нажатия клавиш.

import tkinter as tk import keyboard FORM = tk.Tk() def Update(e = None): # Ваш игровой цикл FORM.after(int(1000/FPS),Update) FPS = 60 CANVAS = tk.Canvas(FORM,bg = 'white',bd = 0,highlightthickness = 0) CANVAS.place(x=0,y=0,width = FORM.winfo_screenwidth(),height = FORM.winfo_screenheight()) FORM.overrideredirect(True) FORM.state('zoomed') FORM.wm_attributes("-topmost", True) FORM.wm_attributes("-transparentcolor", "white") FORM.after(int(1000/FPS),Update) FORM.mainloop()

Я также напишу статью про создание «десктопной» игры в скором времени.

Чат-боты в Telegram на Python. Часть 2. Создаём и настраиваем меню

Продолжаем писать чат-бота для Telegram — добавляем кнопки и интерактив.

Иллюстрация: Катя Павловская для Skillbox Media

Антон Яценко

Антон Яценко
Изучает Python, его библиотеки и занимается анализом данных. Любит путешествовать в горах.

В первой части урока по чат-ботам для Telegram мы создали на Python эхо-бота с помощью библиотеки aiogram. Сам эхо-бот работает просто, а его функция очевидна из названия: в ответ на сообщение пользователя он присылает тот же текст. Если вы ещё не читали первую часть, начните с неё.

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

Виды клавиатур

Библиотека aiogram позволяет создать на Python клавиатуры двух видов, отличающиеся друг от друга расположением кнопок:

  • Reply-кнопки для шаблонных ответов, которые закрепляются вместо основной клавиатуры на экране. Часто используются в чат-ботах как меню. Создаются с помощью метода ReplyKeyboardMarkup.
  • Инлайн-кнопки, связанные с сообщениями в чате. При этом пользователь видит и основную клавиатуру. Создаются с помощью метода InlineKeyboardMarkup.

Создание меню

Наш эхо-бот для Telegram сейчас позволяет только отправлять текстовые сообщения и получать их обратно. Давайте проапгрейдим его и добавим кнопки с готовыми сообщениями, которые не надо вводить самому. Это будут reply-кнопки.

Нам понадобится класс ReplyKeyboardMarkup — для начала импортируем его и дополнительные необходимые классы:

Если нажать на любую кнопку, текст кнопки отправится в чат, а Telegram-бот пришлёт в ответ эту же фразу:

Можно создавать сколько угодно шаблонов, а также связывать кнопку с новыми действиями. Попробуем это на примере инлайн-клавиатур.

Инлайн-кнопки на aiogram

Инлайн-кнопки отличаются от обычных тем, что связаны не с областью клавиатуры в мессенджере, а с каким-то сообщением в Telegram-чате. Самый простой пример инлайн-кнопки — это меню в канале @BotFather, с помощью которого мы создавали токен для доступа к API Telegram. Например, вот так в нём выглядит инлайн-меню с уже созданными ботами:

Создадим на Python для нашего бота инлайн-кнопки со ссылками на Skillbox Media и курсы по программированию. Для этого вернёмся к разделу с импортами в коде и добавим ещё одну строку, чтобы можно было использовать необходимые классы:

Всё получилось. Теперь инлайн-клавиатура появляется при отправке команды /ссылки в бот.

Заключение

В нашем эхо-боте для Telegram появилось два вида меню, написанных на Python: reply-кнопки для быстрых сообщений и инлайн-кнопки для перехода на блог и сайт Skillbox. Для создания сложных ботов — например, ботов онлайн-магазинов — можно самостоятельно изучить документацию к библиотеке aiogram: попробовать новые классы, методы и объекты.

Читайте также:

  • С# для новичков: развеиваем мифы и пишем простого чат-бота
  • Тест. Какой язык создадите вы — Java или Python?
  • Что можно сделать на JavaScript и что нельзя

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

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