如何用Python的tkinter编程实现带GUI的计算器?

1 投票
2 回答
42031 浏览
提问于 2025-04-17 21:05

我正在学习计算机科学,作为我们的控制评估任务之一,需要制作一个带有图形界面的计算器。

我能编写一个简单的没有图形界面的计算器,但我不太明白如何制作一个带图形界面的计算器。

下面是我从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()

2 个回答

0

你需要在Python中使用一个图形用户界面(GUI)库,比如PyQt4wxPython或者Tkinter。这个问题太宽泛了,没法给你更多的细节。

可以从一些教程开始,这些教程会教你关于在Python中创建图形界面的所有基础知识。

另外,我个人建议你选择PyQt

10

我来尽量简单明了地解释一下你给的代码。这个 Calc() 类里包含了所有的功能。这样的结构让主界面(后面会设置)可以很方便地访问每个功能。在 Calc() 类里面,你会看到一些函数(用 def 开头等标识)。这些函数就是这个代码用来计算结果的各种方法。

在类外面,我们有 Tkinter 的界面代码。这段代码负责创建一个窗口,里面放置了各种按钮和显示区域。按钮和文本框的位置是通过 'grid' 方法来控制的。你可以看到,每当代码创建一个对象(这里主要是 FrameButtonEntry 对象),都会有一个 .grid(row=x, column=y...etc) 的设置。这就指定了每个对象在界面中的相对位置。例如,使用 grid 方法,你可以把两个对象堆叠在一起,给第一个对象设置 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 

这可能是界面中最不容易理解的部分,特别是如果你刚开始接触编程。其实它的作用就是自动创建按钮(省去了你一个个手动编写的时间)。循环的前两行(希望)很明显是在遍历指定范围内的值。下面的 bttn.append(... 这一行是在之前设置的 calc 框架中创建一个按钮对象,按钮的文本来自于数字列表(就是上面提到的 numbers="789456123")。最开始,i=0,所以 numbers[i] 会返回列表中的第一个元素,i=1 时,numbers[i] 就会返回 8,以此类推。bttn.grid(row = j, column = k, pady = 5) 这一行使用了之前提到的 grid 定位方法,不过这里的 j 和 k 是循环中给定的值(行的值在 1 到 4 之间,列的值在 0 到 2 之间)。如果你运行这段代码,你会看到这会把所有的数字键盘按钮放置好。这个循环中的最后一行(除了 i+=1,也就是给 i 加 1)负责给按钮分配一个命令。这个命令会调用一个相关的函数,在这里就是 Calc() 中的 numpress 函数。你可能会发现,numpress 本身会根据你按下的数字更新显示内容。

这个例子中的最后一段代码处理计算器的其他操作,你会注意到每个操作也遵循了上面创建按钮、分配命令和在界面中定位按钮的模式。根据我上面解释的内容,你可能会明白 Calc() 中的每个剩余函数都是负责某种数学运算、清除等操作。

我知道这段文字有点多,但希望能帮到你!如果我说得不清楚,或者你有特别不明白的地方,告诉我,我会尽量解释清楚(我自己也刚学不久!)。

你可能会觉得这个 Tkinter 界面指南 有用,我从中学到了很多基础知识。

祝你好运!

撰写回答