Не работает кнопка (tkinter)
Пишу калькулятор. Вот код:
from tkinter import *
class Application(Frame):
def __init__(self, master):
super().__init__(master)
self.grid()
self.create_widgets()
def add_data(self, data):
if "0" <= data <= "9":
self.data_.append(data)
self.is_symbol = False
self.is_point = False
elif data == "=":
if not self.is_point:
if not self.is_symbol:
self.calculate()
elif data == ".":
if not self.is_symbol:
if not self.is_point:
self.data_.append(data)
self.is_point = True
self.is_symbol = True
else:
if not self.is_symbol and not self.is_point:
self.data_.append(data)
self.is_symbol = True
self.is_point = True
elif self.is_symbol and not self.is_point:
self.data_[len(self.data_) - 1] = data
def create_widgets(self):
self.is_point = True
self.is_symbol = True
self.data_ = ["0"]
self.lbl = Label(self, text="")
self.lbl.grid(row=0, column=0, columnspan=3, sticky=W)
Button(self,
text="/",
command=self.add_data("/")
).grid(row=1, column=0, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="*",
command=self.add_data("*")
).grid(row=1, column=1, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="-",
command=self.add_data("-")
).grid(row=1, column=2, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="7",
command=self.add_data("7")
).grid(row=2, column=0, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="8",
command=self.add_data("8")
).grid(row=2, column=1, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="9",
command=self.add_data("9")
).grid(row=2, column=2, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="4",
command=self.add_data("4")
).grid(row=3, column=0, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="5",
command=self.add_data("5")
).grid(row=3, column=1, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="6",
command=self.add_data("6")
).grid(row=3, column=2, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="1",
command=self.add_data("1")
).grid(row=4, column=0, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="2",
command=self.add_data("2")
).grid(row=4, column=1, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="3",
command=self.add_data("3")
).grid(row=4, column=2, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="0",
command=self.add_data("0")
).grid(row=5, column=0, columnspan=2, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text=".",
command=self.add_data(".")
).grid(row=5, column=2, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="+",
command=self.add_data("+")
).grid(row=2, column=3, rowspan=2, ipadx=10, ipady=6, padx=10, pady=10)
Button(self,
text="=",
command=self.add_data("=")
).grid(row=4, column=3, rowspan=2, ipadx=10, ipady=6, padx=10, pady=10)
def calculate(self):
print("WORKING")
numbers = []
symbols = ["+", "-", "*", "/"]
number = "0"
for symbol in self.data_:
if symbol not in symbols:
number += symbol
else:
numbers.append(number)
number = "0"
numbers.append(symbol)
for i in range(0, len(numbers) - 2, 3):
if numbers[i + 1] == "+":
res = int(numbers[i]) + int(numbers[i + 2])
numbers[i + 2] = res
elif numbers[i + 1] == "-":
res = int(numbers[i]) - int(numbers[i + 2])
numbers[i + 2] = res
elif numbers[i + 1] == "/":
res = int(numbers[i]) / int(numbers[i + 2])
numbers[i + 2] = res
else:
res = int(numbers[i]) * int(numbers[i + 2])
numbers[i + 2] = res
self.lbl.configure(text=numbers[len(numbers) - 1])
print(numbers[len(numbers) - 1])
root = Tk()
root.title("Calculator")
root.geometry("400x300")
app = Application(root)
root.mainloop()
Никаких ошибок не получаю, всё запускается. Строчка print("WORKING") сделана для того, чтобы понять входит ли программа в функцию calculate. Как оказалось, не входит, даже при соблюдении всех условий (точка не последний символ, арифметический знак не последний символ - булевые величины is_point и is_symbol отвечают за проверку этих условий).
Ответы (1 шт):
Кнопки не работают, потому что у вас при создании кнопок методы сразу вызываются, а не привязываются к кнопке. Для решения этой проблемы нужно вызов метода обернуть в lambda:
command=lambda: self.add_data("/")Аналогично вот этому вопросу: Код работает, но функция выполняется ДО нажатия на кнопкуКнопки создаются вручную, хотя логично было бы это делать в цикле. Пример реализации:
# Символы обернул в iter, чтобы можно было получать следующий символ с помощью next: symbols = iter("/*-789456123") for row in range(1, 5): # цикл от 1 до 4 for col in range(3): symbol = next(symbols) Button(self, text=symbol, # Тут нужно передавать символ через параметр, иначе символ будет браться из локальной переменной symbol (ее последнего значения): command=lambda sym=symbol: self.add_data(sym) ).grid(row=row, column=col, ipadx=10, ipady=6, padx=10, pady=10) # Дальше параметры grid меняются нерегулярно, можно их хранить как словари params = [ ("0", dict(row=5, column=0, columnspan=2, ipadx=10, ipady=6, padx=10, pady=10)), (".", dict(row=5, column=2, ipadx=10, ipady=6, padx=10, pady=10)), ("+", dict(row=2, column=3, rowspan=2, ipadx=10, ipady=6, padx=10, pady=10)), ("=", dict(row=4, column=3, rowspan=2, ipadx=10, ipady=6, padx=10, pady=10)) ] for symbol, grid_params in params: Button(self, text=symbol, command=lambda sym=symbol: self.add_data(sym) ).grid(**grid_params) # передача словаря параметров в grid