利用Python开发一个GUI计算器本次任务我们要开发一个窗口界面的计算器,可以支持按钮或自己手动输入的功能, 话不多说
开始之前
本次任务我们要开发一个窗口界面的计算器,支持按钮或手动输入的功能,这里需要使用库"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()
运行效果:
可以看到,我们的窗口被设置成了370x420
,其中370
是长度,420
是宽度,并且通过window.resizable(0, 0)
窗口也无法调整大小了。
添加按钮和输入框组件
添加这两个组件,我们需要tkinter
库中的Button
和Entry
。接着,还要让按钮整齐的摆列起来让用户更加直观的去操作。因此,需要使用.place()
和.pack()
方法来实现(其他布局方式也可以)。
- 输入框示例:
#创建单行输入框,设置字体大小和宽度
entry = tk.Entry(window, font=("Menlo", 30), width=12)
#让它显示在窗口上
entry.pack(pady=40)
在这段代码中,Entry
组件将赋值给变量entry
;font=("Menlo", 30)
是一个元组,指定输入框中文本的字体和大小;width=12
指定输入框的宽度(字符的平均宽度为单位);entry.pack(pady=40)
将entry
组件添加父容器window
中,用pack
方法进行布局管理,pady=40
是一个选项,在entry
组件的垂直上添加额外空间,(单位通常是像素)。
接着,将代码插入上次代码的window.title("计算器")
的下方,运行,你会看到这个结果:
- 按钮示例:
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()
的上方,再运行,如果没有问题,就会看到这个:
这样,恭喜你成功做出了一款计算器!如果你的代码不能运行报错,那么请参照以下的所有代码:
# 导入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