Справочник от Автор24
Поделись лекцией за скидку на Автор24

Событийно-ориентированное программирование

  • 👀 316 просмотров
  • 📌 299 загрузок
Выбери формат для чтения
Статья: Событийно-ориентированное программирование
Найди решение своей задачи среди 1 000 000 ответов
Загружаем конспект в формате docx
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Конспект лекции по дисциплине «Событийно-ориентированное программирование» docx
Тема: Событийно-ориентированное программирование. Программирование графического пользовательского интерфейса Все программы, рассмотренные до настоящего времени, осуществляли взаимодействие с пользователем через обычный текст. Однако часто для взаимодействия используются графические элементы (кнопки, значки, диалоговые окна, флажки, переключатели). Совокупность средств, обеспечивающих взаимодействие пользователя с операционной системой и другими программами, принято называть интерфейсом. Если взаимодействие осуществляется с использованием графических элементов на экране, то говорят о графическом интерфейсе пользователя – GUI (англ. graphical user interface). Разрабатываемый интерфейс должен быть максимально простым и обеспечивающим удобные способы ввода и вывода данных. При этом важна эстетическая составляющая: размер окон, фон, шрифт надписей, графическое и звуковое сопровождение. Все графические элементы (кнопка, поле ввода, надпись и т.д.) являются объектами (в Python их принято называть виджетами). Совокупность характеристик, описывающих объект (цвет, размер, положение на экране), называется свойствами объекта. Действие, которое может выполнить объект, называют методами. Пример. Объект – студент, свойства: факультет, группа, успеваемость; методы: посещать занятия, сдавать экзамен и т.д. Синтаксис доступа к свойствам (методам) объектов: Имя объекта.Свойство(или метод) В Python отсутствует встроенный в язык функционал программирования графического интерфейса. Однако, в стандартную библиотеку Python входит модуль tkinter – кросс-платформенная событийно-ориентированная графическая библиотека на основе средств Tk. Tkinter расшифровывается как Tk interface, и является интерфейсом к Tcl/Tk. Именно она позволяет разрабатывать GUI-программы с различными графическими элементами интерфейса. Графические интерфейсы пользователя генерируют события (то, что может произойти с объектами программы). События связываются с обработчиками (программным кодом, запускаемым при соответствующем событии). Такой стиль написания программного кода относят к событийно-ориентированному программированию. Как правило, все GUI- программы являются событийно-ориентированными. Задавая объекты, события и их обработчики, программист задает порядок работы программы. Для запуска программы необходимо создать событийный цикл, внутри которого программа будет ожидать наступления описанных событий. Когда событие происходит, программа обрабатывает его предписанным образом. Чтобы написать GUI-программу, надо выполнить следующие действия: 1. Создать главное окно 2. Создать виджеты и выполнить конфигурацию их свойств (опций) 3. Определить события, то есть то, на что будет реагировать программа 4. Описать обработчики событий, то есть то, как будет реагировать программа 5. Расположить виджеты в главном окне 6. Запустить цикл обработки событий Последовательность действий может не соблюдаться за исключением первого и последнего пунктов. Модуль tkinter предоставляет 15 элементов интерфейса Элемент Класс tkinter Описание Кнопка Button При нажатии пользователем вызывает выполнение определенного действия Флажок Сheckbutton Кнопка, которая может быть в положении «включено/выключено» (позволяет включить или выключить какой-либо параметр) Графическое поле Canvas Прямоугольная область, которая используется для отображения графики Текстовое поле Entry Область, которую пользователь может ввести одну строку входных данных с клавиатуры (принимает и отображает одну строку текста) Текстовая область Text Элемент интерфейса, позволяющий пользователю вводить многочисленные строки текстовых данных (принимает и отображает несколько строк текста) Метка Label Область, которая выводит на экран изображение (значок) или одну строку текста, который нельзя править Контейнер Frame Контейнер, который может содержать другой элемент интерфейса Контейнер с собственным окном Toplevel Контейнер, аналогичный Frame, но в отличие от него, выводимый на экран в собственном окне Переключатель Radiobutton Позволяет пользователю выбрать один параметр из нескольких сгруппированных вариантов Список Listbox Список, из которого пользователь может выбрать значение Список с ползунком Scale Элемент интерфейса, позволяющий пользователю выбирать значения путем перемещения ползунка вдоль шкалы Прокрутка Scrollbar Используется с другими типами элементов интерфейса для обеспечения возможности прокрутки Кнопка меню Menubutton Выводимое на экран меню, на которое пользователь может нажать мышью Меню Menu Список пунктов меню, выводящихся на экран при нажатии пользователем на элемент интерфейса Menubutton Сообщение Message Выводит на экран многочисленные строки текста Создание и изменение вида базового окна Отправная точка любой программы с графическим интерфейсом является базовое или корневое окно, поверх которого размещаются остальные GUI-элементы. Программа с интерфейсом tkinter может содержать только одно базовое окно. В противном случае она перестает отвечать, так как окна будут конфликтовать за приоритет. Переменную, связанную с объектом-окном, принято называть root (не является обязательным). Для назначения заголовка окна используется метод title(). Методу передается строка, которая будет отражена в заголовке. Метод geometry() устанавливает размеры базового окна в пикселях, ширина и высота окна разделяются символом x. Для запуска событийного цикла базового окна используется метод mainloop(). Он работает как бесконечный цикл до тех пор, пока окно не будет закрыто. from tkinter import* # импорт модуля tkinter root=Tk() # обращение к классу Tk() библиотеки tkinter root.title("Название окна") # задание заголовка окна root.geometry("300x200")# задание размеров окна root.mainloop()# запуск событийного цикла базового окна Большинство программистов при написании программ с GUI предпочитают использовать объектно-ориентированный подход. Вместо того, чтобы писать функцию для создания экранных элементов, общепринятой практикой является написание класса и методом _init­_, который создает GUI. Когда создается экземпляр класса, на экране появляется элемент графического интерфейса GUI. Объектно-ориентированная версия программы создания базового окна: from tkinter import* class MyGUI: def __init__(self): self.main_root = Tk() mainloop() my_gui = MyGUI() # создание экземпляра класса MyGUI приводит к выполнению метода__init__(), выводящего на экран пустое окно Создание рамки и метки Элемент управления, внутри которого могут содержаться другие элементы, называется рамкой (аналог: магнитная доска, на которую с помощью магнитов можно прикрепить картинки и др.). Для ее создания используется класс Frame(). При этом в процессе создания элемента управления конструктору нового объекта в скобках необходимо передавать его родительский элемент, то есть, элемент, внутри которого он находится. Например, при создании рамки внутри базового окна методу-конструктору Frame() необходимо передать root. В следующей строке кода, вызван метод grid(), связанный с менеджером размещения и позволяющий управлять расположением элементов в окне. Для вывода в окне надписи (неизменяемой одной строки текста) используется элемент интерфейса Label(). При этом в качестве родительского элемента указан аргумент app, что обеспечит размещение метки внутри рамки. Параметр text определяет содержание надписи, которая появится при отображении метки на экране. Метод grid() будет управлять расположением элементов в окне. В качестве параметров метода указывают row и column (например, app.grid(row=0, column=2). Их значения определяют положение объектов и позволяют передвигать виджет относительно родительского элемента управления. Если рамку базового окна представить в виде сетки, левый верхний угол которой соответствует началу координат (0,0), то можно визуально представить расположение виджета. from tkinter import* root=Tk() root.title("создание метки") root.geometry("200x300") app = Frame(root) # создание рамки, внутри которой будут виджеты app.grid() # менеджер размещения lbl = Label(app, text="Это метка") # создание метки lbl.grid() root.mainloop() При этом для изменения шрифта, стиля и размера текста необходимо передать параметр font: from tkinter import* root=Tk() root.title("создание метки") root.geometry("200x300") app = Frame(root) # создание рамки, внутри которой будут виджеты app.grid() # менеджер размещения lbl = Label(app, text="Это метка",font=("Arial Bold", 25)) # создание метки lbl.grid() root.mainloop() Следует отметить, что параметр font применяется не только к Label, он может быть передан любому виджету, чтобы поменять его шрифт. Объектно-ориентированная версия программы создания рамки и метки: from tkinter import* class MyGUI: def __init__(self): self.main_root = Tk() self.label = Label(self.main_root, text="Это метка") self.label.pack() mainloop() my_gui = MyGUI() Инструкция self.label = Label(self.main_root, text="Это метка") создает элемент интерфейса Label и присваивает его self.label. Первым аргументом в скобках является self.main_root – ссылка на корневой элемент интерфейса, указывающая, что элемент Label должен принадлежать корневому элементу. Второй аргумент text определяет текст, который будет выведен в надписи на экране. Инструкция self.label.pack() вызывает метод pack(), определяющий где должен быть расположен элемент интерфейса и делающий этот элемент видимым при выводе на экран главного окна. Если необходимо вывести несколько надписей, то по умолчанию они располагаются друг под другом. from tkinter import* class MyGUI: def __init__(self): self.main_root = Tk() self.label1 = Label(self.main_root, text="Это метка") self.label2 = Label(self.main_root, text="Это моя первая GUI-программа") self.label1.pack() self.label2.pack() mainloop() my_gui = MyGUI() Порядок размещения можно изменить, указав аргумент для метода pack(). В качестве допустимых аргументов side в метод pack() можно передавать side="left", side="top", side="bottom", side="right". Например, если для созданных элементов интерфейса label1 и label2 в качестве аргументов метода pack() указать side="left", то надписи появятся рядом друг с другом (так как сначала будет добавлен элемент label1, который появится в крайней левой области окна, а затем label2, который расположится рядом с ним. from tkinter import* class MyGUI: def __init__(self): self.main_root = Tk() self.label1 = Label(self.main_root, text="Это метка") self.label2 = Label(self.main_root, text="Это моя первая GUI-программа") self.label1.pack(side="left") self.label2.pack(side="left") mainloop() my_gui = MyGUI() Для упорядочения и группировки элементов интерфейса в окне можно использовать рамки Frame() from tkinter import* class MyGUI: def __init__(self): self.main_root = Tk() # создание рамки для верхней части окна self.top_frame = Frame(self.main_root) # создание рамки для нижней части окна self.bottom_frame = Frame(self.main_root) # создание элементов интерфейса для верхней рамки self.label1 = Label(self.top_frame, text="Мама") self.label2 = Label(self.top_frame, text="мыла") self.label3 = Label(self.top_frame, text="раму") # группировка (упаковка) элементов интерфейса в верхней рамке и расположение их друг под другом self.label1.pack(side="top") self.label2.pack(side="top") self.label3.pack(side="top") # создание элементов интерфейса для нижней рамки self.label4 = Label(self.bottom_frame, text="Моя ") self.label5 = Label(self.bottom_frame, text="первая ") self.label6 = Label(self.bottom_frame, text="GUI-программа") # группировка (упаковка) элементов интерфейса в нижней рамке и расположение горизонтально слева self.label4.pack(side="left") self.label5.pack(side="left") self.label6.pack(side="left") # группировка (упаковка) рамок self.top_frame.pack() self.bottom_frame.pack() mainloop() my_gui = MyGUI() Создание кнопок Для создания в окне стандартной кнопки используется элемент интерфейса Button, который пользователь может нажать. Чтобы вызвать выполнение определенного действия. При создании кнопки необходимо определить текст, который появится на поверхности кнопки и имя функции обратного вызова. Функция обратного вызова – это функция или метод, которая выполняется, когда пользователь нажимает кнопку. Ее называют также обработчиком события, так как она обрабатывает событие, которое происходит при нажатии пользователем кнопки. При нажатии кнопки может выводиться на экран отдельное информационное диалоговое окно. Для этого используется функция showinfo модуля tkinter.messagebox. Функция имеет формат: tkinter.messagebox.showinfo(Заголовок, Сообщение) Заголовок выводится на экран в области заголовка диалогового окна, сообщение выводится на экран в основной части диалогового окна Еще одним вариантом использования кнопки может быть завершение работы программы. Для этого в качестве функции обратного вызова необходимо использовать метод destroy() корневого элемента интерфейса. Пример. Написать программу, демонстрирующую два варианта использования элемента интерфейса Button: 1. Создать виджет с текстом «Нажми меня!», при нажатии на который появляется диалоговое окно с заголовком «Ответ» и сообщением «Спасибо!» 2. Создать виджет с текстом «Выйти», при нажатии на который программа завершает работу import tkinter import tkinter.messagebox class MyGUI: def __init__(self): self.main_root = tkinter.Tk() # создание кнопки с текстом "Нажми меня!" При нажатии кнопки исполняется метод do_something() self.my_button = tkinter.Button(self.main_root, text="Нажми меня!",width=50, height = 5, command=self.do_something) # создание кнопки с текстом "выйти!" При нажатии кнопки программа завершает работу self.quit_button = tkinter.Button(self.main_root, text="выйти!", width=10, height = 2, command=self.main_root.destroy) # упаковать элемент Button self.my_button.pack() self.quit_button.pack() # вход в главный цикл tkinter tkinter.mainloop() # метод do_something() - функция обратного вызова для Button def do_something(self): # показать информационное окно tkinter.messagebox.showinfo('Ответ', 'Спасибо!') # создание экземпляра класса my_gui = MyGUI() Пояснение: Инструкция self.my_button = tkinter.Button(self.main_root, text=”Нажми меня!”,width=50, height = 5, command=self.do_something) создает элемент интерфейса Button. Первым аргументом в скобках является родительский элемент интерфейса (self.main_root), второй аргумент определяет текст на поверхности кнопки (text=”Нажми меня!”), аргументы width=50 и height = 5 задают размеры, аргумент command=self.do_something задает метод do_something в качестве функции обратного вызова (метод исполняется, когда пользователь нажимает кнопку). Получение входных данных с помощью элемента Entry Элемент интерфейса Entry – это прямоугольная область, предназначенная для введения пользователем входных данных. Для извлечения данных, введённых пользователем в элемент интерфейса Entry, используется его метод get(). Метод возвращает строковое (!!!) значение, поэтому значение необходимо приводить к надлежащему типу данных (если, к примеру, элемент интерфейса Entry используется для ввода чисел). Пример. Написать программу с элементами GUI, которая переводит километры (км) в метры (м). При этом для ввода пользователем расстояния в километрах используется элемент интерфейса Entry. Создать кнопку с текстом «Преобразовать», при нажатии на которую расстояние преобразуется в метры и преобразованное значение выводится в информационном диалоговом окне. Расположить в нижней части окна кнопку с текстом «Выйти», при нажатии на которую программа завершает работу. Для расположения элементов интерфейса целесообразно использовать две рамки. В верхней рамке top_frame будут расположены элементы: Label – надпись, выводящая подсказку для пользователя "Введите расстояние в километрах:" и Entry – область для входных данных. В нижней рамке – две кнопки: «Преобразовать», при нажатии на которую введенное значение преобразуется в метры и результат выводится в информационном диалоговом окне; «Выйти», при нажатии на которую программа завершает работу import tkinter import tkinter.messagebox class ConverterGUI: def __init__(self): self.main_root = tkinter.Tk() # создание рамок для группировки элементов self.top_frame = tkinter.Frame(self.main_root) self.botton_frame = tkinter.Frame(self.main_root) # создание элементов интерфейса для верхней рамки self.prompt_label = tkinter.Label (self.top_frame, text = "Введите расстояние в километрах:") self.kilo_entry = tkinter.Entry(self.top_frame, width=10) # упаковать элементы верхней рамки self.prompt_label.pack(side="left") self.kilo_entry.pack(side="left") # создание кнопок с текстом "Преобразовать" и "выйти!" для нижней рамки self.calc_button = tkinter.Button(self.botton_frame, text="Преобразовать", command=self.convert) self.quit_button = tkinter.Button(self.botton_frame, text="выйти!", command=self.main_root.destroy) # упаковать элементы Button self.calc_button.pack(side='left') self.quit_button.pack(side='left') # упаковать рамки self.top_frame.pack() self.botton_frame.pack() # войти в главный цикл tkinter tkinter.mainloop() # метод convert() - функция обратного вызова для Button "Преобразовать" def convert(self): # получить введенное пользователем значение в элемент интерфейса kilo_entry kilo = float(self.kilo_entry.get()) # конвертировать километры в метры metr = kilo*1000 # показать результаты в диалоговом окне tkinter.messagebox.showinfo('Результат', str(kilo)+" км равно " + str(metr) + " м") # создание экземпляра класса kilo_konv = ConverterGUI() Пояснение: Функцией обратного вывода кнопки «Преобразовать» является метод convert(). Для извлечения введенных пользователем данных в элемент интерфейса Entry используется метод get() (строка kilo = float(self.kilo_entry.get()). При этом полученное значение преобразуется к вещественному типу float и присваивается переменной kilo. Результат преобразований, проведенных в строке metr = kilo*1000, присваивается переменной metr и при помощи функции showinfo модуля messagebox выводится в информационном диалоговом окне. Создание переключателей (радиокнопок) Radiobutton Переключатели Radiobutton реализуют выбор только одного из нескольких возможных вариантов, обеспечивая выбор в формате да/нет или включено/выключено. Каждая радиокнопка имеет кружок и два возможных состояния: если она выбрана – кружок заполнен, если нет – кружок пустой. Для создания переключателей используется класс Radiobutton модуля tkinter. Одновременно можно выбрать только один элемент Radiobutton в контейнере (например, в рамке Frame. Выбор одного элемента автоматически снимает возможность выбора любого другого, поэтому их называют взаимоисключающими. Модуль tkinter предоставляет класс IntVar, который используется вместе с элементами Radiobutton. При создании группы элементов все они связываются с одним и тем же объектом IntVar. Кроме того, каждому элементу интерфейса Radiobutton надо присвоить уникальное целочисленное значение. Когда выбирается один из элементов Radiobutton, он сохраняет свое уникальное целочисленное значение в объекте IntVar. Пример. Написать программу с элементами GUI, которая предоставляет пользователю возможность выбора только одного из трех вариантов. При нажатии кнопки «ОК» появляется информационное диалоговое окно с пояснением, какой из элементов Radiobutton был выбран пользователем. import tkinter import tkinter.messagebox class MyGUI: def __init__(self): self.main_root = tkinter.Tk() # создание рамок для группировки элементов (1- для Radiobutton, 2-для обычных элементов Button) self.top_frame = tkinter.Frame(self.main_root) self.botton_frame = tkinter.Frame(self.main_root) # создание объекта IntVar для Radiobutton self.radio_var = tkinter.IntVar()\ # назначение объекту IntVar значения 1 self.radio_var.set(1) # создание элементов интерфейса в рамке top_frame self.rb1 = tkinter.Radiobutton (self.top_frame, text = "Вариант 1",variable=self.radio_var,value=1) self.rb2 = tkinter.Radiobutton (self.top_frame, text = "Вариант 2",variable=self.radio_var,value=2) self.rb3 = tkinter.Radiobutton (self.top_frame, text = "Вариант 3",variable=self.radio_var,value=3) # упаковать элементы Radiobutton self.rb1.pack() self.rb2.pack() self.rb3.pack() # создание кнопок с текстом "OK" и "выйти!" self.ok_button = tkinter.Button(self.botton_frame, text="OK", command=self.show_choice) self.quit_button = tkinter.Button(self.botton_frame, text="выйти!", command=self.main_root.destroy) # упаковать элементы Button self.ok_button.pack(side='left') self.quit_button.pack(side='left') # упаковать рамки self.top_frame.pack() self.botton_frame.pack() # войти в главный цикл tkinter tkinter.mainloop() # метод show_choice - функция обратного вызова для Button "OK" def show_choice(self): tkinter.messagebox.showinfo('Ваш выбор', 'Выбран вариант ' + str(self.radio_var.get())) # создание экземпляра класса my_gui = MyGUI() Создание флаговых кнопок (флажков) Checkbutton Подобно переключателям, флаговые кнопки могут иметь два состояния: быть выбранными или невыбранными. При нажатии флаговой кнопки в соответствующем поле появляется «галочка». Но в отличие от переключателей, пользователю разрешено выбирать любое количество указанных в группе флаговых кнопок, поэтому флажки не используются для создания взаимоисключающих вариантов выбора. Для создания флажков используется класс Checkbutton модуля tkinter. Вместе с элементом Checkbutton используется объект IntVar. Однако, в отличие от элементов Radiobutton, отдельный объект IntVar связывается с каждым (!!!) элементом Checkbutton. При выборе элемента Checkbutton связанный с ним объект IntVar будет содержать значение 1, при снятии «галочки» в поле объекта Checkbutton связанный с ним объект IntVar содержит значение 0. Пример. Написать программу с элементами GUI, которая предоставляет пользователю возможность выбора нескольких из трех возможный вариантов. При нажатии кнопки «ОК» появляется информационное диалоговое окно с пояснением, какие из элементов Checkbutton были выбраны пользователем. import tkinter import tkinter.messagebox class MyGUI: def __init__(self): self.main_root = tkinter.Tk() # создание рамок для группировки элементов (1- для Checkbutton, 2-для обычных элементов Button) self.top_frame = tkinter.Frame(self.main_root) self.botton_frame = tkinter.Frame(self.main_root) # создание объектов IntVar для Checkbutton self.cb_var1 = tkinter.IntVar() self.cb_var2 = tkinter.IntVar() self.cb_var3 = tkinter.IntVar() # назначение объектам IntVar значения 0 self.cb_var1.set(0) self.cb_var2.set(0) self.cb_var3.set(0) # создание объектов элементов интерфейса Checkbutton в рамке top_frame self.cb1 = tkinter.Checkbutton (self.top_frame, text = "Вариант 1",variable=self.cb_var1) self.cb2 = tkinter.Checkbutton (self.top_frame, text = "Вариант 2",variable=self.cb_var2) self.cb3 = tkinter.Checkbutton (self.top_frame, text = "Вариант 3",variable=self.cb_var3) # упаковать элементы Radiobutton self.cb1.pack() self.cb2.pack() self.cb3.pack() # создание кнопок с текстом "OK" и "выйти!" self.ok_button = tkinter.Button(self.botton_frame, text="OK", command=self.show_choice) self.quit_button = tkinter.Button(self.botton_frame, text="выйти!", command=self.main_root.destroy) # упаковать элементы Button self.ok_button.pack(side='left') self.quit_button.pack(side='left') # упаковать рамки self.top_frame.pack() self.botton_frame.pack() # войти в главный цикл tkinter tkinter.mainloop() # метод show_choice - функция обратного вызова для Button "OK" def show_choice(self): # создание строкового значения с сообщением self.message = 'Вы выбрали:\n' # Определить, какие элементы Checkbutton выбраны и составить соответствующее сообщение if self.cb_var1.get() == 1: self.message= self.message +'1\n' if self.cb_var2.get() == 1: self.message= self.message +'2\n' if self.cb_var3.get() == 1: self.message= self.message +'3\n' # вывод сообщениея в информационном диалоговом окне tkinter.messagebox.showinfo('Ваш выбор', self.message) # создание экземпляра класса my_gui = MyGUI()
«Событийно-ориентированное программирование» 👇
Готовые курсовые работы и рефераты
Купить от 250 ₽
Решение задач от ИИ за 2 минуты
Решить задачу
Найди решение своей задачи среди 1 000 000 ответов
Найти
Найди решение своей задачи среди 1 000 000 ответов
Крупнейшая русскоязычная библиотека студенческих решенных задач

Тебе могут подойти лекции

Смотреть все 588 лекций
Все самое важное и интересное в Telegram

Все сервисы Справочника в твоем телефоне! Просто напиши Боту, что ты ищешь и он быстро найдет нужную статью, лекцию или пособие для тебя!

Перейти в Telegram Bot