作者:小5聊基础
简介:一只喜欢全栈方向的程序员,欢迎咨询,尽绵薄之力答疑解惑
编程原则:Write Less Do More
- 效果如下
【开发信息】
1)python版本:3.6
2)开发工具:VS 2017
3)操作系统:windows11
【题目信息】
- 实现一个小程序,有如下功能
1)随机出题(30以内整数加减乘除法的算术题)<br/>
2)判题,<br/>
3)打分,<br/>
- 要求如下
1)使用tkinter库绘制界面 <br/>
绘制生成图形界面窗口,高宽度大小为800x600 <br/>
2)界面元素 <br/>
若干标签控件Label、<br/>
若干文本框控件Entry、<br/>
三个命令按钮控件Button、<br/>
以及其他个性化控件元素,根据自己觉得不错的控件<br/>
3)标签、文本框、按钮<br/>
label_name=姓名(标签),input_name=请输入姓名(文本框)<br/>
label_no=学号(标签),input_no=请输入学号(文本框)<br/>
label_questionId=题号(标签)<br/>
label_question_num=题目数字(标签)<br/>
label_operator=运算符+-* /(标签) <br/>
label_equal=等号(标签)<br/>
label_result=结果(文本框)<br/>
button_random=随机生成试题(按钮)<br/>
button_confirm=提交(按钮)<br/>
button_answer=查看答案(按钮)<br/>
4)随机生成10个题目,且是简单的单步运算题目,如下<br/>
比如:5+8=__ 7-3=__ 2 * 4=__ 5÷2=__ <br/>
注:除法结果为整数即可 <br/>
- 程序流程
1)学生在界面上输入自己的姓名、学号信息 <br/>
使用字典学号和姓名键值对保存多组数据,点击随机生成试题按钮时判断是否存在当前输入的学社会功能信息 <br/>
如果输入信息为空,那么使用messagebox弹出提示信息:“请注意:姓名或学号不能为空” <br/>
如果存在学生信息,那么自动生成10道简单的加减乘除运算题目,否则弹出对话框窗口提示“姓名或学号有误,请重新输入!” <br/>
2)学生在每个题目对应的文本框中输入对应答案 <br/>
3)答题结束之后,点击提交按钮,页面给出学生的测试成绩(成绩为百分制) <br/>
4)最后,可以点击查看答案按钮,查看本次测试的正确答案 <br/>
注意:在提交按钮按下之前,查看答案按钮应该是灰色、不可用的状态。或者,如果没有做完全部题目就点击查看答案按钮,则自动提交现有题目,并显示分数 <br/>
5)当点击提交按钮时,根据实际答案情况给出成绩,并将本次测试页面的全部基础信息(含:学生信息/题目/结果/成绩等),存入磁盘文件【学生姓名-学生学号.txt】;多次运行此程序测试、做题,磁盘文件根据测试时间,内容应能顺序记录追加(可正序,也可逆序);【注意:文件中不能只有最后一次的测试信息记录】
6)设计窗口中各种元素的布局
【tkinter库信息】
1)tkinter是python自带的GUI界面模块 <br/>
2)导入模块 <br/>import tkinter as tk
<br/>
as后面的是别名,和sql字段as别名一样 <br/>
3)使用TK方法创建一个窗口 <br/>main_windows = tk.Tk()
<br/>
还需要添加一个主方法才能显示 <br/>main_windows.mainloop()
<br/>
4)设置标题 <br/>
必须再主方法之前 <br/>main_windows.title('计算器')
5)设置长宽以及窗口坐标 <br/>
【有趣知识点】
1)方法外定义变量,在方法内赋值,结果值不变<br/>
以下代码value值不变,还是2<br/>
value=2
def test():
value=value*10
- 解决方法
在方法内,使用global关键词声明<br/>global value
<br/>
【完整代码】
可以根据需求情况,精简代码
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# 2022.06.08 11:23
import tkinter as tk
from tkinter import *
from tkinter import messagebox
import random as rd
import math
my_name = ''
my_no = ''
entry_no_value = ''
entry_name_value = ''
my_info={
"my_no":"",
"my_name":"",
"my_score":0,
"answer":{},
"my_answer":{}
}
operator=['+','-','*','÷']
student_info = [{'no':1,'name': '张三'},{'no':2,'name': '李四'},{'no':3,'name': '王五'}]
# 随机生成试题 - 点击事件
def randomCreateQuestion():
my_no = entry_no_value.get()
my_name = entry_name_value.get()
my_info['my_no']=my_no
my_info["my_name"]=my_name
flag = 0
for item in student_info:
if str(item['no']) == my_no and item['name'] == my_name:
flag = 1
break
if my_no.strip() == '' and my_name.strip() == '':
messagebox.askyesno("温馨提示","请注意:姓名或学号不能为空!", icon='info', default='no')
elif flag == 0:
messagebox.askyesno("温馨提示","姓名或学号有误,请重新输入!", icon='info', default='no')
else:
button_random.config(state=tk.DISABLED)
createQuestion()
mw = tk.Tk()
# 创建窗口
def createWindows():
mw.title('简单运算试题') # 设置标题
mw.geometry("800x600") # 绘制窗口的长宽
createWindows()
# 创建学号 - 标签和输入文本框
def createNoLabelEntry():
global entry_no_value
label_no = tk.Label(mw, text="学号:")
label_no.place(x=100,y=100)
entry_no_value = _entry_no_value = StringVar()
entry_no = tk.Entry(mw, bd =1,textvariable=_entry_no_value)
entry_no.place(x=140,y=100)
createNoLabelEntry()
# 创建姓名标签和输入文本框
def createNameLabelEntry():
global entry_name_value
label_name = tk.Label(mw, text="姓名:")
label_name.place(x=100,y=130)
entry_name_value = _entry_name_value = StringVar()
entry_name = tk.Entry(mw, bd =1,textvariable=_entry_name_value)
entry_name.place(x=140,y=130)
createNameLabelEntry()
# 随机生成试题 - 按钮
button_random={}
def createRandomButton():
global button_random
button_random=_button_random = tk.Button(mw, text="随机生成试题",command=randomCreateQuestion)
_button_random.place(x=140,y=160)
createRandomButton()
# 提交 - 按钮
confirm_button={}
def createConfirmButton():
global confirm_button
button = tk.Button(mw, text="提交",command=getScore)
button.place(x=100,y=190+10*30,w=60)
confirm_button=button
# 计算成绩
def getScore():
index=0
my_score=0
for value in answer:
_v=my_answer[index].get()
if _v=='':
continue
my_value=int(_v)
index+=1
if value==my_value:
my_score+=10 # 回答正确一题加10分
else:
continue
my_info["my_score"]=my_score
confirm_button.config(state=tk.DISABLED) # 提交按钮不可点击状态
answer_button.config(state=tk.ACTIVE) # 查看按钮可点击状态
button_random.config(state=tk.ACTIVE) # 随机生成试题
testScoreLabel() # 显示成绩
writeTxt() # 将本次信息写入到txt
# 测试成绩 - 标签
def testScoreLabel():
label = tk.Label(mw, text="您的本次测试成绩为:%s" % my_info["my_score"])
label.place(x=100,y=200+11*30)
# 按钮 - 查看答案
answer_button={}
def createAnswerButton():
global answer_button
button = tk.Button(mw, text="查看答案",command=displayAnswer)
button.place(x=180,y=190+10*30,w=60)
button.config(state=tk.DISABLED)
answer_button=button
# 标签 - 显示答案
def displayAnswer():
index=0
for value in answer:
color='#f60'
_v=my_answer[index].get()
if _v!='':
my_value=int(_v)
if value==my_value:
color='#099dff'
label = tk.Label(mw, text="%s" % str(value),fg=color)
label.place(x=300,y=190+index*30)
index+=1
answer_button.config(state=tk.DISABLED) # 查看答案按钮不可点击状态
# 输出信息到txt
def writeTxt():
file_name='%s/%s-%s.txt' % ("calculator",my_info['my_name'],my_info['my_no'])
with open(file_name, 'a', newline='') as write_f:
write_f.write('学号:%s\n姓名:%s\n本次测试成绩:%s\n' % (my_info["my_no"],my_info["my_name"],str(my_info['my_score'])))
index=0
my_score=0
for value in answer:
line_str='[%s]、%s' % (str(index+1),my_info["question"][index])
_v=my_answer[index].get()
if _v!='':
my_value=int(_v)
if value==my_value:
color='#099dff'
line_str+=' %s (%s)' % (my_value,value)
else:
line_str+=' %s (%s)' % ('',value)
index+=1
write_f.write('%s\n' % (line_str))
write_f.write('\n')
# 循环生成10道试题
answer=[]
question=[]
my_answer=[]
def createQuestion():
answer.clear();
my_answer.clear();
max_num=30 # 最大整数30
max_count=10 # 10道题目
unit_value=30 # 控件之间的间距
for index in range(max_count):
# 题号 - 标签
new_str="[%s]、" % (str(index+1))
label = tk.Label(mw, text=new_str)
label.place(x=100,y=190+index*unit_value)
# 题目数字和运算符 - 标签
left_num=math.floor(rd.random()*30)+1
right_num=math.floor(rd.random()*30)+1
operator_index=math.floor(rd.random()*4)
operator_index=math.floor(rd.random()*4)
operator_value=operator[operator_index]
new_str="%-5s%-5s%-5s = " % (str(left_num),str(operator_value),str(right_num))
question.append(new_str)
label_q = tk.Label(mw, text=new_str)
label_q.place(x=130,y=190+index*unit_value)
if operator_index==0:
answer.append(left_num+right_num)
elif operator_index==1:
answer.append(left_num-right_num)
elif operator_index==2:
answer.append(left_num*right_num)
elif operator_index==3:
answer.append(math.floor(left_num/right_num))
# 答案 - 文本框
entry_answer_value = StringVar()
my_answer.append(entry_answer_value)
entry_answer = tk.Entry(mw, bd =1,textvariable=entry_answer_value)
entry_answer.place(x=240,y=190+index*unit_value,w=50)
my_info["answer"]=answer
my_info["question"]=question
my_info["my_answer"]=my_answer
# 创建提交和查看答案按钮
createConfirmButton()
createAnswerButton()
mw.mainloop()