Рассмотрим пример создания графического интерфейса (GUI) на Python. В качестве "жертвы" напишем простенькую программу - решатель квадратных уравнений. Наше задание мы разобъем на несколько частей.
Часть первая: функция решения квадратного уравнения.
Напомним, что квадратным является уравнение вида:
ax2 + bx + c = 0
Есть несколько способов решить квадратное уравнение, мы выберем решение через дискриминант.
Формула дискриминанта:
D = b2 - 4ac.
Используя эту формулу мы можем вывести решение. Если дискриминант больше или равен нулю, то корни уравнения высчитываются по формуле:
x1,2 = (-b ± √D) ÷ (2a)
Если же дискриминант меньше нуля, то уравнение не имеет решений.
Превратим данные формулы в код:
def solver(a,b,c): """ Решает квадратное уравнение и выводит отформатированный ответ """ # находим дискриминант D = b*b - 4*a*c if D >= 0: x1 = (-b + sqrt(D)) / (2*a) x2 = (-b - sqrt(D)) / (2*a) text = "The discriminant is: %s \n X1 is: %s \n X2 is: %s \n" % (D, x1, x2) else: text = "The discriminant is: %s \n This equation has no solutions" % D return text
Чтобы все работало не забудьте импортировать функцию sqrt из модуля math.
from math import sqrt
Поскольку мы будем выводить результат в специально созданном виджете - мы сразу же вставляем полученный ответ в отформатированную строку и возвращаем ее.
Теперь пора переходить к созданию графической оболочки для нашего приложения.
Часть вторая: создаем GUI для программы
Для простоты будем создавать GUI встроенными средствами Python, поэтому импортируем все из библиотеки Tkinter:
from Tkinter import *
В Python версии 3.х название модуля следует писать с маленькой буквы - tkinter.
Далее создаем само окно и размещаем на нем необходимые виджеты:
# родительский элемент root = Tk() # устанавливаем название окна root.title("Quadratic calculator") # устанавливаем минимальный размер окна root.minsize(325,230) # выключаем возможность изменять окно root.resizable(width=False, height=False) # создаем рабочую область frame = Frame(root) frame.grid() # поле для ввода первого аргумента уравнения (a) a = Entry(frame, width=3) a.grid(row=1,column=1,padx=(10,0)) # текст после первого аргумента a_lab = Label(frame, text="x**2+").grid(row=1,column=2) # поле для ввода второго аргумента уравнения (b) b = Entry(frame, width=3) b.grid(row=1,column=3) # текст после второго аргумента b_lab = Label(frame, text="x+").grid(row=1, column=4) # поле для ввода третьего аргумента уравнения (с) c = Entry(frame, width=3) c.grid(row=1, column=5) # текст после третьего аргумента c_lab = Label(frame, text="= 0").grid(row=1, column=6) # кнопка решить but = Button(frame, text="Solve").grid(row=1, column=7, padx=(10,0)) # место для вывода решения уравнения output = Text(frame, bg="lightblue", font="Arial 12", width=35, height=10) output.grid(row=2, columnspan=8) # запускаем главное окно root.mainloop()
Если вы в точности повторили указанный код, то после запуска скрипта у вас получится примерно следующее окно:
Отлично, программа работает. Осталось объяснить Python как связать эти две части.
Часть третья: объединяем все воедино
Задача перед нами стоит следующая - написать функцию, которая будет брать числа из полей для ввода, передавать их функции решения квадратного уравнения и выводить результат в поле для вывода. Конечно, все это можно реализовать в одной функции, но лучше разделить на несколько:
Функция вставки информации:
def inserter(value): """ Inserts specified value into text widget """ output.delete("0.0","end") output.insert("0.0",value)
Функция inserter предельно проста: очищает поле для ввода и вставляет туда переданный ей аргумент value.
Напишем функцию обработки введенной информации. Назовем ее handler:
def handler(): """ Get the content of entries and passes result to the output area """ try: # make sure that we entered correct values a_val = float(a.get()) b_val = float(b.get()) c_val = float(c.get()) inserter(solver(a_val, b_val, c_val)) except ValueError: inserter("Make sure you entered 3 numbers")
В зависимости от данных введенных в поля для ввода передает функции inserter либо результат решения уравнения, либо сообщение о неверно введенных данных.
Чтобы все работало, следует изменить строку создания виджета Button следующим образом:
but = Button(frame, text="Solve", command=handler).grid(row=1, column=7, padx=(10,0))
Теперь можно спокойно пользоваться нашей программой:
![]() |
![]() |
Дискриминант больше нуля | Дискриминант равен нулю |
![]() |
![]() |
Дискриминант меньше нуля. Решений нет | Введены не все аргументы |
Часть четвертая: необязательная
Можно добавить немного удобства для нашей программы. Проблема в том, что каждый раз вводя новые значения нам приходится удалять старые, что не очень комфортно. Напишем функцию, которая будет очищать поле для ввода после клика по нему.
def clear(event): """ Clears entry form """ caller = event.widget caller.delete("0", "end")
Таким образом мы очищаем виджет, вызвавший данную функцию. Чтобы все работало, добавьте следующие строки после создания виджетов, но до размещения. Например, после строки a = Entry(... , но до строки a.grid(...
a.bind("<FocusIn>", clear) b.bind("<FocusIn>", clear) c.bind("<FocusIn>", clear)
Готово. Программа работает, Вы великолепны!
Исходный код калькулятора квадратных уравнений с GUI на GitHub