python GUI界面编程 口算题生成系统
问题描述
口算题生成系统
功能:
(1)口算:题目显示在界面上(除法必须是整除),逐个显示题目,用户通过输入框输入计算结果。系统能实时统计正确率,将错误题目打印到文件里。
(2)生成题目:用户选择生成的题目数量,打印时的列数,运算符的数量,将题目生成到docx文件里。
设计说明
(1)拟设计的功能及实现思路、需要用到的知识
功能(1)的实现思路:
1.初始化窗口和幕布,为窗口命名
2.记录用到的变量,两个整数x、y,以及用到的符号op(+-*/)
3.将x,y,op打印到界面上,并且生成输入框
4.添加按钮,get_num表示生成题目,judge表示判断结果是否正确,print_error表示将所有错误题目打印到文件里
5.为get_num编写函数update_num,随机生成新的x、y、op
6.为judge编写函数judge,判断答案是否正确。由于除法要用整除来判断,而eval表达式判断的是非整除,加了个特判,当op=/时,特判答案是否正确。
7.编写函数save_error,保存错误的题目,在judge函数中使用,如果回答错误,就将错误题目的字符串形式保存到列表
8.记录变量cur_num表示正确题目的数量,sum表示一共回答问题的数量,每次都计算正确率打印到屏幕上
9.为print_error编写函数 output_error(),将错误题目打印到txt文件,一行一个题目。
10.增加键盘操作,用键盘回车代替判断按钮,免去了每次检验结果时需要鼠标操作的麻烦。
功能(2)的实现思路:
1.初始化窗口和幕布,为窗口命名
2.生成输入框和说明文字,统计用户想要生成的题数,用户想要使用操作符的个数,用户打印文件的列数。
3.设计按钮output,表示用户提交意愿
4.编写output_all函数,根据用户意愿获得相关信息
5.根据题目数量生成题目,以字符串格式保存到列表
6.调用docx相关库创建docx文件,判断表格的行数和列数,生成表格
7.从列表中读取信息到文件
8.保存文件到rex.docx
(2)调用库的说明
tkinter:GUI编程的相关库
random:随机数生成的相关库
(3)定义及调用的函数及功能
Tk():创建应用程序主窗口
Frame():创建控件容器,可依附在窗口中
IntVar(),StringVar():初始化变量
.Label():显示变量的标签
set()为变量重新赋值
randint():生成某一范围的随机数
get():获取变量的值
Button():设置按钮
bind():设置键盘快捷键
mainloop():循环
自己定义的函数
update_num() :产生新的题目,即新的随机的x,y和符号
save_error():#保存错误题目
output_error():#打印错误题目到文件
judge(event):判断答案是否正确
output_all():打印所有题目到docx文件
实现代码
功能(1)
# -*- coding: utf-8 -*-
"""
Created on Wed Jun 16 16:49:28 2021
@author: DELL
"""
#导入GUI的包,以及随机数的包
import tkinter as tk
import random
#初始化窗口和幕布
root = tk.Tk()
window = tk.Frame(root, bg ="lightgreen")
window.pack(expand = tk.YES,fill = tk.BOTH)
root.title('口算计算器') #窗口名字
#初始化用到的变量,两个数x,y和符号sym,sym限定在加号和减号之间,可以添加乘除
x = tk.IntVar()
y = tk.IntVar()
sym = tk.StringVar()
#显示变量的标签
tk.Label(window,textvariable =x).grid(row = 0,column = 0)
tk.Label(window,textvariable =sym).grid(row = 0,column = 2,ipadx=10)
tk.Label(window,textvariable =y).grid(row = 0,column = 3,ipadx=10)
lst=[]
symbol = ['+','-','*','/'] # sym符号的池子
flag = 1
sum=0
cur_num=0
#此函数产生新的题目,即新的随机的x,y和符号
def update_num():
global flag
if flag:
flag = 0
x.set(random.randint(10,100))
y.set(random.randint(10,100))
sym.set(symbol[random.randint(0,3)])
else:
flag = 1
x.set(random.randint(10, 100))
y.set(random.randint(10, 100))
sym.set(symbol[random.randint(0,3)])
global sum
sum=sum+1
def save_error():#保存错误题目
c = str(x.get())+sym.get()+str(y.get())+"=\n"
lst.append(c)
def output_error():#打印错误题目到文件
with open('error_题目.txt',mode='w',encoding='utf-8') as tf:
for i in lst:
tf.write(i)
tk.Button(window,text = 'gen_num', width = 10,height = 4,bg = 'blue', command = update_num).grid(row = 5,column = 10,sticky=tk.W)
tk.Button(window,text="print_error",width = 10,height = 4,bg = 'red',command=output_error).grid(row = 7,column = 10,sticky=tk.W)
# 生成输入框
e = tk.Entry(window)
e.grid(row = 0, column = 4)
result = tk.StringVar()
def judge(event):
global cur_num
c = str(x.get())+sym.get()+str(y.get())
if len(e.get()) !=0:
if(sym.get()=='/'):
tx=int(x.get())
ty=int(y.get())
if(tx//ty==int(e.get())):
cur_num=cur_num+1
result.set("回答正确!"+"正确率为:"+str(cur_num/sum))
update_num()
e.delete(0,'end')
else:
result.set("回答错误"+"正确率为:"+str(cur_num/sum))
save_error()
update_num()
e.delete(0, 'end')
else:
if int(e.get()) == eval(c):
cur_num=cur_num+1
result.set("回答正确!"+"正确率为:"+str(cur_num/sum))
update_num()
e.delete(0,'end')
else:
result.set("回答错误"+"正确率为:"+str(cur_num/sum))
save_error()
update_num()
e.delete(0, 'end')
else:
result.set("请输入答案")
#键盘回车按键代替判断按钮,免去了每次检验结果时都需要鼠标操作的麻烦
root.bind('<Return>', judge)
button = tk.Button(window,text="judge",width = 10,height = 4,bg = 'pink')
button.grid(row = 6,column = 10)
button.bind('<Button-1>',judge)
tk.Label(window,textvariable =result).grid(row = 1,column = 0)
#敞口循环必须有
root.mainloop()
功能(2)
# -*- coding: utf-8 -*-
"""
Created on Wed Jun 16 17:35:59 2021
@author: DELL
"""
import tkinter as tk
import random
from docx import Document
root_all = tk.Tk()
window_all = tk.Frame(root_all, bg ="green")
window_all.pack(expand = tk.YES,fill = tk.BOTH)
root_all.title('生成题目') #窗口名字
tk.Label(window_all,text='题目数量:').grid(row=0,column=0)
tk.Label(window_all,text='运算符个数:').grid(row=1,column=0)
tk.Label(window_all,text='打印到文件里的列数:').grid(row=2,column=0)
num = tk.Entry(window_all)
num.grid(row = 0, column = 1)
oper_num=tk.Entry(window_all)
oper_num.grid(row=1,column=1)
col_num=tk.Entry(window_all)
col_num.grid(row=2,column=1)
symbol = ['+','-','*','/']
lst=[]
def output_all():
num_cnt=int(num.get())
oper_cnt=int(oper_num.get())
col_cnt=int(col_num.get())
#print(type(num_cnt))
for i in range(num_cnt):
x=random.randint(10,100)
y=random.randint(10,100)
op=symbol[random.randint(0,oper_cnt-1)]
c = str(x)+op+str(y)+"= "
lst.append(c)
wordfile=Document()
cnt_row=num_cnt//col_cnt
if num_cnt % col_cnt == 0:
cnt_row=cnt_row+1
table=wordfile.add_table(rows=cnt_row,cols=col_cnt,)
row_idx=0
col_idx=0
for i in lst:
table.rows[row_idx].cells[col_idx].text=i
col_idx=col_idx+1
if col_idx == col_cnt :
col_idx=0
row_idx=row_idx+1
wordfile.save("res.docx")
tk.Button(window_all,text="output",width = 10,height = 4,bg = 'orange',command=output_all).grid(row = 8,column = 10,sticky=tk.W)
root_all.mainloop()
参考博客找到了加上