Введение
В ходе статьи напишем GUI калькулятор на языке программирования Python с использованием модуля tkinter.
Написание GUI калькулятора
Для начала импортируем библиотеку tkinter:
from tkinter import *
Создадим объект класса Tk(), укажем разрешение окна 268×288, заголовок «Калькулятор» и запретим возможность изменять разрешение окна:
from tkinter import *
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
root.mainloop()
Создадим виджет Frame() и отобразим его методом grid():
from tkinter import *
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
root.mainloop()
Добавим текстовое поле (виджет Entry()) на фрейм, укажем шрифт Arial 15 размера жирного начертания, толщину 24 и запретим возможность писать в нём. Отобразим его методом pack():
from tkinter import *
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
root.mainloop()
Далее создадим кортеж, в котором будут храниться кнопки будущего калькулятора:
from tkinter import *
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
buttons = (('7', '8', '9', '/', '4'),
('4', '5', '6', '*', '4'),
('1', '2', '3', '-', '4'),
('0', '.', '=', '+', '4')
)
root.mainloop()
Создадим пустую переменную expression строкового типа данных. Она нам пригодится для избежания ошибок в будущем. Также добавим кнопку, которая в последующем
будет служить для очищения текстового поля:
from tkinter import *
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
buttons = (('7', '8', '9', '/', '4'),
('4', '5', '6', '*', '4'),
('1', '2', '3', '-', '4'),
('0', '.', '=', '+', '4')
)
expression = ""
button = Button(root, text='C', command=lambda: bt_clear())
button.grid(row=1, column=3, sticky="nsew")
root.mainloop()
Теперь добавим основные кнопки калькулятора с помощью цикла. И в основном, и во вложенном циклах будет по 4 итерации. Во вложенном цикле создаётся кнопка, с шириной 2, и высотой 3. Текстом будет являться поиндексное значение из кортежа buttons. Команда будет задаваться с помощью анонимной функции lambda, позиционироваться кнопки будут с помощью метода grid():
from tkinter import *
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
buttons = (('7', '8', '9', '/', '4'),
('4', '5', '6', '*', '4'),
('1', '2', '3', '-', '4'),
('0', '.', '=', '+', '4')
)
expression = ""
button = Button(root, text='C', command=lambda: bt_clear())
button.grid(row=1, column=3, sticky="nsew")
for row in range(4):
for col in range(4):
Button(root, width=2, height=3, text=buttons[row][col],
command=lambda row=row, col=col: btn_click(buttons[row][col])).grid(row=row + 2, column=col, sticky="nsew", padx=1, pady=1)
root.mainloop()
Создадим функцию btn_click(), и в качестве аргумента укажем item. Сделаем переменную expression глобальной, после чего добавим конструкцию try … except:
from tkinter import *
def btn_click(item):
global expression
try:
pass
except:
pass
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
buttons = (('7', '8', '9', '/', '4'),
('4', '5', '6', '*', '4'),
('1', '2', '3', '-', '4'),
('0', '.', '=', '+', '4')
)
expression = ""
button = Button(root, text='C', command=lambda: bt_clear())
button.grid(row=1, column=3, sticky="nsew")
for row in range(4):
for col in range(4):
Button(root, width=2, height=3, text=buttons[row][col],
command=lambda row=row, col=col: btn_click(buttons[row][col])).grid(row=row + 2, column=col, sticky="nsew", padx=1, pady=1)
root.mainloop()
В try мы даём возможность писать в текстовое поле, приведя параметр state в normal. Далее к expression прибавляем item. И вводим результат в текстовое поле:
from tkinter import *
def btn_click(item):
global expression
try:
input_field['state'] = "normal"
expression += item
input_field.insert(END, item)
except:
pass
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
buttons = (('7', '8', '9', '/', '4'),
('4', '5', '6', '*', '4'),
('1', '2', '3', '-', '4'),
('0', '.', '=', '+', '4')
)
expression = ""
button = Button(root, text='C', command=lambda: bt_clear())
button.grid(row=1, column=3, sticky="nsew")
for row in range(4):
for col in range(4):
Button(root, width=2, height=3, text=buttons[row][col],
command=lambda row=row, col=col: btn_click(buttons[row][col])).grid(row=row + 2, column=col, sticky="nsew", padx=1, pady=1)
root.mainloop()
Зададим условие, что если на;ата кнопка «равно», то будет подсчитываться результат методом eval(). После чего результат будет выведен в текстовое поле, а expression обнулится. В конце try снова замораживаем текстовое поле:
from tkinter import *
def btn_click(item):
global expression
try:
input_field['state'] = "normal"
expression += item
input_field.insert(END, item)
if item == '=':
result = str(eval(expression[:-1]))
input_field.insert(END, result)
expression = ""
input_field['state'] = "readonly"
except:
pass
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
buttons = (('7', '8', '9', '/', '4'),
('4', '5', '6', '*', '4'),
('1', '2', '3', '-', '4'),
('0', '.', '=', '+', '4')
)
expression = ""
button = Button(root, text='C', command=lambda: bt_clear())
button.grid(row=1, column=3, sticky="nsew")
for row in range(4):
for col in range(4):
Button(root, width=2, height=3, text=buttons[row][col],
command=lambda row=row, col=col: btn_click(buttons[row][col])).grid(row=row + 2, column=col, sticky="nsew", padx=1, pady=1)
root.mainloop()
В except мы будем ловить ошибку ZeroDivisionError, и говорить, что деление на 0 запрещено.
Также добавим ошибку синтаксиса, при которой будет просто выводиться слово «Ошибка»:
from tkinter import *
def btn_click(item):
global expression
try:
input_field['state'] = "normal"
expression += item
input_field.insert(END, item)
if item == '=':
result = str(eval(expression[:-1]))
input_field.insert(END, result)
expression = ""
input_field['state'] = "readonly"
except ZeroDivisionError:
input_field.delete(0, END)
input_field.insert(0, 'Ошибка (деление на 0)')
except SyntaxError:
input_field.delete(0, END)
input_field.insert(0, 'Ошибка')
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
buttons = (('7', '8', '9', '/', '4'),
('4', '5', '6', '*', '4'),
('1', '2', '3', '-', '4'),
('0', '.', '=', '+', '4')
)
expression = ""
button = Button(root, text='C', command=lambda: bt_clear())
button.grid(row=1, column=3, sticky="nsew")
for row in range(4):
for col in range(4):
Button(root, width=2, height=3, text=buttons[row][col],
command=lambda row=row, col=col: btn_click(buttons[row][col])).grid(row=row + 2, column=col, sticky="nsew", padx=1, pady=1)
root.mainloop()
Теперь добавим функцию для очищения текстового поля. Внутри неё делаем переменную expression глобальной, опять же размораживаем текстовое поле, очищаем его, и снова замораживаем:
from tkinter import *
def btn_click(item):
global expression
try:
input_field['state'] = "normal"
expression += item
input_field.insert(END, item)
if item == '=':
result = str(eval(expression[:-1]))
input_field.insert(END, result)
expression = ""
input_field['state'] = "readonly"
except ZeroDivisionError:
input_field.delete(0, END)
input_field.insert(0, 'Ошибка (деление на 0)')
except SyntaxError:
input_field.delete(0, END)
input_field.insert(0, 'Ошибка')
def bt_clear():
global expression
expression = ""
input_field['state'] = "normal"
input_field.delete(0, END)
input_field['state'] = "readonly"
root = Tk()
root.geometry("268x288")
root.title("Калькулятор")
root.resizable(0, 0)
frame_input = Frame(root)
frame_input.grid(row=0, column=0, columnspan=4, sticky="nsew")
input_field = Entry(frame_input, font='Arial 15 bold', width=24, state="readonly")
input_field.pack(fill=BOTH)
buttons = (('7', '8', '9', '/', '4'),
('4', '5', '6', '*', '4'),
('1', '2', '3', '-', '4'),
('0', '.', '=', '+', '4')
)
expression = ""
button = Button(root, text='C', command=lambda: bt_clear())
button.grid(row=1, column=3, sticky="nsew")
for row in range(4):
for col in range(4):
Button(root, width=2, height=3, text=buttons[row][col],
command=lambda row=row, col=col: btn_click(buttons[row][col])).grid(row=row + 2, column=col, sticky="nsew", padx=1, pady=1)
root.mainloop()
Итог:
Заключение
В ходе статьи мы с Вами написали код для GUI калькулятора на языке программирования Python с использованием модуля tkinter. Надеюсь Вам понравилась статья, желаю удачи и успехов! 🙂