Проблема с динамическим изменением команды, которую вызывает кнопка в tkinter

В этом простом графическом интерфейсе калькулятора я создаю шаблон фрейма, используя классы. Фрейм имеет 2 метки, 2 поля ввода и кнопку. Я бы хотел, чтобы кнопка запускала определенную команду в зависимости от function_callпеременная передана при инициализации - но это не работает. В two_points функция должна быть вызвана для первого объекта, и one_pointследует называть второй. Как мне динамически изменять вызываемую команду в зависимости от того, какой объект я использую? Спасибо, что нашли время, чтобы прочитать это.

      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 ответ

В command аргумент ключевого слова Buttonконструктор должен быть функцией. Здесь вы даете ему вместо строки, которая является именем метода selfэто следует назвать. Итак, вы должны сначала получить этот метод, используя setattrчтобы иметь возможность называть это. Это должно сделать это:

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

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

Тогда у вас есть ошибка в strip_string но это уже другая история.

Другие вопросы по тегам