如何根据调用它的 Button 执行更多命令? (类 和 tkinter)

How can I execute more a command based on the Button that called it? (Classes and tkinter)

我正在自学 Python,目前正在做我的第一个项目。我正在 Python 中制作一个计算器应用程序,我称之为 Pythulator。我试图弄清楚如何在按下按钮时将数字键盘的相应数字连接到数字字符串。我创建了一个名为 class 的小键盘来存储我的小键盘,我让它显示在 GUI 上,但是每当我在小键盘上按下一个数字时,控制台中不会打印任何内容。 这是代码:

#!/usr/bin/python3

"""Pythulator Version 1.0.0"""

import math
import tkinter as tk
from decimal import Decimal, getcontext

numstring = ""

class Numpad:
    global numstring

    def __init__(self, master):
        num_frame = tk.Frame(master)
        num_frame.pack(side = tk.BOTTOM)
        self.numpad_1 = tk.Button(num_frame, text = "1", command = self.concat)
        self.numpad_1.grid(row = 6, column = 3)
        self.numpad_2 = tk.Button(num_frame, text = "2", command = self.concat)
        self.numpad_2.grid(row = 6, column = 4)
        self.numpad_3 = tk.Button(num_frame, text = "3", command = self.concat)
        self.numpad_3.grid(row = 6, column = 5)
        self.numpad_4 = tk.Button(num_frame, text = "4", command = self.concat)
        self.numpad_4.grid(row = 5, column = 3)
        self.numpad_5 = tk.Button(num_frame, text = "5", command = self.concat)
        self.numpad_5.grid(row = 5, column = 4)
        self.numpad_6 = tk.Button(num_frame, text = "6", command = self.concat)
        self.numpad_6.grid(row = 5, column = 5)
        self.numpad_7 = tk.Button(num_frame, text = "7", command = self.concat)
        self.numpad_7.grid(row = 4, column = 3)
        self.numpad_8 = tk.Button(num_frame, text = "8", command = self.concat)
        self.numpad_8.grid(row = 4, column = 4)
        self.numpad_9 = tk.Button(num_frame, text = "9", command = self.concat)
        self.numpad_9.grid(row = 4, column = 5)
        self.numpad_0 = tk.Button(num_frame, text = "0", command = self.concat)
        self.numpad_0.grid(row = 7, column = 4)

    def concat(self):
        self = str(self)
        numstring.join(self)
        print(numstring)



root = tk.Tk()

obj = Numpad(root)

root.geometry("400x400")
root.mainloop() 

我在想当我按下其中一个数字键盘按钮时控制台中没有打印任何内容的原因,当它调用 concat 函数时,没有任何内容可以连接,因为变量不等同于一个字符串。无论如何我可以为每个按钮分配一个字符串来连接吗?我尝试在 class 中为每个数字键盘按钮创建一个函数,为它分配一个字符串,但这占用了太多 space,我只想用一个或两个函数来完成它。

您可以使用lambda创建另一个函数来调用带有附加参数的原始方法

除此之外,您还需要在方法内部声明全局变量。要将一个字符串附加到另一个字符串,您可以使用 += 运算符。

class Numpad:
    def __init__(self, master):
        num_frame = tk.Frame(master)
        num_frame.pack(side = tk.BOTTOM)
        self.numpad_1 = tk.Button(num_frame, text="1", command=lambda: self.concat('1'))
        self.numpad_1.grid(row=6, column=3)
        self.numpad_2 = tk.Button(num_frame, text="2", command=lambda: self.concat('2'))
        self.numpad_2.grid(row=6, column=4)
        self.numpad_3 = tk.Button(num_frame, text="3", command=lambda: self.concat('3'))
        self.numpad_3.grid(row=6, column=5)
        self.numpad_4 = tk.Button(num_frame, text="4", command=lambda: self.concat('4'))
        self.numpad_4.grid(row=5, column=3)
        self.numpad_5 = tk.Button(num_frame, text="5", command=lambda: self.concat('5'))
        self.numpad_5.grid(row=5, column=4)
        self.numpad_6 = tk.Button(num_frame, text="6", command=lambda: self.concat('6'))
        self.numpad_6.grid(row=5, column=5)
        self.numpad_7 = tk.Button(num_frame, text="7", command=lambda: self.concat('7'))
        self.numpad_7.grid(row=4, column=3)
        self.numpad_8 = tk.Button(num_frame, text="8", command=lambda: self.concat('8'))
        self.numpad_8.grid(row=4, column=4)
        self.numpad_9 = tk.Button(num_frame, text="9", command=lambda: self.concat('9'))
        self.numpad_9.grid(row=4, column=5)
        self.numpad_0 = tk.Button(num_frame, text="0", command=lambda: self.concat('0'))
        self.numpad_0.grid(row=7, column=4)

    def concat(self, n):
        global numstring
        numstring += n
        print(n, numstring)

这个方法问题很大:

def concat(self):
    self = str(self)
    numstring.join(self)
    print(numstring)

您还没有定义 __str__ 所以 str(self) 将是一些时髦的字符串。然后 numstring.join(self) 是一个空操作——它 returns 一个你根本没有分配给任何东西的字符串!所以你总是打印你开始时的空numstring

而且——你没有考虑哪个键被按下了……任何按键触发完全相同self.concat 电话,没有关于 "which key was it again?" 的信息。

functools.partial 允许您提前绑定参数(是的,您 可以 使用一个脏兮兮的 lambda,但是,您将 如果你忘记了 lambda 的存在,那么露营者会更快乐...)。

所以例如一个按钮应该是...:[=​​26=]

self.numpad_1 = tk.Button(num_frame, text='1',
    command=functools.partial(self.concat, '1'))

其他人也一样。

现在,concat 方法将接收与被单击的按钮对应的文本,当然它需要将其记录在某处。

我建议避免使用全局变量,而是使用

启动 __init__
self.nums = []

现在concat过着轻松的生活:

def concat(self, digit):
    self.nums.append(digit)
    print(''.join(self.nums))

顺便说一句,这使您可以更轻松地实现关键功能,例如删除键——它只需要删除 self.nums 列表的最后一项(self.nums.pop() 就足够了)并且它是让用户更正拼写错误至关重要!