0

In this simple calculator GUI, I'm creating a frame template using classes. The frame has 2 labels, 2 entry boxes, and a button. I'd like the button to run a specific command depending on the function_call variable passed when initializing - but this doesn't work. The two_points function should be called for the first object, and one_point should be called for the second. How do I dynamically change which command is called based on which object I'm using? Thank you for taking the time to read this.

from tkinter import *

root = Tk()
root.title("Simple Slope Calculator")

class Slope_Calc:
    # Variable info that changes within the frame
    def __init__(self, master, num_1, num_2, frame_name, label_1_name, label_2_name, function_call):
        self.num_1 = int(num_1)
        self.num_2 = int(num_2)
        self.frame_name = frame_name
        self.label_1_name = label_1_name
        self.label_2_name = label_2_name
        self.function_call = function_call

        # Frame template
        self.frame_1 = LabelFrame(master, text = self.frame_name, padx = 5, pady = 5)
        self.frame_1.grid(row = self.num_1, column = self.num_2, padx = 10, pady = 10)

        self.label_1 = Label(self.frame_1, text = self.label_1_name)
        self.label_1.grid(row = 0, column = 0)

        self.entry_1 = Entry(self.frame_1)
        self.entry_1.grid(row = 0, column = 1)

        self.label_2 = Label(self.frame_1, text = self.label_2_name)
        self.label_2.grid(row = 1, column = 0)

        self.entry_2 = Entry(self.frame_1)
        self.entry_2.grid(row = 1, column = 1)

        self.calc_button = Button(self.frame_1, text = "Calculate", command = self.function_call) # This is what doesn't work
        self.calc_button.grid(row = 1, column = 2, padx = 5)

    # Strips string of spaces and parentheses
    # Returns a list of relevant ordered pair
    def strip_string(self, entry_num):
        ordered_pair = entry_num.get().split(", ")
        ordered_pair[0] = ordered_pair[0].replace("(", "")
        ordered_pair[1] = ordered_pair[1].replace(")", "")
        return(ordered_pair)

    # Calculates slope based on one point and y-intercept
    def one_point(self):
        pair_1 = self.strip_string(self.entry_1)

        b = int(self.entry_2.get())
        m = (int(pair_1[1]) - b)/(float(pair_1[1]))

        label_3 = Label(self.frame_1, text = "SLOPE-INTERCEPT EQUATION:   y = " + str(m) + "x + " + str(b))
        label_3.grid(row = 2, column = 0, columnspan = 2)


    # Calculates slope based on two points given
    def two_points(self):
        pair_1 = self.strip_string(self.entry_1)
        pair_2 = self.strip_string(self.entry_2)

        m = (int(pair_2[1]) - int(pair_1[1]))/float(int(pair_2[0]) - int(pair_1[0]))
        b = (int(pair_1[1])) - (m*int(pair_1[0]))

        label_3 = Label(self.frame_1, text = "SLOPE-INTERCEPT EQUATION:   y = " + str(m) + "x + " + str(b))
        label_3.grid(row = 2, column = 0, columnspan = 2)
  
# Calling each object
two_p = Slope_Calc(root, 0, 0, "Two Points", "First Ordered Pair", "Second Ordered Pair", "two_points")
one_p = Slope_Calc(root, 0, 1, "One Point and Y-Intercept", "Ordered Pair", "Y-intercept", "one_point")

root.mainloop()

1 Answers1

0

The command keyword argument of the Button constructor is supposed to be a function. Here you give it instead a string which is the name of the method of self that should be called. So you must first get this method using setattr to be able to call it. This should do it:


        def call():
            method = getattr(self, self.function_call)
            method()

        self.calc_button = Button(
            self.frame_1,
            text = "Calculate",
            command = call)

You then have an error in strip_string but that's another story.

qouify
  • 3,698
  • 2
  • 15
  • 26
  • 1
    Someone suggested I set self.function_call to getattr(self, function_call), and it worked perfectly. I appreciate the time you took to answer my question! Likewise, my strip_string function is working properly (I've added exception handling since posting). Thanks again! – PelicanSquirrel Mar 16 '21 at 21:15