python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python计算器

Python基于Tkinter打造高颜值计算器的完整教学

作者:Li Ming&

很多Python初学者学完基础语法后,都想做一个带界面的小项目来练手,计算器无疑是GUI入门的经典选择,今天小编就带大家用Python自带的 Tkinter 库(无需额外安装)写一个完整的计算器程序,希望对大家有所帮助

前言

很多Python初学者学完基础语法后,都想做一个带界面的小项目来练手。计算器无疑是GUI入门的经典选择——它功能明确、逻辑清晰,而且能直观地看到代码运行效果。

今天我就带大家用Python自带的 Tkinter 库(无需额外安装)写一个完整的计算器程序。它具备以下特点:

无论你是刚学Python的新手,还是想复习Tkinter布局的进阶者,这篇文章都能帮你快速上手!

一、完整代码

无需安装任何第三方库! Tkinter 是 Python 自带的GUI库,安装Python时就已经包含了。直接运行即可创建一个 Python 文件(比如 calculator.py),将以下代码完整复制进去:

#  *_* coding:utf8 *_*
# python开发的计算器代码(可更换按钮颜色)
import tkinter
from functools import partial

def get_input(entry, argu):

    # 从entry窗口展示中获取输入的内容
    input_data = entry.get()
    if (input_data[-1:] == '+') and (argu == '+'):
        return
    if (input_data[-2:] == '+-') and (argu == '-'):
        return
    if (input_data[-2:] == '--') and (argu in ['-', '+']):
        return
    if (input_data[-2:] == '**') and (argu in ['*', '/']):
        return
 
    # 输入合法将字符插入到entry窗口结尾
    entry.insert("end", argu)
 
# 退格(撤销输入)
def backspace(entry):
    input_len = len(entry.get())
    # 删除entry窗口中最后的字符
    entry.delete(input_len - 1)
 
# 清空entry内容(清空窗口)
def clear(entry):
    entry.delete(0, "end")
 
# 计算
def calc(entry):
    input_data = entry.get()
    if not input_data:
        return
    clear(entry)

    try:
        output_data = str(eval(input_data))
    except Exception:
        # 将提示信息输出到窗口
        entry.insert("end", "Calculation error")
    else:
        # 将计算结果显示在窗口中
        if len(output_data) > 20:
            entry.insert("end", "Value overflow")
        else:
            entry.insert("end", output_data)
 
 
if __name__ == '__main__':
 
    root = tkinter.Tk()
    root.title("计算器")
    root.resizable(0, 0)

    button_bg = '#d47655' # 数字颜色
    math_sign_bg = '#ae9aab' # 运算符颜色
    cal_output_bg = '#417ca9' # 等号颜色
    button_active_bg = '#BCC6A3' # 点击背景色

    entry = tkinter.Entry(root, justify="right", font=1)
    entry.grid(row=0, column=0, columnspan=4, padx=10, pady=10)
 
    def place_button(text, func, func_params, bg=button_bg, **place_params):
        my_button = partial(tkinter.Button, root, bg=button_bg, padx=10, pady=3, activebackground=button_active_bg)
        button = my_button(text=text, bg=bg, command=lambda: func(*func_params))
        button.grid(**place_params)
 
    # 文本输入类按钮
    place_button('7', get_input, (entry, '7'), row=1, column=0, ipadx=5, pady=5)
    place_button('8', get_input, (entry, '8'), row=1, column=1, ipadx=5, pady=5)
    place_button('9', get_input, (entry, '9'), row=1, column=2, ipadx=5, pady=5)
    place_button('4', get_input, (entry, '4'), row=2, column=0, ipadx=5, pady=5)
    place_button('5', get_input, (entry, '5'), row=2, column=1, ipadx=5, pady=5)
    place_button('6', get_input, (entry, '6'), row=2, column=2, ipadx=5, pady=5)
    place_button('1', get_input, (entry, '1'), row=3, column=0, ipadx=5, pady=5)
    place_button('2', get_input, (entry, '2'), row=3, column=1, ipadx=5, pady=5)
    place_button('3', get_input, (entry, '3'), row=3, column=2, ipadx=5, pady=5)
    place_button('0', get_input, (entry, '0'), row=4, column=0, padx=8, pady=5,
                 columnspan=2, sticky=tkinter.E + tkinter.W + tkinter.N + tkinter.S)
    place_button('.', get_input, (entry, '.'), row=4, column=2, ipadx=7, padx=5, pady=5)
 
    # 运算输入类按钮(只是背景色不同)
    # 字符大小('+','-'宽度不一样,使用ipadx进行修正)
    place_button('+', get_input, (entry, '+'), bg=math_sign_bg, row=1, column=3, ipadx=5, pady=5)
    place_button('-', get_input, (entry, '-'), bg=math_sign_bg, row=2, column=3, ipadx=5, pady=5)
    place_button('*', get_input, (entry, '*'), bg=math_sign_bg, row=3, column=3, ipadx=5, pady=5)
    place_button('/', get_input, (entry, '/'), bg=math_sign_bg, row=4, column=3, ipadx=5, pady=5)
 
    # 功能输入类按钮(背景色、触发功能不同)
    place_button('<-', backspace, (entry,), row=5, column=0, ipadx=5, padx=5, pady=5)
    place_button('C', clear, (entry,), row=5, column=1, pady=5, ipadx=5)
    place_button('=', calc, (entry,), bg=cal_output_bg, row=5, column=2, ipadx=5, padx=5, pady=5,
                 columnspan=2, sticky=tkinter.E + tkinter.W + tkinter.N + tkinter.S)
 
    root.mainloop()
 

二、代码逐段精讲

2.1导入模块

import tkinter
from functools import partial

2.2 输入验证——防止表达式错误

def get_input(entry, argu):
    input_data = entry.get()
    if (input_data[-1:] == '+') and (argu == '+'):
        return
    if (input_data[-2:] == '+-') and (argu == '-'):
        return
    # ... 更多验证

这段代码防止用户输入类似 1++2、1--3、1**2 这样的非法表达式。虽然 eval() 最终也会报错,但提前拦截能让用户体验更好。

注意:负数输入是一个特例。比如用户想输入 -5,代码中 input_data[-2:] == '+-' 配合 argu == '-' 会拦截掉,所以负数需要在数字前直接输入 -(比如 -5+3)。这里为了保持简单,做了折中处理。

2.3 计算核心——eval()的妙用

output_data = str(eval(input_data))

eval() 是Python内置函数,可以把字符串当作表达式来执行。比如 eval("1+2*3") 会返回 7。用它来做计算器核心,代码非常精简。

安全提醒:eval() 虽然方便,但如果程序用于网络环境,会有安全风险。但这里只是本地桌面应用,完全不用担心。

三、异常捕获——防止程序崩溃

try: output_data = str(eval(input_data)) except Exception: entry.insert("end", "Calculation error")

如果用户输入了非法表达式(比如 1/0 或空字符串),程序会捕获异常并在界面显示 "Calculation error",而不是直接崩溃。

3.1批量创建按钮——partial的妙用

def place_button(text, func, func_params, bg=button_bg, **place_params):
    my_button = partial(tkinter.Button, root, bg=bg, padx=10, pady=3,
                       activebackground=button_active_bg)
    button = my_button(text=text, command=lambda: func(*func_params))
    button.grid(**place_params)

partial 相当于“预制”了一个按钮模板,每次调用时只需要传入不同的 text 和 command 参数即可。这样避免了写几十行重复的 tkinter.Button 代码,非常优雅。

3.2 运行界面截图

四、测试用例

输入预期结果
1+23
10-55
2*36
6/23.0
1+2*37(遵循运算符优先级)
(1+2)*39(支持括号)
10/0Calculation error(除零错误)
空输入点击=无反应

常见问题

1. 如何更换皮肤颜色?

代码顶部定义了配色变量,直接修改即可:

button_bg = '#d47655'        # 数字按钮 → 橙色
math_sign_bg = '#ae9aab'    # 运算符按钮 → 紫色
cal_output_bg = '#417ca9'   # 等号按钮 → 蓝色

你可以去 颜色选择器 挑选自己喜欢的十六进制颜色值替换。

2. 如何添加键盘快捷键?

在 root 上绑定键盘事件:

root.bind('<Return>', lambda e: calc(entry))   # 回车键触发计算
root.bind('<BackSpace>', lambda e: backspace(entry))  # 退格键

3. 如何限制输入长度?

在 get_input 函数开头添加:

if len(entry.get()) >= 15:
    return

4. 如何改成科学计算器?

在 calc 函数中导入 math 模块,并在 eval 前将 math 的命名空间传入:

import math
output_data = str(eval(input_data, {"__builtins__": None}, {"sqrt": math.sqrt, "sin": math.sin}))

这样用户就可以输入 sqrt(16) 或 sin(30) 了。

总结

通过不到 100 行代码,我们用 Python 自带的 Tkinter 库实现了一个功能完整、界面美观、可自定义皮肤的计算器程序。它涵盖了:

这是一个非常适合 Python 初学者的练手项目。你可以在此基础上继续扩展,加入更多功能,把它变成属于自己的工具。

到此这篇关于Python基于Tkinter打造高颜值计算器的完整教学的文章就介绍到这了,更多相关Python计算器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文