文章目录
- 结果展示
- PSP表格
- 核心代码
- 设计过程
- 改进方案
- 单元测试
- 实验心得
作业要求
项目源码
源代码如下:
import tkinter as tk
'''布局'''
#初始界面定义
root = tk.Tk()
root.title('简易计算器')
root.geometry('350x460+130+130')
root.attributes("-alpha", 0.95)
root["background"] = "#fffaf0"
font=('宋体',20)
font_16=('宋体',16)
#对0排版
result_num = tk.StringVar()
result_num.set('')
tk.Label(root,textvariable=result_num,font=font,height=4,width=20,justify=tk.LEFT,anchor=tk.SE).grid(row=1,column=1,columnspan=4)
#第一行按键
button_clear = tk.Button(root,text='C',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_back = tk.Button(root,text='←',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_pingfang = tk.Button(root,text='^',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_genhao = tk.Button(root,text='√',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_clear.grid(row=2,column=1,padx=3,pady=2)
button_back.grid(row=2,column=2,padx=3,pady=2)
button_pingfang.grid(row=2,column=3,padx=3,pady=2)
button_genhao.grid(row=2,column=4,padx=3,pady=2)
#第二行按键
button_leftkuo = tk.Button(root,text='(',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_rightkuo = tk.Button(root,text=')',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_division = tk.Button(root,text='/',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_mutiplication = tk.Button(root,text='*',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_leftkuo.grid(row=3,column=1,padx=3,pady=2)
button_rightkuo.grid(row=3,column=2,padx=3,pady=2)
button_division.grid(row=3,column=3,padx=3,pady=2)
button_mutiplication.grid(row=3,column=4,padx=3,pady=2)
#第三行按键
button_seven = tk.Button(root,text='7',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_eight = tk.Button(root,text='8',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_nine = tk.Button(root,text='9',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_add = tk.Button(root,text='+',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_seven.grid(row=4,column=1,padx=3,pady=2)
button_eight.grid(row=4,column=2,padx=3,pady=2)
button_nine.grid(row=4,column=3,padx=3,pady=2)
button_add.grid(row=4,column=4,padx=3,pady=2)
#第四行按键
button_four = tk.Button(root,text='4',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_five = tk.Button(root,text='5',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_six = tk.Button(root,text='6',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_sub = tk.Button(root,text='-',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_four.grid(row=5,column=1,padx=3,pady=2)
button_five.grid(row=5,column=2,padx=3,pady=2)
button_six.grid(row=5,column=3,padx=3,pady=2)
button_sub.grid(row=5,column=4,padx=3,pady=2)
#第四行按键
button_one = tk.Button(root,text='1',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_two = tk.Button(root,text='2',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_three = tk.Button(root,text='3',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_equal = tk.Button(root,text='=',width=5,height=3,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_one.grid(row=6,column=1,padx=3,pady=2)
button_two.grid(row=6,column=2,padx=3,pady=2)
button_three.grid(row=6,column=3,padx=3,pady=2)
button_equal.grid(row=6,column=4,padx=3,pady=2,rowspan=2)
#第五行按键
button_zero = tk.Button(root,text='0',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_douhao = tk.Button(root,text=',',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_dot = tk.Button(root,text='.',width=5,font=font_16, relief=tk.FLAT,bg='#ffe4e1')
button_zero.grid(row=7,column=1,padx=3,pady=2)
button_dot.grid(row=7,column=2,padx=3,pady=2)
button_douhao.grid(row=7,column=3,padx=3,pady=2)
'''点击事件'''
def click_button(x):
result_num.set(result_num.get() + x)
def calculation():
opt_str = result_num.get()
result = eval(opt_str)
result_num.set(str(result))
def deback():
i = 0
str2=''
list1=list(result_num.get())
len1=len(list1)-1
for i in range(len1):
str2=str2+str(list1[i])
result_num.set(str2)
def delete():
result_num.set('')
button_one.config(command=lambda :click_button('1'))
button_two.config(command=lambda :click_button('2'))
button_three.config(command=lambda :click_button('3'))
button_four.config(command=lambda :click_button('4'))
button_five.config(command=lambda :click_button('5'))
button_six.config(command=lambda :click_button('6'))
button_seven.config(command=lambda :click_button('7'))
button_eight.config(command=lambda :click_button('8'))
button_nine.config(command=lambda :click_button('9'))
button_zero.config(command=lambda :click_button('0'))
button_add.config(command=lambda :click_button('+'))
button_sub.config(command=lambda :click_button('-'))
button_pingfang.config(command=lambda :click_button('**'))
button_genhao.config(command=lambda :click_button('pow('))
button_leftkuo.config(command=lambda :click_button('('))
button_rightkuo.config(command=lambda :click_button(')'))
button_mutiplication.config(command=lambda :click_button('*'))
button_division.config(command=lambda :click_button('/'))
button_dot.config(command=lambda :click_button('.'))
button_douhao.config(command=lambda :click_button(','))
button_equal.config(command=calculation)
button_clear.config(command=delete)
button_back.config(command=deback)
root.mainloop()
0.界面及功能展示
简易计算器功能展示
目前本人能力只够做简易计算器
1.PSP表格
步骤 | 预估耗时(min) | 实际耗时(min) |
设计思考 | 20 | 30 |
布局开发 | 50 | 60 |
逻辑开发 | 40 | 60 |
实际编码 | 200 | 250 |
实例检测 | 30 | 25 |
改进方案 | 100 | 120 |
2.解题思路
1.编程语言选择与界面:
python在GUI图形用户界面的开发方面提供了丰富的库支持,例如tkinter,PyQt等等,为用户开发提供便利,利用python的tkinter库,利用其grid等布局管理器来实现布局的工整性
2.核心功能:
Python是一门通用编程语言,可以轻松处理计算器的核心功能,包括接收用户输入、执行计算、显示结果等,使用Python来实现基本的四则运算以及科学计算功能,如开方、取余、幂运算等,非常方便,Python的字符串处理功能强大,可以轻松处理用户输入的表达式,进行计算,并生成结果,这里由于个人能力有限并不能很好的复现计算器的全部功能
3.核心代码
对初始输入的数字排版,使其显示在右下角并按序输出
result_num = tk.StringVar()
result_num.set('')
tk.Label(root,textvariable=result_num,font=font,height=4,width=20,justify=tk.LEFT,anchor=tk.SE).grid(row=1,column=1,columnspan=4)
对字符串的具体处理,包括back删去一个字符以免用户清空所有元素的麻烦,点击等号自动读取并执行计算
'''点击事件'''
def click_button(x):
result_num.set(result_num.get() + x)
def calculation():
opt_str = result_num.get()
result = eval(opt_str)
result_num.set(str(result))
def deback():
i = 0
str2=''
list1=list(result_num.get())
len1=len(list1)-1
for i in range(len1):
str2=str2+str(list1[i])
result_num.set(str2)
def delete():
result_num.set('')
4.设计过程
导入tkinter库,通过定义一个名为Calculator的类,实现了计算器的功能和界面。用tk.Button功能实现对按键位置大小等参数信息的调整,通过grid操作实现按键位置间隔的排版,例如:
button_clear = tk.Button(root,text='C',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_back = tk.Button(root,text='←',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_pingfang = tk.Button(root,text='^',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_genhao = tk.Button(root,text='√',width=5,font=font_16, relief=tk.FLAT,bg='#b1b2b2')
button_clear.grid(row=2,column=1,padx=3,pady=2)
button_back.grid(row=2,column=2,padx=3,pady=2)
button_pingfang.grid(row=2,column=3,padx=3,pady=2)
button_genhao.grid(row=2,column=4,padx=3,pady=2)
通过config操作引用函数实现具体计算功能,例如:
button_division.config(command=lambda :click_button('/'))
button_dot.config(command=lambda :click_button('.'))
button_douhao.config(command=lambda :click_button(','))
button_equal.config(command=calculation)
button_clear.config(command=delete)
button_back.config(command=deback)
而核心区代码已经展示如上,这里不再赘述
5.性能改进方案:
1.加入try…except块捕获可能的异常,提高检验性和修改方便度
2.导入math库以实现一些比较常见的数学功能,例如sin,cos等
3.结果一致保留定长浮点数以加强精确性和可读性
4.对于按键等布局的精细化处理
6.单元测试
对计算器的部分运算进行测试
测试代码
import unittest
import tkinter as tk
from tkinter import Entry, Button
# 导入你的应用主文件中的函数或类,这里是一个假设的导入方式
# from your_application import click_button, calculation, deback, delete
class TestCalculator(unittest.TestCase):
def setUp(self):
self.root = tk.Tk()
self.entry = Entry(self.root, textvariable=tk.StringVar())
self.entry.grid(row=1, column=1)
self.app = Application(self.root, self.entry) # 假设你有一个Application类
def test_addition(self):
self.app.click_button('1')
self.app.click_button('+')
self.app.click_button('2')
self.app.calculation()
self.assertEqual(self.app.result_num.get(), '3') # 检查是否正确计算
def test_subtraction(self):
self.app.click_button('5')
self.app.click_button('-')
self.app.click_button('3')
self.app.calculation()
self.assertEqual(self.app.result_num.get(), '2') # 检查是否正确计算
# 继续编写其他测试用例,覆盖更多功能
def tearDown(self):
self.root.destroy()
if __name__ == '__main__':
unittest.main()
7.实验心得
通过本次实验,我熟悉了python利用tkinter库来进行图形布局和逻辑编写,对初步开发有了一定的理解,这次计算器的功能还没有开发的很好,但是我会在未来继续做出改进