Skip to main content
 首页 » 编程设计

python之如何在 Python 中使用 tkinter 编写带有 GUI 的计算器

2025年05月04日26think

我正在为 GCSE 学习计算,我们受控评估的任务之一是创建一个带有 GUI 的计算器。

我能够在没有 GUI 的情况下编写一个简单的计算器,但我不明白如何使用 GUI 完成它。

下面是我从 teampython.wordpress.com 获得的一段代码,我对它的理解有些模糊,但如果有人能向我解释每个步骤,那将非常有帮助。

 # calc.py - a Python calculator 
 from tkinter import * 
 
 
class Calc(): 
    def __init__(self): 
        self.total = 0 
        self.current = "" 
        self.new_num = True 
        self.op_pending = False 
        self.op = "" 
        self.eq = False 
 
 
    def num_press(self, num): 
        self.eq = False 
        temp = text_box.get() 
        temp2 = str(num)       
        if self.new_num: 
            self.current = temp2 
            self.new_num = False 
        else: 
            if temp2 == '.': 
                if temp2 in temp: 
                    return 
            self.current = temp + temp2 
        self.display(self.current) 
 
    def calc_total(self): 
        self.eq = True 
        self.current = float(self.current) 
        if self.op_pending == True: 
            self.do_sum() 
        else: 
            self.total = float(text_box.get()) 
 
    def display(self, value): 
        text_box.delete(0, END) 
        text_box.insert(0, value) 
 
    def do_sum(self): 
        if self.op == "add": 
            self.total += self.current 
        if self.op == "minus": 
            self.total -= self.current 
        if self.op == "times": 
            self.total *= self.current 
        if self.op == "divide": 
            self.total /= self.current 
        self.new_num = True 
        self.op_pending = False 
        self.display(self.total) 
 
    def operation(self, op):  
        self.current = float(self.current) 
        if self.op_pending: 
            self.do_sum() 
        elif not self.eq: 
            self.total = self.current 
        self.new_num = True 
        self.op_pending = True 
        self.op = op 
        self.eq = False 
 
    def cancel(self): 
        self.eq = False 
        self.current = "0" 
        self.display(0) 
        self.new_num = True 
 
    def all_cancel(self): 
        self.cancel() 
        self.total = 0 
 
    def sign(self): 
        self.eq = False 
        self.current = -(float(text_box.get())) 
        self.display(self.current) 
 
sum1 = Calc() 
root = Tk() 
calc = Frame(root) 
calc.grid() 
 
root.title("Calculator") 
text_box = Entry(calc, justify=RIGHT) 
text_box.grid(row = 0, column = 0, columnspan = 3, pady = 5) 
text_box.insert(0, "0") 
 
numbers = "789456123" 
i = 0 
bttn = [] 
for j in range(1,4): 
    for k in range(3): 
        bttn.append(Button(calc, text = numbers[i])) 
        bttn[i].grid(row = j, column = k, pady = 5) 
        bttn[i]["command"] = lambda x = numbers[i]: sum1.num_press(x) 
        i += 1 
 
bttn_0 = Button(calc, text = "0") 
bttn_0["command"] = lambda: sum1.num_press(0) 
bttn_0.grid(row = 4, column = 1, pady = 5) 
 
bttn_div = Button(calc, text = chr(247)) 
bttn_div["command"] = lambda: sum1.operation("divide") 
bttn_div.grid(row = 1, column = 3, pady = 5) 
 
bttn_mult = Button(calc, text = "x") 
bttn_mult["command"] = lambda: sum1.operation("times") 
bttn_mult.grid(row = 2, column = 3, pady = 5) 
 
minus = Button(calc, text = "-") 
minus["command"] = lambda: sum1.operation("minus") 
minus.grid(row = 3, column = 3, pady = 5) 
 
point = Button(calc, text = ".") 
point["command"] = lambda: sum1.num_press(".") 
point.grid(row = 4, column = 0, pady = 5) 
 
add = Button(calc, text = "+") 
add["command"] = lambda: sum1.operation("add") 
add.grid(row = 4, column = 3, pady = 5) 
 
neg= Button(calc, text = "+/-") 
neg["command"] = sum1.sign 
neg.grid(row = 5, column = 0, pady = 5) 
 
clear = Button(calc, text = "C") 
clear["command"] = sum1.cancel 
clear.grid(row = 5, column = 1, pady = 5) 
 
all_clear = Button(calc, text = "AC") 
all_clear["command"] = sum1.all_cancel 
all_clear.grid(row = 5, column = 2, pady = 5) 
 
equals = Button(calc, text = "=") 
equals["command"] = sum1.calc_total 
equals.grid(row = 5, column = 3, pady = 5) 
 
root.mainloop() 

请您参考如下方法:

因此,我将尽我所能解释您提供的代码。 Calc() 类包含这段代码的所有函数。该结构意味着主 GUI(稍后设置)可以轻松访问每个功能。在 Calc() 类中,您有自己的函数(用 def 等表示)。这些包含此代码计算其输出的各种方法。

在类之外,我们有 Tkinter UI 代码。此代码构建您的窗口,您的各种按钮和显示位于其中。在这种情况下,按钮和文本字段的定位由“网格”方法控制。可以看到,每次代码设置一个对象(这里只有Frame、Button和Entry对象),都有一个关联的.grid(行=x,列=y...等)。这指定了每个对象在 UI 中的相对位置。例如,使用网格方法,您可以通过给第一个对象 row=1、column=0 和第二个 row=2、column=0 等来堆叠两个对象。

for 循环:

for j in range(1,4): 
    for k in range(3): 
        bttn.append(Button(calc, text = numbers[i])) 
        bttn[i].grid(row = j, column = k, pady = 5) 
        bttn[i]["command"] = lambda x = numbers[i]: sum1.num_press(x) 
        i += 1  

可能是 UI 中唯一不便于查看的部分,如果您是新手。从本质上讲,它所做的只是自动构建按钮(节省您为每个按钮单独编码的时间)。 循环中的前两行(希望如此)显然是在指定范围内循环值。在 bttn.append(... 行之下,在之前设置的 calc 框架中创建了一个按钮对象 calc = Frame(root),按钮文本由数字列表给出(字面意思是 numbers="789456123" 以上)。最初,i = 0,因此 numbers[i] 将返回列表 numbers 中的第一个元素,numbers[i] for i=1(下一次循环) 会给出 8 等等。bttn.grid(row = j, column = k, pady = 5) 使用前面提到的网格定位方法,但这里的 j 和 k 由循环本身的值(在行的情况下,值在 1 到 4 之间,在列的情况下,值在 0 到 2 - 3 列之间)。如果你运行代码,你可以看到这将定位所有键盘输入数字的按钮。此循环的最后一行(除了 i+=1,即向 i 加 1)处理为按钮分配命令。该命令将调用相关函数,在本例中为 numpress Calc() 中的函数。您可能会看到,numpress 本身会根据您按下的任何数字更新您的显示。

此示例中的最后一个代码块处理计算器的其余操作,您会注意到每个操作都遵循上述创建按钮、分配命令和在 UI 中定位按钮的模式。根据我上面的解释,您可能会看到 Calc() 中的每个剩余函数都控制算术运算或清除等。

我知道这是一堵文字墙,但希望对您有所帮助!如果我不清楚或者有什么特别的地方你不明白,请告诉我,我会尽力解释(我自己学的时间不长!)。

您可能会发现此 Tkinter UI Guide 很有用,我从该指南中学到了很多基础知识。

祝你好运