课程:《Python程序设计》
班级: 1921
姓名: 刘廷奇
学号:20192103
实验教师:王志强
实验日期:2021年4月28日
必修/选修: 公选课
## 一 . 实验内容
-
设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善。
- 考核基本语法、判定语句、循环语句、逻辑运算等知识点
## 二 . 实验过程及结果
- 为了使计算器更具符合日常的使用习惯,依据GUI教程设计了简单的计算器的界面
- 编辑计算功能的函数
- 双目运算+ - * /
- 单目运算sin cos tan cot
具体实现:
1、定义窗体类,类中包含窗体的构造方法、输入组件、按钮组件以及计算部分4个方法
1 class MainForm: # 定义窗体类 2 3 def __init__(self): # 构造方法里面进行窗体的控制 4 5 def input_frame(self): # ..定义输入组件 6 7 def button_frame(self): # 定义按纽组计算部分 8 9 def button_handle(self, event): # 计算部分
(1)窗体的构造方法
1 def __init__(self): # 构造方法里面进行窗体的控制 2 self.root = tkinter.Tk() # 创建一个窗体 3 self.root.title("简易计算器") # 设置标题 4 self.root.iconbitmap(LOGO_PATH) # 设置logo的资源 5 self.root.geometry("231x345") # 设置初始化尺寸,小写字母"x" 6 self.root.maxsize(1000, 400) # 设置窗体的最大尺寸 7 self.root["background"] = "White" 8 self.input_frame() # 显示输入组件 9 self.button_frame() # 显示按钮组件 10 self.root.mainloop() # 显示窗体
(2)窗体的输入组件
1 def input_frame(self): # ..定义输入组性 2 self.input_frame = tkinter.Frame(self.root, width=20) # 创建一个内部容器 3 self.content = tkinter.StringVar() # 标签的显示 4 # 此时不是多行输入内容,而是使用单行输入,所以应该使用Entry组件 5 self.entry = tkinter.Entry(self.input_frame, width=14, font=("微软雅黑", 20), textvariable=self.content) 6 self.entry.pack(fill="x", expand=1) 7 self.clean = False # 清除标记,每一次计算完成之后清险 9 self.input_frame.pack(side="top")
(3)窗体的按钮组件
1 def button_frame(self): # 定义按纽组 2 self.button_frame = tkinter.Frame(self.root, width=50) # 创建一个Frame 3 self.button_list = [[], [], [], [], []] # 一共定义了5组组件 4 self.button_list[0].append(tkinter.Button(self.button_frame, text="1", fg="black", width=3, font=("微软雅黑", 20))) 5 self.button_list[0].append(tkinter.Button(self.button_frame, text="2", fg="black", width=3, font=("微软雅黑", 20))) 6 self.button_list[0].append(tkinter.Button(self.button_frame, text="3", fg="black", width=3, font=("微软雅黑", 20))) 7 self.button_list[0].append(tkinter.Button(self.button_frame, text="+", fg="black", width=3, font=("微软雅黑", 20))) 8 self.button_list[1].append(tkinter.Button(self.button_frame, text="4", fg="black", width=3, font=("微软雅黑", 20))) 9 self.button_list[1].append(tkinter.Button(self.button_frame, text="5", fg="black", width=3, font=("微软雅黑", 20))) 10 self.button_list[1].append(tkinter.Button(self.button_frame, text="6", fg="black", width=3, font=("微软雅黑", 20))) 11 self.button_list[1].append(tkinter.Button(self.button_frame, text="-", fg="black", width=3, font=("微软雅黑", 20))) 12 self.button_list[2].append(tkinter.Button(self.button_frame, text="7", fg="black", width=3, font=("微软雅黑", 20))) 13 self.button_list[2].append(tkinter.Button(self.button_frame, text="8", fg="black", width=3, font=("微软雅黑", 20))) 14 self.button_list[2].append(tkinter.Button(self.button_frame, text="9", fg="black", width=3, font=("微软雅黑", 20))) 15 self.button_list[2].append(tkinter.Button(self.button_frame, text="*", fg="black", width=3, font=("微软雅黑", 20))) 16 self.button_list[3].append(tkinter.Button(self.button_frame, text="0", fg="black", width=3, font=("微软雅黑", 20))) 17 self.button_list[3].append(tkinter.Button(self.button_frame, text=".", fg="black", width=3, font=("微软雅黑", 20))) 18 self.button_list[3].append(tkinter.Button(self.button_frame, text="=", fg="black", width=3, font=("微软雅黑", 20))) 19 self.button_list[3].append(tkinter.Button(self.button_frame, text="/", fg="black", width=3, font=("微软雅黑", 20))) 20 self.button_list[4].append( 21 tkinter.Button(self.button_frame, text="sin", fg="black", width=3, font=("微软雅黑", 20))) 22 self.button_list[4].append( 23 tkinter.Button(self.button_frame, text="cos", fg="black", width=3, font=("微软雅黑", 20))) 24 self.button_list[4].append( 25 tkinter.Button(self.button_frame, text="tan", fg="black", width=3, font=("微软雅黑", 20))) 26 self.button_list[4].append( 27 tkinter.Button(self.button_frame, text="cot", fg="black", width=3, font=("微软雅黑", 20))) 28 self.row = 0 # 进行行数的控制 29 for group in self.button_list: 30 self.column = 0 # 进行列的控制 31 for button in group: 32 button.bind("<Button-1>", lambda event: self.button_handle(event)) # 绑定事件 33 button.grid(row=self.row, column=self.column) 34 self.column += 1 # 每一次修改布局的列数 35 self.row += 1 # 修改布局行数 36 self.button_frame.pack(side="bottom")
(4)窗体的计算部分
前三部分主要依据教程框架实现,计算部分我使用了课程中的判定语句、正则表达式、输入输出等功能。
计算部分流程如下:
1 def button_handle(self, event): 2 oper = event.widget["text"] 3 if self.clean: 4 self.content.set("") 5 self.clean = False 6 if oper != "=": 7 self.entry.insert("end", oper) 8 if oper == "=": 9 result = 0 10 exp = self.entry.get() 11 pattern = r"\+|\-|\*|\/" 12 nums = re.split(pattern, exp) 13 print(nums) 14 flag = re.findall(pattern, exp)[0] 15 self.content.set("") 16 if flag == "+": 17 result = float(nums[0]) + float(nums[1]) 18 elif flag == "-": 19 result = float(nums[0]) - float(nums[1]) 20 elif flag == "*": 21 result = float(nums[0]) * float(nums[1]) 22 elif flag == "/": 23 result = float(nums[0]) / float(nums[1]) 24 self.entry.insert("end", "=%s" % result) 25 self.clean = True 26 if oper == "sin": 27 result = 0 28 exp = self.entry.get() 29 pattern = r"sin|cos|tan|cot" 30 nums = re.split(pattern, exp) 31 print(nums) 32 flag = re.findall(pattern, exp)[0] 33 result = math.sin(float(nums[0])) 34 self.content.set("") 35 self.entry.insert("end", "=%s" % result) 36 self.clean = True 37 if oper == "cos": 38 result = 0 39 exp = self.entry.get() 40 pattern = r"sin|cos|tan|cot" 41 nums = re.split(pattern, exp) 42 print(nums) 43 flag = re.findall(pattern, exp)[0] 44 result = math.cos(float(nums[0])) 45 self.content.set("") 46 self.entry.insert("end", "=%s" % result) 47 self.clean = True 48 if oper == "tan": 49 result = 0 50 exp = self.entry.get() 51 pattern = r"sin|cos|tan|cot" 52 nums = re.split(pattern, exp) 53 print(nums) 54 flag = re.findall(pattern, exp)[0] 55 result = math.tan(float(nums[0])) 56 self.content.set("") 57 self.entry.insert("end", "=%s" % result) 58 self.clean = True 59 if oper == "cot": 60 result = 0 61 exp = self.entry.get() 62 pattern = r"sin|cos|tan|cot" 63 nums = re.split(pattern, exp) 64 print(nums) 65 flag = re.findall(pattern, exp)[0] 66 result = math.cot(float(nums[0])) 67 self.content.set("") 68 self.entry.insert("end", "=%s" % result) 69 self.clean = True
以计算加的方法来说明我的实现过程:
oper = event.widget["text"] # 获取当前点击的键值
if self.clean: #如果计算完成后,self.clean会被置为真,实现计算后清零
self.content.set("")
self.clean = False
if oper != "=": # 当点击的不是“=” ,继续显示输入的键值
self.entry.insert("end", oper)
if oper == "=": #当点击了=,执行以下代码,假设之前输入了1234+1233
result = 0
exp = self.entry.get() # 获取exp =“1234+1233”
pattern = r"\+|\-|\*|\/"
nums = re.split(pattern, exp) #去除“+”,得到num=["1234","1233"]
flag = re.findall(pattern, exp)[0] #反向,得到“+”
self.content.set("") # 清空窗口文本框
if flag == "+":
result = float(nums[0]) + float(nums[1])
self.entry.insert("end", "=%s" % result) #输出结果 “=2467”
self.clean = True #标记为已完成计算
## 3. 实验过程中遇到的问题和解决过程
- 问题1:这段图形界面的程序对目前来说还是很难懂,对窗口类中各方法不理解
- 问题1解决方案:
拆分,分段考虑它的用途,先完成文本框的出现,再完成内容的显示、追加、调取等操作
实现单个按钮的信息输出,利用frame框架完成排列
查询某些方法的功能,比如self.entry = tkinter.Entry(self.input_frame, width=14, font=("微软雅黑", 20), textvariable=self.content)完成了输入内容的显示
(实在看不懂的选择接受)
- 问题2:对列表操作不熟练,我意识到按键的设置可以用循环完成,具体的按键名称可存入列表,等待后续改进
- 问题2解决方案:处理中
## 其他(感悟、思考等)
还要不断练习、学习新的知识,温故知新