动态更改按钮在 tkinter 中调用的命令的问题

Posted

技术标签:

【中文标题】动态更改按钮在 tkinter 中调用的命令的问题【英文标题】:Problem with dynamically changing which command a button calls in tkinter 【发布时间】:2021-06-14 02:02:36 【问题描述】:

在这个简单的计算器 GUI 中,我正在使用类创建框架模板。该框架有 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()

【问题讨论】:

self.function_call = getattr(self, function_call)? 效果很好,谢谢! 【参考方案1】:

Button 构造函数的command 关键字参数应该是一个函数。 在这里,您给它一个字符串,它是应该调用的self 方法的名称。因此,您必须首先使用setattr 获取此方法才能调用它。应该这样做:


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

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

然后你在strip_string 中有一个错误,但那是另一回事了。

【讨论】:

有人建议我将 self.function_call 设置为 getattr(self, function_call),效果很好。感谢您花时间回答我的问题!同样,我的 strip_string 函数工作正常(自发布以来我添加了异常处理)。再次感谢!

以上是关于动态更改按钮在 tkinter 中调用的命令的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用tkinter按钮更改变量的值?

基于选定的单选按钮在 Tkinter 中启动命令?

在 Python 3 和 tkinter 中使用变量调用函数

Python中带有lambda的tkinter按钮命令

Tkinter - 在类中使用Button命令从另一个类调用函数

在Canvas tkinter上动态更改滚动条的长度