Я создаю программу калькулятора и создаю кнопки для перехода в интерфейс калькулятора.Сначала я создаю все кнопки, используя одну для цикла, а затем хочу перенастроить определенные кнопки, чтобы изменить их цвет и команду.Есть ли способ ссылаться на такой атрибут, как атрибут «текст» кнопки внутри списка?Например, если индекс кнопки имеет текстовый атрибут «+», или «-», или «/», или «*», измените цвет на красный.
Текущий код, который я должен сделать, очень неэффективен, так кактребует, чтобы каждая кнопка была указана индексом индивидуально.Если возможно, я бы хотел ссылаться по атрибуту, а не только по номеру индекса.Рассматриваемый алгоритм можно найти ниже.
#Method that creates calculator buttons, appends them to a list and packs them into the grid.
def create_number_buttons(self):
button_characters = "789*456/123-0.=+"
i = 0
self.button_list = []
for row_counter in range(2,6):
for column_counter in range(4):
self.button_list.append(Button(root, bg="#11708e", fg="white", activebackground="#11708e", pady=25, padx=35, text=button_characters[i], font=("Helvetica", 16, 'bold')))
self.button_list[i].grid(row=row_counter, column=column_counter, sticky="NSEW")
self.button_list[i].configure(command = lambda c=button_characters[i]: self.num_press(c))
i += 1
#Reconfigures the specific buttons.
self.button_list[3].configure(bg="#d14302", activebackground="#d14302")
self.button_list[7].configure(bg="#d14302", activebackground="#d14302")
self.button_list[11].configure(bg="#d14302", activebackground="#d14302")
self.button_list[13].configure(bg="#d14302", activebackground="#d14302")
self.button_list[14].configure(command=lambda: self.calculate_answer(), bg="#d14302", activebackground="#d14302")
self.button_list[15].configure(bg="#d14302", activebackground="#d14302")
Спасибо за вашу помощь!
Полный код ниже:)
from tkinter import *
from tkinter import messagebox
#Import so that I'm able to use regex to remove leading zeroes from the equation string when performing the calcultion.
import re
#Class to support logic of calculator, used for functionality and math operations.
class CalculatorFunctions:
def __init__(self, root):
self.root = root
self.answer = 0
#Command called if a number button is pressed.
def num_press(self, num):
new_input = num
self.text_box.insert(self.value_position, new_input)
self.value_position += 1
#Command that clears everything in the calculator's entrybox.
def clear_screen(self):
self.text_box.delete(0, END)
#Creates a message-box popup to display relevant author information.
def show_author_button(self):
messagebox.showinfo("Author", "Devin, August 2018")
#If the eval function returns a syntaxerror or a zerodivision error this command is called.
#Makes an error message popup box.
def error_popup(self):
messagebox.showwarning("Error", "Please edit your code and calculate again. Common errors include dividing by 0 and including too many decimal points in one number.")
#Uses the eval function to calculate entered string in calculator.
def calculate_answer(self):
errormessage = "SyntaxError"
try:
#Removes leading zeroes from the start of digits but not after a decimal point.
self.answer = eval(re.sub(r"((?<=^)|(?<=[^\.\d]))0+(\d+)", r"\1\2", self.equation.get()))
except (SyntaxError, ZeroDivisionError):
self.error_popup()
self.answer = eval(re.sub(r"((?<=^)|(?<=[^\.\d]))0+(\d+)", r"\1\2", self.equation.get()))
#Appends answer to list of values able to be inserted into calculator entry.
self.accepted_values.append(str(self.answer))
self.text_box.delete(0, END)
self.update_entry_with_answer()
def update_entry_with_answer(self):
self.text_box.insert(0, self.answer)
#Removes the last character in the entry field.
def backspace(self):
current = str(self.text_box.get())
new_input = current[:-1]
self.accepted_values.append(new_input)
self.text_box.delete(0, END)
self.text_box.insert(0, new_input)
#Checks for valid input
def testVal(self, entered_value, modifytype):
#Checks if text wanting to be inserted into the entryfield is valid.
if modifytype == '1': #insert
operators_and_d_point = "/*+-"
current_string = str(self.equation.get())
if entered_value == ".":
if current_string[-1] == ".":
return False
#If the last character entered was an operator, don't allow another operator or decimal point to be added to the entry box.
if entered_value in operators_and_d_point:
if current_string == "":
if entered_value == "-" or entered_value == "+":
return True
else:
return False
if current_string[-1] in operators_and_d_point:
if entered_value == "+" or entered_value == "-":
return True
else:
return False
if entered_value in self.accepted_values:
return True
#Accepts all attempts to remove text from the entryfield.
elif modifytype == "0":#delete
return True
return False
#Class to create widgets for the calculator GUI.
class CalculatorGUI(CalculatorFunctions):
def __init__(self, root):
self.root = root
self.value_position = 0
self.create_calculator_widgets()
root.bind("=", lambda event: self.calculate_answer())
self.accepted_values = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "-", "*", "/", "."]
#Method called to create widgets associated with the calculator.
def create_calculator_widgets(self):
self.create_text_box()
self.create_number_buttons()
self.create_clear_button()
self.create_author_button()
self.create_backspace_button()
#Creates entry field, contents of the entry field stored as textvariable.
def create_text_box(self):
self.equation = StringVar()
self.text_box = Entry(root, justify=RIGHT, validate="key", textvariable=self.equation, font=("Helveitca", 16), borderwidth=15)
#Uses the tkinter entry box's "validatecommand" to check for valid input, method found in above class.
self.text_box['validatecommand'] = (self.text_box.register(self.testVal),'%S','%d')
self.text_box.grid(row=0, column=0, columnspan=4, ipady=10, sticky="WE")
#Method that creates calculator buttons, appends them to a list and packs them into the grid.
def create_number_buttons(self):
button_characters = "789*456/123-0.=+"
i = 0
self.button_list = []
for row_counter in range(2,6):
for column_counter in range(4):
self.button_list.append(Button(root, bg="#11708e", fg="white", activebackground="#11708e", pady=25, padx=35, text=button_characters[i], font=("Helvetica", 16, 'bold')))
self.button_list[i].grid(row=row_counter, column=column_counter, sticky="NSEW")
self.button_list[i].configure(command = lambda c=button_characters[i]: self.num_press(c))
i += 1
#Reconfigures the specific buttons.
self.button_list[3].configure(bg="#d14302", activebackground="#d14302")
self.button_list[7].configure(bg="#d14302", activebackground="#d14302")
self.button_list[11].configure(bg="#d14302", activebackground="#d14302")
self.button_list[13].configure(bg="#d14302", activebackground="#d14302")
self.button_list[14].configure(command=lambda: self.calculate_answer(), bg="#d14302", activebackground="#d14302")
self.button_list[15].configure(bg="#d14302", activebackground="#d14302")
def create_clear_button(self):
clear_button = Button(root, bg="#302e2e", fg="white", text="AC", font=("Helvetica", 12, 'bold'), pady=10, command=lambda: self.clear_screen())
clear_button.grid(row=1, columnspan=2, sticky="WE")
def create_backspace_button(self):
backspace_button = Button(root, bg="#302e2e", fg="white", text="Backspace", font=("Helvetica", 12, 'bold'), command=lambda: self.backspace())
backspace_button.grid(row=1, column=3, sticky="NSEW")
def create_author_button(self):
author_button = Button(root, bg="#302e2e", fg="white", font=("Helvetica", 12, 'bold'), text="Info", command=lambda: self.show_author_button())
author_button.grid(row=1, column=2, sticky="NSEW")
if __name__ == "__main__":
root = Tk()
calc = CalculatorGUI(root)
root.title("Calculator")
#Ensures the GUI window containing the calculator is unable to be resized, the 0,0 represents the x,y of resize allowed.
root.resizable(0, 0)
root.mainloop()