前言:
谢谢丽哥 是真的强 看到来点个赞哦
1 GUI界面编程
1.1 问题描述 选题:口算题生成系统 设计GUI界面实现口算题生成系统,至少包括但不仅限于以下功能。 (1)口算:题目显示在界面上(除法必须是整除),可以一次性显示或逐个显示题目,用户通过输入框输入计算结果。系统能够显示错误题目,统计正确率。 (2)打印:将题目生成到word文档“口算.docx”中。 (3)可以选择口算及打印生成题目的数量,打印时的行和列,运算符的数量。 1.2 设计说明 包括但不限于: (1) 拟设计的功能及实现思路、需要用到的知识 一、项目各模块功能及实现思路: 1.第一模块为标题栏模块,表示欢迎用户来到口算生成系统 实现思路为使用tkinter中的frame盒子模型,然后再套用一个Entry函数,将文本内容放置进去,同时使用grid函数调整样式(配合padx、pady调整宽高边距、使整体看起来整洁舒服。
2.第二模块为菜单栏的“文件” 及 “打印” 其中文件中可以选择关闭填写,则GUI界面消失,或者点击打印按钮,可以出现如下两个功能,打印至word或指定题目打印至word,根据用户需求来进行选择在这里插入图片描述
3.第三模块中为选择答题类型,有加法、减法、乘法、除法、混合题目五种题型,用户可以根据自己的需求选中对应的单选框。可以选中开始生成,则十二道题目会直接全部出现于界面上,若点击逐一生成,则可以一道一道的做,同时每一道都可以切换答题题型,根据自己的不足,做对应的题型,十分利于实际做题当中。
4.第四模块中为用户的答题区域:我一共准备了十二道题目,然后利用grid函数将他们整齐的防止在这个lableFrame当中。其中题目框我使用了label标签,后面的答案框使用了Entry标签。即题目是不可修改的,是后台生成,而答案是自己输入进去的,符合实际开发要求。
5.第五模块中为用户选择打印指定题目,我准备了12个复选框,用户可以根据自己的需求,勾中想要打印的题目,然后在界面左上角点击打印指定题目至word就可以成功打印了。题目的第一行三个题目指定下面的前三个复选框,以此类推,题目的第二行三个题目指定第4-6个复选框,以此类推….
6.第六模块中为用户提交答案模块,用户在答题结束时,可以点击提交答案,系统则会为此评分,将结果计算于接下来的成绩模块(也就是第七模块),后面的考试时间是方便用户掌握答题时间的,当用户点击开始生成按钮时,便会自动生成当前的时间,并累加一个小时为考试时间后显示在页面上。
7.第七模块为成绩栏模块,当用户提交答案后,系统会为此评分,每题10分,一共120分,然后同时也会计算对应的正确率,当点击后面的打印错误报告时,系统会将错误的题目打印至word中。
8.第八模块中为错误题目报告模块,系统会统计错误题目数量,同时把对应错误的题号显示在上面
总体项目截图;
二、项目需要用到的知识 1.项目用到了tkinter库,也是GUI编程最重要的一个库。 以下是我本次大作业在csdn中学习的教程: https://blog.csdn.net/RNG_uzi_/article/details/89792518?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162495353716780265439340%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162495353716780265439340&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-2-89792518.pc_search_result_cache&utm_term=tkinter%E5%BA%93%E7%95%8C%E9%9D%A2%E8%AE%BE%E8%AE%A1&spm=1018.2226.3001.4187 2.其次我用到了python中求质数、合数的知识,因为除法出题必须为整除,所以我的思路是先把100以内所有的合数找出来,然后对每一个合数约分,找到约数就把两个数显示在界面上。 3.用到了大量列表的遍历知识,同时也回顾了上课所讲的列表知识,学会怎么快速遍历列表,可以使用下标遍历:
或者使用遍历或迭代器都是可以的:
(2) 调用库的说明 1.Tkinter库: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中。 GUI 编程就相当于小孩子搭积木,每个积木块应该放在哪里,每个积木块显示为多大,也就是对大小和位置都需要进行管理,而布局管理器正是负责管理各组件的大小和位置的。此外,当用户调整了窗口的大小之后,布局管理器还会自动调整窗口中各组件的大小和位置。 2.datetime类: datetime 类通过 datetime.datetime(year, month, day, hour, minute, second, microsecond, tzinfo) 创建对象,对应对象的属性值通过类似方法取得。
datetime.datetime.now():获取当前时刻的详细时间信息 datetime.datetime.combine(date, time):传入 date 和 time 对象,将两者信息组合生成对应 datetime 对象。 timestamp():将 datetime 对象转换成时间戳对象(浮点数,从 1970-1-1 00:00:00 UTC+0:00 开始计算) 3.Random类:
(3) 定义及调用的函数及功能 本次GUI编程共定义了 函数,
- 其中主函数_main_为整个函数入口,调用run函数
- run函数为GUI界面的框架设计函数,通过Frame和lableFrame设计出整体框架界面后,利用grid函数(类似于前端css调样式的方法)修改整体布局,使页面变得美观。
- 定义了create函数(即题目生成函数),当点击开始生成按钮后,command调用create函数,通过全局变量获取到用户选择的题型后,(利用tk.stringVar中的get方法获取)然后利用Random库生成对应题目后,最终set方法注入到界面上去。其中我一共十二个题目,所以我用了for循环进行依次注入,就不用写上12个set方法了,大大提高页面的代码整洁度,提高代码效率。
- 定义了create2函数(即逐一生成题目函数),与create函数基本为一个思路,但区别在于不是循环依次注入到界面中。我定义了一个全局变量,然后每当我点击逐一生成按钮后,全局int变量就加一,代表我要注入的下一个题目题号,再拼接上我的前缀字符串常量,使用eval函数,最后set方法注入即可。
- 定义了submit函数(题目提交函数),当12道题目全部答完后,便可以点击提交,同时这里我在函数外定义了一个全局变量error_list列表,函数使用global引用,然后对12道题进行遍历,如果答对则答对数量加1,打错则记录错误题目题号,append方法加入至error_list中,并最终显示正确率、错误题目题号等信息
- 定义了Print函数(题目打印函数),先获取到文件,如果没有则创建一个,然后利用get方法获取到12道题目,然后打印流输出到文件中即可。
- 定义了Print2函数(指定题目打印函数),先获取到文件,如果没有则创建一个,然后通过用户选择复选框的题目,打印指定题目到文件中
- 定义了Print3函数(错误题目打印函数),先获取到文件,如果没有则创建一个,然后根据之前系统统计,将用户答错的题目输出到文件中
1.3 实现代码 1.3.1 创建主窗口
1.3.2 页面设计(框架Frame的布局) 1.左上角菜单 Menu
2.从上到下依次框架设计(及grid函数布局):
3.各框架对应实现代码: 标题:
答题类型:
选择打印题目:
答题区域:
提交答案:
成绩报告:
错误题目报告:
最后:
4.create函数(题目全部生成函数详解) 答题类型用了q_type来表示,此函数中引用了这个全局变量(使用global方法)同时利用datetime类获取到当前时间,并用striftime方法设置了指定格式,并且设置了考试时间为一个小时,累加到当前时间并计算出来统一显示在界面上。 然后根据q_type的get方法获取到用户选择的答题类型,生成对应的题目,利用random.randint方法随机生成,然后拼接字符串生成题目,使用eval方法拼接出一个新变量,使用set方法,将题目生成至界面之上。
其中除法我使用了合数找约数,一旦找到便break退出循环,将数据显示在页面上。先将所有合数打表至list列表
5.create2函数(逐一生成函数详解) 与create函数思路基本一致,只不过这里没有用到for循环全部注入到界面上,而是使用了Is_List全局变量,记录我们生成题目到第几个了,然后继续生成下一个。
当题目全部生成完了,再点击逐一生成按钮,系统会弹窗系统提示题目全部生成完了。
6.题目提交函数(submit) 首先用eval方法拼接字符串,再用get方法获取到每道题目及其答案,若答案正确,则正确数量加一,反之将错误题号记录到error_list列表当中,最后提交答案后,显示分数、正确率、错误题号。
7.题目打印函数 首先使用open方法打开对应文件,若文件不存在则创建一个,然后依次获取到对应题目,利用write输出流 输出到文件当中
8.指定题目打印函数(Print2):
9.错误题目打印函数(Print3)
最后是代码:
import sys
import tkinter as tk
import tkinter.messagebox
import pickle
import random
import datetime
window = tk.Tk()
window.title('高翔的口算生成系统')
window.geometry('600x500')
q_type = tk.StringVar()
question1 = tk.StringVar()
question2 = tk.StringVar()
question3 = tk.StringVar()
question4 = tk.StringVar()
question5 = tk.StringVar()
question6 = tk.StringVar()
question7 = tk.StringVar()
question8 = tk.StringVar()
question9 = tk.StringVar()
question10 = tk.StringVar()
question11 = tk.StringVar()
question12 = tk.StringVar()
answer1=tk.StringVar()
answer2=tk.StringVar()
answer3=tk.StringVar()
answer4=tk.StringVar()
answer5=tk.StringVar()
answer6=tk.StringVar()
answer7=tk.StringVar()
answer8=tk.StringVar()
answer9=tk.StringVar()
answer10=tk.StringVar()
answer11=tk.StringVar()
answer12=tk.StringVar()
grade=tk.StringVar()
grades=tk.StringVar()
error=tk.StringVar()
errors=tk.StringVar()
gg1=tk.StringVar()
gg2=tk.StringVar()
gg3=tk.StringVar()
gg4=tk.StringVar()
gg5=tk.StringVar()
gg6=tk.StringVar()
gg7=tk.StringVar()
gg8=tk.StringVar()
gg9=tk.StringVar()
gg10=tk.StringVar()
gg11=tk.StringVar()
gg12=tk.StringVar()
Date=tk.StringVar()
Is_List=1
list = []
for i in range(4, 100):
for j in range(2, i):
if (i % j == 0):
list.append(i)
break
print((list))
def create():
global q_type
Date.set((datetime.datetime.now().strftime("%m-%d %H:%M"))+"考试至"+(datetime.datetime.now()+datetime.timedelta(hours=1)).strftime("%m-%d %H:%M"))
if (q_type.get() == 'jia'):
for i in range(1, 13):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '+' + str(second) + '='
qq = eval("question" + str(i))
qq.set(result)
elif (q_type.get() == 'jian'):
for i in range(1, 13):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '-' + str(second) + '='
qq = eval("question" + str(i))
qq.set(result)
elif (q_type.get() == 'cheng'):
for i in range(1, 13):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '*' + str(second) + '='
qq = eval("question" + str(i))
qq.set(result)
elif (q_type.get() == 'chu'):
for k in range(1, 13):
suiji = random.randint(1, 72)
for i in range(2,list[suiji]):
if list[suiji] % i == 0:
j = list[suiji] / i
break
result = str(list[suiji]) + '/' + '{:g}'.format(j) + '='
qq = eval("question" + str(k))
qq.set(result)
else:
for i in range(1, 5):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '*' + str(second) + '='
qq = eval("question" + str(i))
qq.set(result)
for i in range(5, 10):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '+' + str(second) + '='
qq = eval("question" + str(i))
qq.set(result)
for i in range(10, 13):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '-' + str(second) + '='
qq = eval("question" + str(i))
qq.set(result)
def reply():
tk.messagebox.showwarning(title='提示', message='题目已经全部出完了~')
def create2():
Date.set((datetime.datetime.now().strftime("%m-%d %H:%M"))+"考试至"+(datetime.datetime.now()+datetime.timedelta(hours=1)).strftime("%m-%d %H:%M"))
global Is_List
if(Is_List>12):
reply()
if (q_type.get() == 'jia'):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '+' + str(second) + '='
qq = eval("question" + str(Is_List))
qq.set(result)
Is_List+=1
elif (q_type.get() == 'jian'):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '-' + str(second) + '='
qq = eval("question" + str(Is_List))
qq.set(result)
Is_List += 1
elif (q_type.get() == 'cheng'):
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '*' + str(second) + '='
qq = eval("question" + str(Is_List))
qq.set(result)
Is_List += 1
elif (q_type.get() == 'chu'):
suiji = random.randint(1, 72)
for i in range(2, list[suiji]):
if list[suiji] % i == 0:
j = list[suiji] / i
break
result = str(list[suiji]) + '/' + '{:g}'.format(j) + '='
qq = eval("question" + str(Is_List))
qq.set(result)
else:
first = random.randint(1, 100)
second = random.randint(1, 100)
result = str(first) + '+' + str(second) + '='
qq = eval("question" + str(Is_List))
qq.set(result)
Is_List += 1
right_list=[]
error_list=[]
def submit():
global error_list
error_list.clear()
true=0
for i in range(1,13):
an=eval("answer"+str(i))
qu=eval("question"+str(i))
ans=an.get()
qus=qu.get()
qus_list=qus.split('=')
quse=str(eval(qus_list[0]))
if quse==ans:
true+=1
else:
error_list.append(i)
sum = ''
for i in error_list:
sum = '{} {}'.format(sum, i)
error.set(len(error_list))
errors.set(sum)
grade.set(true*10)
grades.set(str((round(true/12,2))*100)+"%")
def click():
print("点击了一次")
def Print():
file_name='gx的口算习题.docx'
file=open(file_name,'w')
Write=''
for i in range(1,13):
quest=eval("question"+str(i))
Write=quest.get()+'\n'
print(Write)
file.write(Write)
file.close()
def Print2():
file_name = 'gx的指定口算习题.docx'
file = open(file_name, 'w')
Write_str = ''
for i in range(1, 13):
gx = eval("gg" + str(i))
if gx.get()==1:
quest = eval("question" + str(i))
Write_str = quest.get() + '\n'
print(Write_str)
file.write(Write_str)
file.close()
def Print3():
global error_list
file_name = 'gx的错误口算习题报告.docx'
file = open(file_name, 'w')
Write_str = ''
for i in range(13):
if error_list[i]!=0:
Write_str = eval("qustion"+str(error_list[i])).get() + '\n'
file.write(Write_str)
file.close()
menubar = tk.Menu(window)
window.config(menu=menubar)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu2 = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='文件', menu=filemenu)
menubar.add_cascade(label='打印', menu=filemenu2)
filemenu.add_command(label='登录', command=click())
filemenu.add_command(label='关闭填写', command=window.quit)
filemenu2.add_cascade(label="输出word",command=Print)
filemenu2.add_cascade(label="指定题目输出word",command=Print2)
frame1 = tk.Frame(window, bg='MediumTurquoise', bd=4)
frame2 = tk.LabelFrame(window, text='答题类型', padx=5, pady=1, bd=5)
frame5 = tk.Frame(window, bg='LightSkyBlue', bd=40, height=280)
frame8 = tk.LabelFrame(window, text='选择打印题目', pady=1, bg='LightSeaGreen', bd=5)
frame7 = tk.LabelFrame(window, text='提交答案', pady=1, bg='LightGreen', bd=5)
frame4 = tk.LabelFrame(window, text='成绩(共十二题,每题10分 满分120分)', pady=1, bg='LightSeaGreen', bd=5)
frame6 = tk.LabelFrame(window, text='错误报告', pady=5, bg='LightYellow', bd=5)
frame1.grid(row=0, pady=10, sticky=tk.W + tk.E)
frame2.grid(row=1, padx=5, sticky=tk.W)
frame4.grid(row=5, pady=10, sticky=tk.W + tk.E)
frame5.grid(row=2, pady=10, sticky=tk.W + tk.E)
frame6.grid(row=6, pady=10, sticky=tk.W + tk.E)
frame7.grid(row=4, pady=10, sticky=tk.W + tk.E)
frame8.grid(row=3, pady=10, sticky=tk.W+tk.E)
g1 = tk.Checkbutton(frame8, text="1",textvariable=gg1).grid(row=1, column=0, padx=2)
g2 = tk.Checkbutton(frame8, text="2",textvariable=gg2 ).grid(row=1, column=1, padx=2)
g3 = tk.Checkbutton(frame8, text="3",textvariable=gg3 ).grid(row=1, column=2, padx=2)
g4 = tk.Checkbutton(frame8, text="4" ,textvariable=gg4).grid(row=1, column=3, padx=2)
g5 = tk.Checkbutton(frame8, text="5",textvariable=gg5 ).grid(row=1, column=4, padx=2)
g6 = tk.Checkbutton(frame8, text="6" ,textvariable=gg6).grid(row=1, column=5, padx=2)
g7 = tk.Checkbutton(frame8, text="7",textvariable=gg7 ).grid(row=1, column=6, padx=2)
g8 = tk.Checkbutton(frame8, text="8",textvariable=gg8 ).grid(row=1, column=7, padx=2)
g9 = tk.Checkbutton(frame8, text="9" ,textvariable=gg9).grid(row=1, column=8, padx=2)
g10 = tk.Checkbutton(frame8, text="10",textvariable=gg10 ).grid(row=1, column=9, padx=2)
g11 = tk.Checkbutton(frame8, text="11",textvariable=gg11 ).grid(row=1, column=10, padx=2)
g12 = tk.Checkbutton(frame8, text="12",textvariable=gg12 ).grid(row=1, column=11, padx=2)
colors = ['red', 'green', 'light blue', 'yellow']
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question1).grid(row=0, column=0,padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer1).grid(row=0, column=1, padx=5,pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question2).grid(row=0, column=2, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer2).grid(row=0, column=3, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question3).grid(row=0, column=4, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer3).grid(row=0, column=5, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question4).grid(row=1, column=0, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer4).grid(row=1, column=1, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question5).grid(row=1, column=2, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3,bg='White',textvariable=answer5).grid(row=1, column=3, padx=5, pady=10)
tk.Label(frame5, width=10,bg='Honeydew', text='1+3=', textvariable=question6).grid(row=1, column=4, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer6).grid(row=1, column=5, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question7).grid(row=2, column=0, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer7).grid(row=2, column=1, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question8).grid(row=2, column=2, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer8).grid(row=2, column=3, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question9).grid(row=2, column=4, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer9).grid(row=2, column=5, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question10).grid(row=3, column=0, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer10).grid(row=3, column=1, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question11).grid(row=3, column=2, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer11).grid(row=3, column=3, padx=5, pady=10)
tk.Label(frame5, width=10, bg='Honeydew', text='1+3=', textvariable=question12).grid(row=3, column=4, padx=5, pady=10)
tk.Entry(frame5, font="Arial 12", width=3, bg='White',textvariable=answer12).grid(row=3, column=5, padx=5, pady=10)
name1 = tk.Label(frame1, text="欢迎来到口算生成系统", bd=10, font=('Arial 12 bold'), width=15, height=2, bg='MediumTurquoise',
anchor="center")
name1.grid(row=0, column=100, padx=150, sticky=tk.E)
r1 = tk.Radiobutton(frame2, text="混合题目", value="flex", variable=q_type).grid(row=1, column=0, padx=5)
r2 = tk.Radiobutton(frame2, text="加法", value="jia", variable=q_type).grid(row=1, column=1, padx=5)
r3 = tk.Radiobutton(frame2, text="减法", value="jian", variable=q_type).grid(row=1, column=2, padx=5)
r4 = tk.Radiobutton(frame2, text="乘法", value="cheng", variable=q_type).grid(row=1, column=3, padx=5)
r5 = tk.Radiobutton(frame2, text="除法", value="chu", variable=q_type).grid(row=1, column=4, padx=5)
r6 = tk.Button(frame2, text="逐一生成", bg='DeepSkyBlue', command=create2).grid(row=2, column=1, padx=6)
r7 = tk.Button(frame2, text="开始生成", bg='DeepSkyBlue', command=create).grid(row=2, column=2, padx=6)
score = tk.Label(frame4, bg='MintCream', text='成绩:').grid(row=0, column=2, padx=8, pady=2)
score_entry = tk.Entry(frame4, bg='Honeydew', bd=6, width=10, textvariable=grade).grid(row=0, column=3, padx=2)
score2 = tk.Label(frame4, bg='MintCream', text='正确率:').grid(row=0, column=4, padx=8, pady=12)
score2_entry = tk.Entry(frame4, bg='Honeydew', bd=6, width=10, textvariable=grades).grid(row=0, column=5, padx=2)
r7 = tk.Button(frame4, text="打印错误报告", bg='red').grid(row=0, column=6, padx=6)
score = tk.Label(frame6, bg='MintCream', text='错误题目数量:').grid(row=0, column=2, padx=8, pady=2)
score_entry = tk.Entry(frame6, bg='Honeydew', bd=6, width=5,textvariable=error).grid(row=0, column=3, padx=2)
score2 = tk.Label(frame6, bg='MintCream', text='错误题号').grid(row=0, column=4, padx=8, pady=12)
score2_entry = tk.Entry(frame6, bg='Honeydew', bd=6, width=30,textvariable=errors).grid(row=0, column=5, padx=2)
r6 = tk.Button(frame7, text="提交答案", bg='MediumSpringGreen',command=submit).grid(row=0, column=1, padx=6)
time = tk.Label(frame7, bg='MintCream', text='考试时间为:').grid(row=0, column=2, padx=8, pady=12)
time_entry = tk.Label(frame7, bg='Honeydew', bd=6, width=30,textvariable=Date).grid(row=0, column=3, padx=2)
window.mainloop()
结尾: 我的print2和3方法有bug 其他木问题
|