likes
comments
collection
share

利用Python开发一个GUI计算器本次任务我们要开发一个窗口界面的计算器,可以支持按钮或自己手动输入的功能, 话不多说

作者站长头像
站长
· 阅读数 25

开始之前

本次任务我们要开发一个窗口界面的计算器,支持按钮或手动输入的功能,这里需要使用库"tkinter"来实现,如果你的Python里没有安装这个库,请在终端里输入这行代码:

pip install tkinter

话不多说,直接开始!

构建GUI窗口

首先,必须确定窗口的大小,太大会失去美观,太小又会使用不便,因此一个合适的大小的计算器才能简便兼顾美观;此外,最好不要让用户调整计算器的大小,这样会出现一些不必要的麻烦。所以,我们会有以下的代码:

#导入tkinter库
from tkinter import *
import tkinter as tk

#创建变量
window = tk.Tk()
#设置窗口大小
window.geometry("370x420")
#不允许用户调整窗口大小
window.resizable(0, 0)
#窗口标题
window.title("计算器")

#窗口加载
window.mainloop()

运行效果

利用Python开发一个GUI计算器本次任务我们要开发一个窗口界面的计算器,可以支持按钮或自己手动输入的功能, 话不多说

可以看到,我们的窗口被设置成了370x420,其中370长度420宽度,并且通过window.resizable(0, 0)窗口也无法调整大小了。

添加按钮和输入框组件

添加这两个组件,我们需要tkinter库中的ButtonEntry。接着,还要让按钮整齐的摆列起来让用户更加直观的去操作。因此,需要使用.place().pack()方法来实现(其他布局方式也可以)。

  • 输入框示例
#创建单行输入框,设置字体大小和宽度
entry = tk.Entry(window, font=("Menlo", 30), width=12)
#让它显示在窗口上
entry.pack(pady=40)

在这段代码中,Entry组件将赋值给变量entryfont=("Menlo", 30)是一个元组,指定输入框中文本的字体和大小width=12指定输入框的宽度字符的平均宽度为单位);entry.pack(pady=40) 将entry组件添加父容器window中,用pack方法进行布局管理pady=40是一个选项,在entry组件的垂直上添加额外空间,(单位通常是像素)。

接着,将代码插入上次代码window.title("计算器")下方,运行,你会看到这个结果:

利用Python开发一个GUI计算器本次任务我们要开发一个窗口界面的计算器,可以支持按钮或自己手动输入的功能, 话不多说

  • 按钮示例
Button_0 = tk.Button(window, text="0", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "0"))
Button_0.place(x=8, y=135)

Button_delete = tk.Button(window, text="清空", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: del_number(entry))
Button_delete.place(x=98, y=135)

Button_calculation = tk.Button(window, text="计算", width=6, height=2, font=("Arial", 14, "bold"),command=calculate_and_display)
Button_calculation.place(x=188, y=135)

Button_1 = tk.Button(window, text="1", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "1"))
Button_1.place(x=8, y=200)

Button_2 = tk.Button(window, text="2", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "2"))
Button_2.place(x=98, y=200)

Button_3 = tk.Button(window, text="3", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "3"))
Button_3.place(x=188, y=200)

Button_jia = tk.Button(window, text="+", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "+"))
Button_jia.place(x=278, y=135)

Button_4 = tk.Button(window, text="4", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "4"))
Button_4.place(x=8, y=270)

Button_5 = tk.Button(window, text="5", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "5"))
Button_5.place(x=98, y=270)

Button_6 = tk.Button(window, text="6", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "6"))
Button_6.place(x=188, y=270)

Button_jian = tk.Button(window, text="-", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "-"))
Button_jian.place(x=278, y=200)

Button_7 = tk.Button(window, text="7", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "7"))
Button_7.place(x=8, y=340)

Button_8 = tk.Button(window, text="8", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "8"))
Button_8.place(x=98, y=340)

Button_9 = tk.Button(window, text="9", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "9"))
Button_9.place(x=188, y=340)

Button_cheng = tk.Button(window, text="×", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "*"))
Button_cheng.place(x=278, y=270)

Button_chu = tk.Button(window, text="÷", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "/"))
Button_chu.place(x=278, y=340)

这段代码通过place方法实现布局管理数字按钮传递on_button_click函数,传递给entry输入框中对应的数字运算符按钮同样于数字按钮,但在点击时传递的是相应的操作符作为参数;清空按钮被配置为在点击时调用del_number函数,负责清空entry中的字符;此外计算按钮在点击时调用calculate_and_display函数,负责读取entry中的文本,执行计算。

将代码插入上次代码entry.pack(pady=40)下方,继续运行,你会看到这个错误结果:

Traceback (most recent call last):
  File "e:\Python\text.py", line 23, in <module>
    Button_calculation = tk.Button(window, text="计算", width=6, height=2, font=("Arial", 14, "bold"),command=calculate_and_display)
NameError: name 'calculate_and_display' is not defined

这段代码为什么会报错呢?因为我们还没有添加负责这些功能的函数,接下来的代码才是这个计算器的核心。

添加功能函数

接着,我们继续添加代码,去完成上述的功能:

# 计算函数
def calculate_and_display():
    #获取输入框中的内容
    expression = entry.get()

    try:
        # 计算输入框中的内容
        result = eval(expression, {"__builtins__": None}, {}) 
        entry.delete(0, tk.END)
        # 将计算结果写入输入框
        entry.insert(0,result)
    # 捕获异常
    except (SyntaxError, NameError, TypeError, ValueError, ZeroDivisionError):
        entry.delete(0, tk.END)
        #将错误写入输入框
        entry.insert(0, "无法运算")


# 按钮输入数字
def on_button_click(entry_widget, text):
    
    current_text = entry_widget.get()
    entry_widget.delete(0, tk.END)
    # 插入按钮对应数字
    entry_widget.insert(0, current_text + text)


# 删除输入框中的内容
def del_number(entry_widget):
    entry_widget.delete(0, tk.END)

在这三个函数代码里,有几个可以重点了解的地方:

  • result = eval(expression, {"__builtins__": None}, {})

    1. 执行表达式eval() 函数会执行 expression 输入框内的表达式,并返回结果result中;

    2. 限制全局变量:通过将 globals 参数设置为 {"__builtins__": None},实际上在告诉 eval() 不要使用任何内置函数或模块

    3. 限制局部变量locals 参数被设置为一个空字典 {},这意味着在表达式中不能引用任何局部变量(除了那些可能被定义在 expression 字符串中的临时变量)。

  • except (SyntaxError, NameError, TypeError, ValueError, ZeroDivisionError):

    1. SyntaxError:当运行前解释器编译出现异常时,SyntaxError会抛出异常并执行except下的代码;

    2. NameError:当未定义的变量或函数拼写错误等情况时,会出现这个异常;

    3. TypeError:当操作或函数不适用于指定的数据类型参数类型不正确其他情况时,会出现这个错误异常;

    4. ValueError: 当数学或逻辑错误,或函数接收到一个合法但不适合该上下文的值时,就会抛出这个异常;

    5. ZeroDivisionError:这个情况一般是由某个数字除以0时所发出的异常。

最后,将代码插入到第一次代码window = tk.Tk()上方,再运行,如果没有问题,就会看到这个:

利用Python开发一个GUI计算器本次任务我们要开发一个窗口界面的计算器,可以支持按钮或自己手动输入的功能, 话不多说

这样,恭喜你成功做出了一款计算器!如果你的代码不能运行报错,那么请参照以下的所有代码:

# 导入tkinter库
from tkinter import *
import tkinter as tk


# 计算函数
def calculate_and_display():
    # 获取输入框中的内容
    expression = entry.get()

    try:
        # 计算输入框中的内容
        result = eval(expression, {"__builtins__": None}, {})
        entry.delete(0, tk.END)
        # 将计算结果写入输入框
        entry.insert(0, result)
    # 捕获异常
    except (SyntaxError, NameError, TypeError, ValueError, ZeroDivisionError):
        entry.delete(0, tk.END)
        # 将错误写入输入框
        entry.insert(0, "无法运算")

# 按钮输入数字
def on_button_click(entry_widget, text):

    current_text = entry_widget.get()
    entry_widget.delete(0, tk.END)
    # 插入按钮对应数字
    entry_widget.insert(0, current_text + text)


# 删除输入框中的内容
def del_number(entry_widget):
    entry_widget.delete(0, tk.END)


# 创建变量
window = tk.Tk()
# 设置窗口大小
window.geometry("370x420")
# 不允许用户调整窗口大小
window.resizable(0, 0)
# 窗口标题
window.title("计算器")

entry = tk.Entry(window, font=("Menlo", 30), width=12)
entry.pack(pady=40)

Button_0 = tk.Button(window, text="0", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "0"))
Button_0.place(x=8, y=135)

Button_delete = tk.Button(window, text="清空", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: del_number(entry))
Button_delete.place(x=98, y=135)

Button_calculation = tk.Button(window, text="计算", width=6, height=2, font=("Arial", 14, "bold"),command=calculate_and_display)
Button_calculation.place(x=188, y=135)

Button_1 = tk.Button(window, text="1", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "1"))
Button_1.place(x=8, y=200)

Button_2 = tk.Button(window, text="2", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "2"))
Button_2.place(x=98, y=200)

Button_3 = tk.Button(window, text="3", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "3"))
Button_3.place(x=188, y=200)

Button_jia = tk.Button(window, text="+", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "+"))
Button_jia.place(x=278, y=135)

Button_4 = tk.Button(window, text="4", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "4"))
Button_4.place(x=8, y=270)

Button_5 = tk.Button(window, text="5", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "5"))
Button_5.place(x=98, y=270)

Button_6 = tk.Button(window, text="6", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "6"))
Button_6.place(x=188, y=270)

Button_jian = tk.Button(window, text="-", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "-"))
Button_jian.place(x=278, y=200)

Button_7 = tk.Button(window, text="7", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "7"))
Button_7.place(x=8, y=340)

Button_8 = tk.Button(window, text="8", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "8"))
Button_8.place(x=98, y=340)

Button_9 = tk.Button(window, text="9", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "9"))
Button_9.place(x=188, y=340)

Button_cheng = tk.Button(window, text="×", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "*"))
Button_cheng.place(x=278, y=270)

Button_chu = tk.Button(window, text="÷", width=6, height=2, font=("Arial", 14, "bold"),command=lambda: on_button_click(entry, "/"))
Button_chu.place(x=278, y=340)

# 窗口加载
window.mainloop()

如果还有其他的问题,请随时提问

对了,看过的人如果有什么好的灵感,在评论区留一下言,谢谢!

转载自:https://juejin.cn/post/7398709913570394147
评论
请登录