Simple_calculator
/
Simple_calculator.py
277 строк · 11.5 Кб
1"""
2Примитивный калькулятор с применением встроенного фреймворка для построения
3пользовательского интерфейса Tkinter
4"""
5
6import tkinter as tk
7import tkinter.ttk as ttk
8
9
10class Example(ttk.Frame):
11def __init__(self, parent):
12"""
13Конструктов приложения с инициализацией метода построения интерфейса.
14:param parent: ссылка на родительское окно приложения
15"""
16ttk.Frame.__init__(self) # вызов конструктора родительского класса
17self.parent = parent # сохранение ссылки на основное окно
18self.entry = ttk.Entry(self, font=('serif', 12), justify=tk.RIGHT) # создание текстового однострочного поля
19self.entry.insert(tk.END, '0') # базовый ноль на экране
20self.memory = 0 # создание ячейки памяти, в качестве 2-ой ячейки будет entry
21self.clear_screen = True
22self.action = '' # создание указателя на действие
23self.action_case = {'/': lambda x, y: x / y, # набор действий
24'*': lambda x, y: x * y,
25'+': lambda x, y: x + y,
26'-': lambda x, y: x - y}
27self.init_ui() # инициализация метода построения интерфейса
28
29def init_ui(self):
30"""
31Метод построения интерфейса калькулятора.
32"""
33self.parent.title('Калькулятор на Tkinter') # установка имени окна
34ttk.Style().configure('TButton', padding=(0, 5, 0, 5), font=('serif', 12))
35ttk.Style().configure('TEntry', padding=(0, 5, 0, 5))
36# устанавливаем стиль для кнопок включая отступы и шрифт
37self.columnconfigure(0, pad=3) # конфигурирование столбцов сетки
38self.columnconfigure(1, pad=3)
39self.columnconfigure(2, pad=3)
40self.columnconfigure(3, pad=3)
41self.rowconfigure(0, pad=3) # конфигурирование строк сетки
42self.rowconfigure(1, pad=3)
43self.rowconfigure(2, pad=3)
44self.rowconfigure(3, pad=3)
45self.rowconfigure(4, pad=3)
46self.rowconfigure(5, pad=3)
47self.entry.grid(row=0, columnspan=4, sticky=tk.W + tk.E) # размещение текстового поля в нулевой строке
48# с заполнением на 4 клетки сетки и закреплением к левому и правому краю рамки
49cls = ttk.Button(self, text='Очистить', command=self.clear) # создание и размещение кнопок калькулятор
50cls.grid(row=1, column=0)
51bck = ttk.Button(self, text='Удалить', command=self.delete)
52bck.grid(row=1, column=1)
53rev = ttk.Button(self, text='+/-', command=self.neg_pos) # пустая кнопка
54rev.grid(row=1, column=2)
55clo = ttk.Button(self, text='Закрыть', command=quit)
56clo.grid(row=1, column=3)
57sev = ttk.Button(self, text='7', command=self.enter_7)
58sev.grid(row=2, column=0)
59eig = ttk.Button(self, text='8', command=self.enter_8)
60eig.grid(row=2, column=1)
61nin = ttk.Button(self, text='9', command=self.enter_9)
62nin.grid(row=2, column=2)
63div = ttk.Button(self, text='/', command=self.division)
64div.grid(row=2, column=3)
65fou = ttk.Button(self, text='4', command=self.enter_4)
66fou.grid(row=3, column=0)
67fiv = ttk.Button(self, text='5', command=self.enter_5)
68fiv.grid(row=3, column=1)
69six = ttk.Button(self, text='6', command=self.enter_6)
70six.grid(row=3, column=2)
71mul = ttk.Button(self, text='*', command=self.multiplication)
72mul.grid(row=3, column=3)
73one = ttk.Button(self, text='1', command=self.enter_1)
74one.grid(row=4, column=0)
75two = ttk.Button(self, text='2', command=self.enter_2)
76two.grid(row=4, column=1)
77thr = ttk.Button(self, text='3', command=self.enter_3)
78thr.grid(row=4, column=2)
79mns = ttk.Button(self, text='-', command=self.subtraction)
80mns.grid(row=4, column=3)
81zer = ttk.Button(self, text='0', command=self.enter_0)
82zer.grid(row=5, column=0)
83dot = ttk.Button(self, text='.', command=self.enter_dot)
84dot.grid(row=5, column=1)
85equ = ttk.Button(self, text='=', command=self.equally)
86equ.grid(row=5, column=2)
87pls = ttk.Button(self, text='+', command=self.addition)
88pls.grid(row=5, column=3)
89self.pack()
90
91def enter_1(self):
92"""
93Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
94"""
95self.enter_digit('1')
96
97def enter_2(self):
98"""
99Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
100"""
101self.enter_digit('2')
102
103def enter_3(self):
104"""
105Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
106"""
107self.enter_digit('3')
108
109def enter_4(self):
110"""
111Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
112"""
113self.enter_digit('4')
114
115def enter_5(self):
116"""
117Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
118"""
119self.enter_digit('5')
120
121def enter_6(self):
122"""
123Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
124"""
125self.enter_digit('6')
126
127def enter_7(self):
128"""
129Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
130"""
131self.enter_digit('7')
132
133def enter_8(self):
134"""
135Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
136"""
137self.enter_digit('8')
138
139def enter_9(self):
140"""
141Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
142"""
143self.enter_digit('9')
144
145def enter_0(self):
146"""
147Переадресация вызова на метод ввода цифры с передачей ее в виде аргумента.
148"""
149self.enter_digit('0')
150
151def neg_pos(self):
152"""
153Метод установки знака числа.
154"""
155if self.entry.get() == 'Error' or self.entry.get() == '0' or not self.entry.get(): # блокирование ввода если имеется ошибка
156return
157elif self.entry.get()[0] == '-':
158self.entry.delete(0)
159else:
160self.entry.insert(0, '-')
161
162def cls(self):
163"""
164Метод очистки экрана
165"""
166self.entry.delete(0, tk.END)
167self.clear_screen = False
168
169def enter_dot(self):
170"""
171Метод ввода десятичной точки
172"""
173if self.clear_screen:
174self.cls()
175if '.' in self.entry.get():
176return
177elif self.entry.get():
178self.entry.insert(tk.END, '.')
179else:
180self.entry.insert(tk.END, '0.')
181
182def clear(self):
183"""
184Метод очистки калькулятора
185"""
186self.entry.delete(0, tk.END) # очистка экрана
187self.entry.insert(tk.END, '0') # базовый ноль на экране
188self.memory = 0 # очистка памяти
189self.action = '' # очистка указателя операций
190
191def delete(self):
192"""
193Метод удаления последнего символа на экране
194"""
195if self.clear_screen:
196self.cls()
197self.entry.delete(len(self.entry.get()) - 1) # удаление последнего символа
198if not self.entry.get():
199self.entry.insert(tk.END, '0')
200
201def division(self):
202"""
203Переадресация вызова на метод ввода действия с передачей его в виде аргумента.
204"""
205self.actions('/')
206
207def multiplication(self):
208"""
209Переадресация вызова на метод ввода действия с передачей его в виде аргумента.
210"""
211self.actions('*')
212
213def subtraction(self):
214"""
215Переадресация вызова на метод ввода действия с передачей его в виде аргумента.
216"""
217self.actions('-')
218
219def addition(self):
220"""
221Переадресация вызова на метод ввода действия с передачей его в виде аргумента.
222"""
223self.actions('+')
224
225def equally(self):
226"""
227Переадресация вызова на метод ввода действия равно.
228"""
229self.actions()
230
231def enter_digit(self, digit: str):
232"""
233Метод ввода цифры
234:param digit: текст
235"""
236if self.entry.get() == '0' or self.clear_screen:
237self.cls()
238self.entry.insert(tk.END, digit)
239
240def actions(self, op: str = ''):
241"""
242Метод выполнения действий.
243:param op: текст - знак действия -,+,/,*
244"""
245try:
246if self.entry.get() == 'Error' or self.entry.get()[-1] == '.':
247return
248elif self.action:
249self.memory = self.action_case[self.action](self.memory, float(self.entry.get()))
250if self.memory % 1 == 0:
251self.memory = int(self.memory)
252self.cls()
253self.entry.insert(0, self.memory)
254self.action = op
255self.clear_screen = True
256return
257self.action = op
258self.memory = float(self.entry.get())
259self.clear_screen = True
260except (ZeroDivisionError, ValueError):
261self.cls()
262self.entry.insert(tk.END, 'Error')
263self.action = ''
264self.clear_screen = True
265
266
267def main():
268"""
269Функция запуска основного цикла приложения
270"""
271root = tk.Tk() # создание главного окна приложения
272Example(root) # создание экземпляра класса приложения
273root.mainloop() # запуск основного цикла приложения
274
275
276if __name__ == '__main__':
277main()
278