практические работы по питону. МУ_ИНФОРМАТИКА_ПРОГРАММИРОВАНИЕ_ПИТОН Коренюгина_2021. Методические указания по подготовке к практическим занятиям, в том числе в интерактивной форме, и самостоятельному изучению дисциплины для школьников 911 классов общеобразовательных средних учебных заведений
Скачать 2.38 Mb.
|
from tkinter import * class CheckButton: def __init__ ( self , master , title): self .var = BooleanVar() self .var. set ( 0 ) self .title = title self .cb = Checkbutton( master , text = title , variable = self .var , onvalue = 1 , offvalue = 0 ) self .cb.pack(side = LEFT) 96 def ch_on(): for ch in checks: ch.cb. select () def ch_off(): for ch in checks: ch.cb.deselect() root = Tk() f1 = Frame() f1.pack(padx = 10 , pady = 10 ) checks = [] for i in range ( 10 ): checks.append(CheckButton(f1 , i)) f2 = Frame() f2.pack() button_on = Button(f2 , text = "Все ВКЛ" , command = ch_on) button_on.pack(side = LEFT) button_off = Button(f2 , text = "Все ВЫКЛ" , command = ch_off) button_off.pack(side = LEFT) root.mainloop() Практическая работа Виджеты Radiobatton и Checkbutton поддерживают большинство свойств оформления внешнего вида, которые есть у других элементов графического интерфейса. При этом у Radiobutton есть особое свойство indicatoron. По-умолчанию он равен единице, в этом случае радиокнопка выглядит как нормальная радиокнопка. Однако если присвоить этой опции ноль, то виджет Radiobutton становится похожим на обычную кнопку по внешнему виду. Но не по смыслу. Напишите программу, в которой имеется несколько объединенных в группу радиокнопок, индикатор которых выключен (indicatoron=0). Если какая-нибудь кнопка включается, то в метке должна отображаться соответствующая ей информация. Обычных кнопок в окне быть не должно. 97 Помните, что свойство command есть не только у виджетов класса Button. практическая работа 1. Напишите следующую программу. На главном окне находится несколько флажков и текстовое поле. При щелчке левой кнопкой мыши в пределах текстового поля в нем должны отображаться значения включенных флажки (появляться сообщение о том, какие флажки включены), при щелчке правой кнопкой мыши — значения выключенных флажков. 2. Напишите скрипт, генерирующий в окне два текстовых поля и рамку. Размер рамки можно менять с помощью вводимых значений в текстовые поля (определяют длину и ширину) и нажатии клавиши пробел на клавиатуре. Библиотека Tkinter содержит специальные классы, объекты которых выполняют роль переменных для хранения значений о состоянии различных виджет. Изменение значения такой переменной ведет к изменению и свойства виджета, и наоборот: изменение свойства виджета изменяет значение ассоциированной переменной. Существует несколько таких классов Tkinter, предназначенных для обработки данных разных типов. 1. StringVar() - для строк; 2. IntVar() - целых чисел; 3. DoubleVar() - дробных чисел; 4. BooleanVar() - для обработки булевых значений (true и false). Пример 1. Во втором уроке мы уже использовали переменную-объект типа IntVar() при создании группы радиокнопок: 1. var=IntVar() 2. var. set ( 1 ) 3. rad0 = Radiobutton(root,text= "Первая" ,variable=var,value= 0 ) 4. rad1 = Radiobutton(root,text= "Вторая" ,variable=var,value= 1 ) 5. rad2 = Radiobutton(root,text= "Третья" ,variable=var,value= 2 ) Здесь создается объект класса IntVar и связывается с переменной var. С помощью метода set устанавливается начальное значение, равное 1. Три радиокнопки относятся к одной группе: об этом свидетельствует одинаковое значение опции (свойства) variable. Variable предназначена для связывания переменной Tkinter с радиокнопкой. Опция value определяет значение, которое будет передано переменной, если данная кнопка будет в состоянии "включено". Если в процессе выполнения скрипта значение переменной var будет изменено, то это отразится на группе кнопок. Например, это делается во второй строчке кода: включена кнопка rad1.__ 98 Если метод set позволяет устанавливать значения переменных, то метод get, наоборот, позволяет получать (узнавать) значения для последующего их использования. 1. def display(event): 2. v = var.get() 3. if v == 0: 4. ( "Включена первая кнопка" ) 5. elif v == 1: 6. ( "Включена вторая кнопка" ) 7. elif v == 2: 8. ( "Включена третья кнопка" ) 9. 10. but = Button(root,text= "Получить значение" ) 11. but.bind( ' ,display) При вызове функции display в переменную v ―записывается― значение, связанное в текущий момент с переменной var. Чтобы получить значение переменной var, используется метод get (вторая строчка кода). Пример 2. Несколько сложнее обстоит дело с флажками. Поскольку состояния флажков независимы друг друга, то для каждого должна быть введена собственная ассоциированная переменная-объект. 1. from tkinter import * 2. 3. root = Tk() 4. 5. var0=StringVar() # значение каждого флажка ... 6. var1=StringVar() # ... хранится в собственной переменной 7. var2=StringVar() 8. # если флажок установлен, то в ассоциированную переменную ... 9. # ...(var0,var1 или var2) заносится значение onvalue, ... 10. # ...если флажок снят, то - offvalue. 11. ch0 = Checkbutton(root,text= "Окружность" ,variable=var0, 12. onvalue= "circle" ,offvalue= "-" ) 13. ch1 = Checkbutton(root,text= "Квадрат" ,variable=var1, 14. onvalue= "square" ,offvalue= "-" ) 15. ch2 = Checkbutton(root,text= "Треугольник" ,variable=var2, 16. onvalue= "triangle" ,offvalue= "-" ) 17. 18. lis = Listbox(root,height=3) 19. def result(event): 20. v0 = var0.get() 21. v1 = var1.get() 22. v2 = var2.get() Если метод set позволяет устанавливать значения переменных, то метод get, наоборот, позволяет получать (узнавать) значения для последующего их использования. 1. def display(event): 2. v = var.get() 3. if v == 0: 4. ( "Включена первая кнопка" ) 5. elif v == 1: 99 6. ( "Включена вторая кнопка" ) 7. elif v == 2: 8. ( "Включена третья кнопка" ) 9. 10. but = Button(root,text= "Получить значение" ) 11. but.bind( ' ,display) При вызове функции display в переменную v ―записывается― значение, связанное в текущий момент с переменной var. Чтобы получить значение переменной var, используется метод get (вторая строчка кода). Пример 2. Несколько сложнее обстоит дело с флажками. Поскольку состояния флажков независимы друг друга, то для каждого должна быть введена собственная ассоциированная переменная-объект. 1. from tkinter import * 2. 3. root = Tk() 4. 5. var0=StringVar() # значение каждого флажка ... 6. var1=StringVar() # ... хранится в собственной переменной 7. var2=StringVar() 8. # если флажок установлен, то в ассоциированную переменную ... 9. # ...(var0,var1 или var2) заносится значение onvalue, ... 10. # ...если флажок снят, то - offvalue. 11. ch0 = Checkbutton(root,text= "Окружность" ,variable=var0, 12. onvalue= "circle" ,offvalue= "-" ) 13. ch1 = Checkbutton(root,text= "Квадрат" ,variable=var1, 14. onvalue= "square" ,offvalue= "-" ) 15. ch2 = Checkbutton(root,text= "Треугольник" ,variable=var2, 16. onvalue= "triangle" ,offvalue= "-" ) 17. 18. lis = Listbox(root,height=3) 19. def result(event): 20. v0 = var0.get() 21. v1 = var1.get() 22. v2 = var2.get() 23. l = [v0,v1,v2] # значения переменных заносятся в список 24. lis.delete( 0 , 2 ) # предыдущее содержимое удаляется из Listbox 25. for v in l: # содержимое списка l последовательно ... 26. lis.insert(END,v) # ...вставляется в Listbox 27. 28. but = Button(root,text= "Получить значения" ) 29. but.bind( ' ,result) 30. 31. ch0.deselect() # "по умолчанию" флажки сняты 32. ch1.deselect() 33. ch2.deselect() 34. 35. ch0.pack() 36. ch1.pack() 37. ch2.pack() 38. but.pack() 39. lis.pack() 100 40. 41. root.mainloop() Пример 3. Помимо свойства (опции) variable, связывающей виджет с переменной-объектом Tkinter (IntVar, StringVar и др.), у многих виджет существует опция textvariable, которая определяет текст-содержимое или текст-надпись виджета. Несмотря на то, что «текстовое свойство» может быть установлено для виджета и изменено в процессе выполнения кода без использования ассоциированных переменных, иногда такой способ изменения оказывается более удобным. 1. from tkinter import * 2. root = Tk() 3. v = StringVar() 4. ent1 = Entry (root, textvariable = v,bg= "black" ,fg= "white" ) 5. ent2 = Entry(root, textvariable = v) 6. ent1.pack() 7. ent2.pack() 8. root.mainloop() Здесь содержимое одного текстового поля немедленно, отображается в другом, т.к. оба поля привязаны к одной и той же переменной v. Практическая работа 1. Напишите скрипт, как в примере с флажками; в отличии от примера значения ассоциированных переменных должны отображаться в метке (Label) через запятую. Для реализации графического интерфейса воспользуемся стандартным пакетом Tkinter. Он входит в состав Python 3. Соответственно, если у вас установлен Python, то дополнительно не надо ничего устанавливать. Создание простого GUI приложения на Tkinter Главным элементом GUI Tkinter является окно . Окнами называют контейнеры, в которых находятся все GUI элементы. Данные GUI элементы, к числу которых относятся текстовые боксы, ярлыки и кнопки, называются виджетами. Виджеты помещаются внутри окон. Сперва создадим окно с одним виджетом. Запустим новую сессию оболочки Python, следуя инструкции. В первых строках файла calculator.py подключаем библиотечные функции: Tkinter для графического интерфейса; Decimal для вычислений с большей точность, так как точности float не достаточно. Импорт библиотек и исходные данные 1) КНОПКИ ООП def button_press(): print("ryjgrf yf;fnf") from tkinter import* tk=Tk() b1 = Button (tk,text="yf;vb vtyf",command=button_press) b1.pack() 101 from tkinter import * root = Tk() root.title("GUI на Python") root.geometry("300x250") btn = Button(text="Hello") btn.pack() root.mainloop() from tkinter import * root = Tk() root.title("кнопка на Python") root.geometry("300x250") btn = Button(text="Hello", # текст кнопки background="#555", # фоновый цвет кнопки foreground="#ccc", # цвет текста padx="20", # отступ от границ до содержимого по горизонтали pady="8", # отступ от границ до содержимого по вертикали font="16" # высота шрифта ) btn.pack() root.mainloop() РАДИОБАТТОНЫ ЦВЕТНЫЕ from tkinter import * def red_label(): label['bg'] = 'red' def yellow_label(): label['bg'] = 'yellow' def green_label(): label['bg'] = 'green' def blue_label(): label['bg'] = 'blue' def purple_label(): 102 label['bg'] = 'purple' root = Tk() var = IntVar() var.set(0) Radiobutton(text="Red", command=red_label, variable=var, value=0).pack() Radiobutton(text="Yellow", command=yellow_label, variable=var, value=3).pack() Radiobutton(text="Green", command=green_label, variable=var, value=1).pack() Radiobutton(text="Blue", command=blue_label, variable=var, value=2).pack() Radiobutton(text="Purple", command=purple_label, variable=var, value=4).pack() label = Label(width=20, height=10, bg='red') label.pack() root.mainloop() Всего же конструктор Button может принимать следующие параметры: 1 Button (master, options) Параметр master представляет ссылку на родительский контейнер. В случае выше это могло бы быть само графическое окно, и мы могли написать: 1 2 3 4 5 6 root = Tk() root.title("GUI на Python") root.geometry("300x250") btn = Button(root, text="Hello") btn.pack() Однако если в коде создается одно окно, то кнопка и любой другой элемент уже по умолчанию размещаются в этом окне. Поэтому первый параметр мы можем опустить, как в примерах выше. Если бы у нас в коде создавалось бы несколько окон, тогда мы могли бы передать в конструктор Button ссылку на нужное окно. Второй параметр options представляет набор на самом деле набор параметров, которые мы можем установить по их имени: activebackground: цвет кнопки, когда она находится в нажатом состоянии activeforeground: цвет текста кнопки, когда она в нажатом состоянии bd: толщина границы (по умолчанию 2) bg/background: фоновый цвет кнопки 103 fg/foreground: цвет текста кнопки font: шрифт текста, например, font="Arial 14" - шрифт Arial высотой 14px, или font=("Verdana", 13, "bold") - шрифт Verdana высотой 13px с выделением жирным height: высота кнопки highlightcolor: цвет кнопки, когда она в фокусе image: изображение на кнопке justify: устанавливает выравнивание текста. Значение LEFT выравнивает текст по левому краю, CENTER - по центру, RIGHT - по правому краю padx: отступ от границ кнопки до ее текста справа и слева pady: отступ от границ кнопки до ее текста сверху и снизу relief: определяет тип границы, может принимать значения SUNKEN, RAISED, GROOVE, RIDGE state: устанавливает состояние кнопки, может принимать значения DISABLED, ACTIVE, NORMAL (по умолчанию) text: устанавливает текст кнопки textvariable: устанавливает привязку к элементу StringVar underline: указывает на номер символа в тексте кнопки, который подчеркивается. По умолчанию значение -1, то есть никакой символ не подчеркивается width: ширина кнопки wraplength: при положительном значении строки текста будут переносится для вмещения в пространство кнопки Обработка нажатия на кнопку Для обработки нажатия на кнопку необходимо установить в конструкторе параметр command, присвоив ему ссылку на функцию, которая будет срабатывать при нажатии: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from tkinter import * clicks = 0 def click_button(): global clicks clicks += 1 root.title("Clicks {}".format(clicks)) root = Tk() root.title("GUI на Python") root.geometry("300x250") btn = Button(text="Click Me", background="#555", foreground="#ccc", padx="20", pady="8", font="16", command=click_button) btn.pack() root.mainloop() Здесь в качестве обработчика нажатия устанавливается функция click_button. В этой функции изменяется глобальная переменная clicks, которая хранит число кликов, и ее значение выводится в заголовок окна. Таким образом, при каждом нажатии кнопки будет срабатывать функция click_button, и количество кликов будет увеличиваться: Создаем окно приложения – объект Tk с заголовком Calculator. Во вложенном кортеже buttons будут храниться обозначения для кнопок. В список stack будем добавлять введенные числа и операции, которые надо совершить. activeStr предназначен для хранения набираемого числа. 104 from tkinter import * from decimal import * root = Tk() root.title('Calculator') buttons = (('7', '8', '9', '/', '4'), ('4', '5', '6', '*', '4'), ('1', '2', '3', '-', '4'), ('0', '.', '=', '+', '4') ) activeStr = '' stack = [] Вычисление результата Функция calculate получает из списка stack операнды и операцию которую над ними надо произвести. Результат отображается в надписи label. Получать из списка строки будем с помощью метода pop. def calculate(): global stack global label result = 0 operand2 = Decimal(stack.pop()) operation = stack.pop() operand1 = Decimal(stack.pop()) if operation == '+': result = operand1 + operand2 if operation == '-': result = operand1 - operand2 if operation == '/': result = operand1 / operand2 if operation == '*': result = operand1 * operand2 label.configure(text=str(result)) Обработка нажатия В функции click выполняется обработка нажатой клавиши. В качестве ее аргумента передается текст, отображаемый на кнопке, которую нажали. Хотелось бы хранить вводимое значение прямо в надписи, а не создавать для этого отдельную переменную. Но так не получается из-за алгоритма работы. После того как посчитан результат, он записывается в надписи. При попытке после этого начать вводить новое число, оно бы дописывало прежний результат. В списке с операторами и командами для калькулятора не обязательно их будет 3. Но при обработке с помощью метода pop, будут рассматриваться 3 последних введенных значения. А после проведения расчета список очистится. Далее в него добавляется полученный результат, на случай если пользователь нажмет на калькуляторе клавишу операции сразу, а не будет вводить новое число. def click(text): global activeStr global stack if text == 'CE': stack.clear() 105 activeStr = '' label.configure(text='0') elif '0' <= text <= '9': activeStr += text label.configure(text=activeStr) elif text == '.': if activeStr.find('.') == -1: activeStr += text label.configure(text=activeStr) else: if len(stack) >= 2: stack.append(label['text']) calculate() stack.clear() stack.append(label['text']) activeStr = '' if text != '=': stack.append(text) else: if text != '=': stack.append(label['text']) stack.append(text) activeStr = '' label.configure(text='0') Внешний вид |