课程:《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
self.entry.get() # 获取exp =“1234+1233”
pattern = r"\+|\-|\*|\/"
, 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”
True #标记为已完成计算
## 3. 实验过程中遇到的问题和解决过程
- 问题1:这段图形界面的程序对目前来说还是很难懂,对窗口类中各方法不理解
- 问题1解决方案:
拆分,分段考虑它的用途,先完成文本框的出现,再完成内容的显示、追加、调取等操作
实现单个按钮的信息输出,利用frame框架完成排列
self.entry = tkinter.Entry(self.input_frame, width=14, font=("微软雅黑", 20), textvariable=self.content)完成了输入内容的显示
(实在看不懂的选择接受)
- 问题2:对列表操作不熟练,我意识到按键的设置可以用循环完成,具体的按键名称可存入列表,等待后续改进
- 问题2解决方案:处理中
## 其他(感悟、思考等)
还要不断练习、学习新的知识,温故知新