如何引用列表内部的tkinter按钮的属性? (蟒蛇)

时间:2018-08-27 07:02:01

标签: python list tkinter attributes

我正在制作一个计算器程序,正在创建要在计算器界面中使用的按钮。我最初使用一个for循环创建所有按钮,然后想要重新配置某些按钮以更改其颜色和命令。有什么方法可以引用属性,例如列表内按钮的“文本”属性?例如,如果按钮索引的文本属性为“ +”或“-”,“ /”或“ *”,则将颜色重新配置为红色。

我现在要做的当前代码效率很低,因为它要求每个按钮分别由索引引用。如果可能,我想通过属性而不是仅通过索引号进行引用。有问题的算法可以在下面找到。

#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()

1 个答案:

答案 0 :(得分:0)

如果您知道要将一组小部件配置为相同样式,请保存 专用对象(列表或字典)中的窗口小部件引用。 然后,您可以应用相同的配置遍历那些特定的引用。 例如,如果您只想将红色应用于操作员按钮。

“…/assets/strings/pt-br.json”;
“…/assets/strings/es-es.json”;
“…/assets/strings/pt-br.json”