自学了一段时间python~ 在摸爬滚打中算是了解了基本的语法。但感觉这样好像不够,光写一些简短的代码好像不满足。恰逢学习文科的女朋友问我有没有一款类似驾考宝典的app,可以自己导入题库,用来随机抽取题目回答,从而加深记忆。搜了一圈貌似没有特别对胃口的。那为什么不自己写一个呢~
说干就干!首先跟她确定了一下需求。题库中的题型有选择、判断、填空。导入题库后可以自己选择题型与章节,组成一个子题目池。在子题目池中随机抽取题目作答,并且反馈正确与否。
然后大概思考一下整个一套的流程~ 第一步(姑且叫做choose_file环节)先选择一个题库,导入了题库以后,第二步(姑且叫做entry环节)在一个复选框页面选择想要的题型与章节。第三步循环,随机抽取并回答题目。当题目回答完以后第四步(姑且叫做question_empty环节)提示已完成,并回到第二步的选择题型与章节中。
那么就开始吧~ 说明一下,完整代码会在文章的最后贴出来。
首先导入我们需要的库
# /usr/bin/python3
# -*- coding:utf-8 -*-
import tkinter as tk
import tkinter.messagebox as msg
import tkinter.filedialog as fd
from tkinter import *
import json
import random
import os
import sys
先轻微施工一下main函数。定义主窗口,并调用一个choose_file函数来导入我们需要的题库。考虑到后续按钮的command命令仅可输入函数名,对于参数的传入传出不是那么方便,因此考虑对一些原本需要传出的变量用global全局一下。
def choose_file():
global timu_list, whole_chapter_list, whole_qtype_list
file_path = 'NoFileChosed'
while file_path[-5:] != '.json': # 判断文件格式
if file_path == '': # 当没有导入文件时直接退出程序
sys.exit(0)
if file_path != 'NoFileChosed':
msg.showwarning(title='提示', message='请选择json文件!')
default_dir = os.path.split(os.path.realpath(__file__))[0] # 默认路径
file_path = tk.filedialog.askopenfilename(title=u'选择文件', initialdir=(os.path.expanduser(default_dir))) # 在默认路径中打开选择文件对话框
with open(file_path, 'r', encoding='utf-8') as f:
timu_list = json.load(f)
whole_chapter_list = []
whole_qtype_list = []
# 统计该题库总共含有哪些题型和章节
for timu in timu_list:
if timu['chapter'] not in whole_chapter_list:
whole_chapter_list.append(timu['chapter'])
if timu['q_type'] not in whole_qtype_list:
whole_qtype_list.append(timu['q_type'])
main_window = Tk()
main_window.title('背题助手')
main_window.geometry('600x450')
qtype_meaning = ['选择', '填空', '判断']
choose_file()
在这里题库的格式可以根据自己的习惯设定。我个人是先将题库录入成json文件然后导入。追求整体性的朋友可以用正则等方法直接导入word文件分析。
json文件的大致范式如下(仅抽取几道题):
[
{"chapter": "1", "q_type": "1", "content": {"title": "新石器时期,标志着人类开始通过化学变化改变材料特性的创造性活动,也标志着人类手工艺设计阶段的开端的发明是( )。", "opt_a": "瓷器", "opt_b": "青铜器", "opt_c": "陶器", "opt_d": "漆器", "ans": "C"}},
{"chapter": "1", "q_type": "2", "content": {"title": "人类设计活动的历史大体可以划分为三个阶段,即设计的萌芽阶段、手工艺设计阶段和____阶段。", "ans": "工业设计"}},
{"chapter": "4", "q_type": "3", "content": {"title": "英国的机械化首先开始于纺织业。", "ans": "A", "correct": ""}},
{"chapter": "4", "q_type": "3", "content": {"title": "纸张的模数化始于美国。", "ans": "B", "correct": "德国"}}
]
其中chapter代表章节,q_type为题型,1、2、3分别对应选择、填空、判断。content里录入题目具体内容,如题面、选项、答案等信息。
获得这些信息以后,就可以在main函数内继续部署进入页面的一些控件并开始进入mainloop了。
# 续main函数
label_welcome = Label(main_window, text='请选择题型与章节!', font=('宋体', 14, 'bold'), relief='solid')
qtype_checkbutton_list = []
qtype_var_list = []
qtype_chosed_list = []
chapter_checkbutton_list = []
chapter_var_list = []
chapter_chosed_list = []
entry_ok_button = Button(main_window, text='确认', command=entry_out)
all_chapter_button = Button(main_window, text='章节全选', command=entry_out_all_chapter)
for i in range(len(whole_qtype_list)):
qtype_var_list.append(IntVar())
qtype_checkbutton_list.append(Checkbutton(main_window, text=qtype_meaning[int(whole_qtype_list[i]) - 1],
variable=qtype_var_list[i], onvalue=1, offvalue=0))
for i in range(len(whole_chapter_list)):
chapter_var_list.append(IntVar())
chapter_checkbutton_list.append(Checkbutton(main_window, text=shuwei(int(whole_chapter_list[i]), ' ', 2, 'back'),
variable=chapter_var_list[i], onvalue=1, offvalue=0))
entry_in()
main_window.mainloop()
在mainloop之前有一个entry_in函数和一个shuwei函数。entry_in的作用在于将选择页面的控件(包含题型、章节的复选框和两个“下一步”按钮)部署到窗口。代码如下
def entry_in():
label_welcome.place(relwidth=0.5, relheight=0.1, relx=0.25, rely=0.05)
entry_ok_button.place(relwidth=0.15, relheight=0.08, relx=0.25, rely=0.85)
all_chapter_button.place(relwidth=0.15, relheight=0.08, relx=0.6, rely=0.85)
for i in range(len(whole_qtype_list)):
qtype_checkbutton_list[i].place(relwidth=0.2, relx=0.2, rely=0.2 + i * 0.05)
for i in range(len(whole_chapter_list)):
chapter_checkbutton_list[i].place(relwidth=0.2, relx=0.6, rely=0.2 + i * 0.05)
效果就像这样
shuwei函数其实是懒得对不同长度章节编号细致排版,直接拿空格占位达到对其效果。代码如下
def shuwei(num, character, weishu, side):
append_text = ''
for i in range(weishu - len(str(num))):
append_text = append_text + character
if side == 'front':
return append_text + str(num)
elif side == 'back':
return str(num) + append_text
entry界面的两个button“确认”和“章节全选”,分别对应了手动选择题型、章节和手动选择题型以后生成子题目池。对应的command分别是entry_out和entry_out_all_chapter,代码如下
def entry_out():
global chosed_timu
for i in range(len(whole_qtype_list)):
if qtype_var_list[i].get() == 1 and whole_qtype_list[i] not in qtype_chosed_list:
qtype_chosed_list.append(whole_qtype_list[i])
elif qtype_var_list[i].get() == 0 and whole_qtype_list[i] in qtype_chosed_list:
qtype_chosed_list.remove(whole_qtype_list[i])
for i in range(len(whole_chapter_list)):
if chapter_var_list[i].get() == 1 and whole_chapter_list[i] not in chapter_chosed_list:
chapter_chosed_list.append(whole_chapter_list[i])
elif chapter_var_list[i].get() == 0 and whole_chapter_list[i] in chapter_chosed_list:
chapter_chosed_list.remove(whole_chapter_list[i])
if qtype_chosed_list != [] and chapter_chosed_list == []:
msg.showwarning(title='提示', message='请选择章节!')
return
elif chapter_chosed_list != [] and qtype_chosed_list == []:
msg.showwarning(title='提示', message='请选择题型!')
return
elif chapter_chosed_list == [] and qtype_chosed_list == []:
msg.showwarning(title='提示', message='请选择题型和章节!')
return
elif get_question(qtype_chosed_list, chapter_chosed_list) == []:
msg.showwarning(title='提示', message='此种组合无题目!')
return
else:
label_welcome.place_forget()
entry_ok_button.place_forget()
all_chapter_button.place_forget()
for i in range(len(whole_qtype_list)):
qtype_checkbutton_list[i].place_forget()
for i in range(len(whole_chapter_list)):
chapter_checkbutton_list[i].place_forget()
chosed_timu = get_question(qtype_chosed_list, chapter_chosed_list)
random_timu()
def entry_out_all_chapter():
global chosed_timu
for i in range(len(whole_qtype_list)):
if qtype_var_list[i].get() == 1 and whole_qtype_list[i] not in qtype_chosed_list:
qtype_chosed_list.append(whole_qtype_list[i])
elif qtype_var_list[i].get() == 0 and whole_qtype_list[i] in qtype_chosed_list:
qtype_chosed_list.remove(whole_qtype_list[i])
chapter_chosed_list = whole_chapter_list
if qtype_chosed_list == []:
msg.showwarning(title='提示', message='请选择题型!')
return
elif get_question(qtype_chosed_list, chapter_chosed_list) == []:
msg.showwarning(title='提示', message='此种组合无题目!')
return
else:
label_welcome.place_forget()
entry_ok_button.place_forget()
all_chapter_button.place_forget()
for i in range(len(whole_qtype_list)):
qtype_checkbutton_list[i].place_forget()
for i in range(len(whole_chapter_list)):
chapter_checkbutton_list[i].place_forget()
chosed_timu = get_question(qtype_chosed_list, chapter_chosed_list)
random_timu()
这两个函数内都有将entry界面控件forget的相关函数,为下一界面腾出空间。在最后均有一个get_question函数,作用是找到对应题型和章节的题目,生成一个子列表。代码如下
def get_question(qtype_chosed_list, chapter_chosed_list):
question_chosed_list = []
for timu in timu_list:
if timu['q_type'] in qtype_chosed_list and timu['chapter'] in chapter_chosed_list:
question_chosed_list.append(timu)
return question_chosed_list
在entry_out和entry_out_all_chapter的最后调用了random_timu函数,作用是从子题目池中pop出一个,代码如下
def random_timu():
global chosed_timu, random_question
if chosed_timu == []:
question_empty()
return
random_num = random.randint(0, len(chosed_timu) - 1)
random_question = chosed_timu.pop(random_num)
if random_question['q_type'] == '1':
xuanze_on()
elif random_question['q_type'] == '2':
tiankong_on()
elif random_question['q_type'] == '3':
panduan_on()
接下来的循环,节点都是这个random_timu函数。以随机到选择题为例。进入xuanze_on函数,部署相关控件,代码如下
def xuanze_on():
global label_answer, var_option, label_question, option_a, option_b, option_c, option_d
label_question = Label(main_window, text=lingqiyihang(random_question['content']['title'], 38),
anchor='w', justify='left')
var_option = StringVar()
option_a = Radiobutton(main_window, text='A. ' + random_question['content']['opt_a'],
anchor='w', variable=var_option, value='a', command=xuanze_1)
option_b = Radiobutton(main_window, text='B. ' + random_question['content']['opt_b'],
anchor='w', variable=var_option, value='b', command=xuanze_1)
option_c = Radiobutton(main_window, text='C. ' + random_question['content']['opt_c'],
anchor='w', variable=var_option, value='c', command=xuanze_1)
option_d = Radiobutton(main_window, text='D. ' + random_question['content']['opt_d'],
anchor='w', variable=var_option, value='d', command=xuanze_1)
label_question.place(relwidth=0.8, relheight=0.3, relx=0.1, rely=0.05)
option_a.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.35)
option_b.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.4)
option_c.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.45)
option_d.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.5)
该函数部署了题面文本框和四个选项的单选按钮。题面文本框中有一个lingqiyihang函数,作用是对给定的num,将字符串每num个字另起一行。代码如下
def lingqiyihang(text, num):
sth_list = []
while len(text) > num:
sth = text[:num]
text = text[num:]
sth_list.append(sth)
return '\n'.join(sth_list) + '\n' + text
而四个按钮触发的command为entry_1,该函数将选项按钮forget,改为文本控件,并根据选择错误与否显示“答对了”或“选项是X”,代码如下
def xuanze_1():
global next_button, label_answer, option_a_text, option_b_text, option_c_text, option_d_text
option_a.place_forget()
option_b.place_forget()
option_c.place_forget()
option_d.place_forget()
option_a_text = Label(main_window, text=' A. ' + random_question['content']['opt_a'], anchor='w')
option_b_text = Label(main_window, text=' B. ' + random_question['content']['opt_b'], anchor='w')
option_c_text = Label(main_window, text=' C. ' + random_question['content']['opt_c'], anchor='w')
option_d_text = Label(main_window, text=' D. ' + random_question['content']['opt_d'], anchor='w')
option_a_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.352)
option_b_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.4)
option_c_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.452)
option_d_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.5)
if var_option.get() != random_question['content']['ans'].lower():
label_answer = Label(main_window, text='答案是: ' + random_question['content']['ans'].upper(), anchor='w')
else:
label_answer = Label(main_window, text='答对了w', anchor='w')
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.65)
next_button = Button(main_window, text='下一题', command=xuanze_off)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
点击此时产生页面的“下一步”按钮,将会触发xuanze_off函数,代码如下
def xuanze_off():
label_question.place_forget()
option_a_text.place_forget()
option_b_text.place_forget()
option_c_text.place_forget()
option_d_text.place_forget()
label_answer.place_forget()
next_button.place_forget()
random_timu()
这个函数将页面上剩余所有控件forget,并且回到random_timu函数中。选择题界面的效果如下
填空和判断题界面的设计思路跟选择题并无二异。代码如下
def tiankong_on():
global label_question, answer_get, label_question, answer_sheet, answer_get_button
label_question = Label(main_window, text=lingqiyihang(random_question['content']['title'], 38) + '\n\n请输入答案:',
anchor='w', justify='left')
answer_get = StringVar()
answer_sheet = Entry(main_window, show=None, textvariable=answer_get)
answer_get_button = Button(main_window, text='提交', command=tiankong_1)
label_question.place(relwidth=0.8, relheight=0.25, relx=0.1, rely=0.05)
answer_sheet.place(relwidth=0.45, relx=0.1, rely=0.3)
answer_get_button.place(relwidth=0.1, relheight=0.06, relx=0.6, rely=0.295)
def tiankong_1():
global label_answer, next_button, answer_print
answer_get_button.place_forget()
answer_sheet.place_forget()
if answer_get.get() == random_question['content']['ans'].lower():
label_answer = Label(main_window, text='答对了w', anchor='w')
else:
label_answer = Label(main_window, text='答案是: ' + random_question['content']['ans'], anchor='w')
answer_print = Label(main_window, text=answer_get.get(), anchor='w')
answer_print.place(relwidth=0.45, relx=0.1, rely=0.298)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.65)
next_button = Button(main_window, text='下一题', command=tiankong_off)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
def tiankong_off():
label_answer.place_forget()
next_button.place_forget()
label_question.place_forget()
answer_print.place_forget()
random_timu()
def panduan_on():
global label_question, var_option, option_a, option_b
label_question = Label(main_window, text=lingqiyihang(random_question['content']['title'], 38) + '\n\n请选择正误:',
anchor='w', justify='left')
var_option = StringVar()
option_a = Radiobutton(main_window, text='正确',
anchor='w', variable=var_option, value='a', command=panduan_1)
option_b = Radiobutton(main_window, text='错误',
anchor='w', variable=var_option, value='b', command=panduan_1)
label_question.place(relwidth=0.8, relheight=0.3, relx=0.1, rely=0.05)
option_a.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.3)
option_b.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.35)
def panduan_1():
global label_answer, next_button, answer_get, answer_sheet, answer_get_button, option_a_text, option_b_text
option_a.place_forget()
option_b.place_forget()
option_a_text = Label(main_window, text=' 正确', anchor='w')
option_b_text = Label(main_window, text=' 错误', anchor='w')
option_a_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.3)
option_b_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.352)
if var_option.get() == 'a' and random_question['content']['ans'].lower() == 'a':
label_answer = Label(main_window, text='答对了w', anchor='w')
next_button = Button(main_window, text='下一题', command=panduan_off_1)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.42)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
elif var_option.get() == 'a' and random_question['content']['ans'].lower() == 'b':
label_answer = Label(main_window, text='答案是:错误 请输入改正意见:', anchor='w')
answer_get = StringVar()
answer_sheet = Entry(main_window, show=None, textvariable=answer_get)
answer_get_button = Button(main_window, text='提交', command=panduan_2)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.42)
answer_sheet.place(relwidth=0.45, relx=0.1, rely=0.5)
answer_get_button.place(relwidth=0.1, relheight=0.06, relx=0.6, rely=0.495)
elif var_option.get() == 'b' and random_question['content']['ans'].lower() == 'a':
label_answer = Label(main_window, text='答案是:正确', anchor='w')
next_button = Button(main_window, text='下一题', command=panduan_off_1)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.42)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
elif var_option.get() == 'b' and random_question['content']['ans'].lower() == 'b':
label_answer = Label(main_window, text='答对了w 请输入改正意见:', anchor='w')
answer_get = StringVar()
answer_sheet = Entry(main_window, show=None, textvariable=answer_get)
answer_get_button = Button(main_window, text='提交', command=panduan_2)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.42)
answer_sheet.place(relwidth=0.45, relx=0.1, rely=0.5)
answer_get_button.place(relwidth=0.1, relheight=0.06, relx=0.6, rely=0.495)
def panduan_off_1():
label_question.place_forget()
option_a_text.place_forget()
option_b_text.place_forget()
label_answer.place_forget()
next_button.place_forget()
random_timu()
def panduan_2():
global label_answer_2, answer_print, next_button
answer_get_button.place_forget()
answer_sheet.place_forget()
answer_print = Label(main_window, text=answer_get.get(), anchor='w')
if answer_get.get() == random_question['content']['correct'].lower():
label_answer_2 = Label(main_window, text='答对了w', anchor='w')
else:
label_answer_2 = Label(main_window, text='答案是: ' + random_question['content']['correct'], anchor='w')
next_button = Button(main_window, text='下一题', command=panduan_off_2)
answer_print.place(relwidth=0.45, relx=0.1, rely=0.498)
label_answer_2.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.65)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
def panduan_off_2():
label_question.place_forget()
option_a_text.place_forget()
option_b_text.place_forget()
label_answer.place_forget()
next_button.place_forget()
answer_print.place_forget()
next_button.place_forget()
label_answer_2.place_forget()
random_timu()
界面效果图如下
当回到random_question函数时,如果子题目池内已经没有题目,那么将触发question_empty函数,代码和效果如下
def question_empty():
msg.showwarning(title='提示', message='所有题目都已做完!')
entry_in()
点击确定后将触发entry_in函数,回到entry界面。
好啦~ 算是大功告成等着女朋友的夸奖啦~ 用pyinstaller生成一个可双击执行的exe文件,连同题库的json文件一起发给她就完事了~
最后自我总结一下,作为一个自学python的小白,在设计的过程中感觉自己学到了很多,并且成品出来以后内心非常有成就感。但回过头来看好像代码还是过于凌乱、冗长了一些,变量名的命名也相当...放飞自我,呵呵~
希望各位在参考过程中包容我的不足,毕竟是我的第一个完整的小项目,虽然说不上多高大上,但也算是我成长过程中小小的一步吧。有任何意见、建议或者疑问都可以在评论区或简信中告诉我。要是能留下一个大大的赞那就太感激不过了~
完整代码(因为一开始偷懒了所以并没有定义main函数而是直接开写的,以后会注意):
# /usr/bin/python3
# -*- coding:utf-8 -*-
import tkinter as tk
import tkinter.messagebox as msg
import tkinter.filedialog as fd
from tkinter import *
import json
import random
import os
import sys
def shuwei(num, character, weishu, side):
append_text = ''
for i in range(weishu - len(str(num))):
append_text = append_text + character
if side == 'front':
return append_text + str(num)
elif side == 'back':
return str(num) + append_text
def get_question(qtype_chosed_list, chapter_chosed_list):
question_chosed_list = []
for timu in timu_list:
if timu['q_type'] in qtype_chosed_list and timu['chapter'] in chapter_chosed_list:
question_chosed_list.append(timu)
return question_chosed_list
def lingqiyihang(text, num):
sth_list = []
while len(text) > num:
sth = text[:num]
text = text[num:]
sth_list.append(sth)
return '\n'.join(sth_list) + '\n' + text
def question_empty():
msg.showwarning(title='提示', message='所有题目都已做完!')
entry_in()
def choose_file():
global timu_list, whole_chapter_list, whole_qtype_list
file_path = 'NoFileChosed'
while file_path[-5:] != '.json':
if file_path == '':
sys.exit(0)
if file_path != 'NoFileChosed':
msg.showwarning(title='提示', message='请选择json文件!')
default_dir = os.path.split(os.path.realpath(__file__))[0]
file_path = tk.filedialog.askopenfilename(title=u'选择文件', initialdir=(os.path.expanduser(default_dir)))
with open(file_path, 'r', encoding='utf-8') as f:
timu_list = json.load(f)
whole_chapter_list = []
whole_qtype_list = []
for timu in timu_list:
if timu['chapter'] not in whole_chapter_list:
whole_chapter_list.append(timu['chapter'])
if timu['q_type'] not in whole_qtype_list:
whole_qtype_list.append(timu['q_type'])
def entry_in():
label_welcome.place(relwidth=0.5, relheight=0.1, relx=0.25, rely=0.05)
entry_ok_button.place(relwidth=0.15, relheight=0.08, relx=0.25, rely=0.85)
all_chapter_button.place(relwidth=0.15, relheight=0.08, relx=0.6, rely=0.85)
for i in range(len(whole_qtype_list)):
qtype_checkbutton_list[i].place(relwidth=0.2, relx=0.2, rely=0.2 + i * 0.05)
for i in range(len(whole_chapter_list)):
chapter_checkbutton_list[i].place(relwidth=0.2, relx=0.6, rely=0.2 + i * 0.05)
def entry_out():
global chosed_timu
for i in range(len(whole_qtype_list)):
if qtype_var_list[i].get() == 1 and whole_qtype_list[i] not in qtype_chosed_list:
qtype_chosed_list.append(whole_qtype_list[i])
elif qtype_var_list[i].get() == 0 and whole_qtype_list[i] in qtype_chosed_list:
qtype_chosed_list.remove(whole_qtype_list[i])
for i in range(len(whole_chapter_list)):
if chapter_var_list[i].get() == 1 and whole_chapter_list[i] not in chapter_chosed_list:
chapter_chosed_list.append(whole_chapter_list[i])
elif chapter_var_list[i].get() == 0 and whole_chapter_list[i] in chapter_chosed_list:
chapter_chosed_list.remove(whole_chapter_list[i])
if qtype_chosed_list != [] and chapter_chosed_list == []:
msg.showwarning(title='提示', message='请选择章节!')
return
elif chapter_chosed_list != [] and qtype_chosed_list == []:
msg.showwarning(title='提示', message='请选择题型!')
return
elif chapter_chosed_list == [] and qtype_chosed_list == []:
msg.showwarning(title='提示', message='请选择题型和章节!')
return
elif get_question(qtype_chosed_list, chapter_chosed_list) == []:
msg.showwarning(title='提示', message='此种组合无题目!')
return
else:
label_welcome.place_forget()
entry_ok_button.place_forget()
all_chapter_button.place_forget()
for i in range(len(whole_qtype_list)):
qtype_checkbutton_list[i].place_forget()
for i in range(len(whole_chapter_list)):
chapter_checkbutton_list[i].place_forget()
chosed_timu = get_question(qtype_chosed_list, chapter_chosed_list)
random_timu()
def entry_out_all_chapter():
global chosed_timu
for i in range(len(whole_qtype_list)):
if qtype_var_list[i].get() == 1 and whole_qtype_list[i] not in qtype_chosed_list:
qtype_chosed_list.append(whole_qtype_list[i])
elif qtype_var_list[i].get() == 0 and whole_qtype_list[i] in qtype_chosed_list:
qtype_chosed_list.remove(whole_qtype_list[i])
chapter_chosed_list = whole_chapter_list
if qtype_chosed_list == []:
msg.showwarning(title='提示', message='请选择题型!')
return
elif get_question(qtype_chosed_list, chapter_chosed_list) == []:
msg.showwarning(title='提示', message='此种组合无题目!')
return
else:
label_welcome.place_forget()
entry_ok_button.place_forget()
all_chapter_button.place_forget()
for i in range(len(whole_qtype_list)):
qtype_checkbutton_list[i].place_forget()
for i in range(len(whole_chapter_list)):
chapter_checkbutton_list[i].place_forget()
chosed_timu = get_question(qtype_chosed_list, chapter_chosed_list)
random_timu()
def random_timu():
global chosed_timu, random_question
if chosed_timu == []:
question_empty()
return
random_num = random.randint(0, len(chosed_timu) - 1)
random_question = chosed_timu.pop(random_num)
if random_question['q_type'] == '1':
xuanze_on()
elif random_question['q_type'] == '2':
tiankong_on()
elif random_question['q_type'] == '3':
panduan_on()
def xuanze_on():
global label_answer, var_option, label_question, option_a, option_b, option_c, option_d
label_question = Label(main_window, text=lingqiyihang(random_question['content']['title'], 38),
anchor='w', justify='left')
var_option = StringVar()
option_a = Radiobutton(main_window, text='A. ' + random_question['content']['opt_a'],
anchor='w', variable=var_option, value='a', command=xuanze_1)
option_b = Radiobutton(main_window, text='B. ' + random_question['content']['opt_b'],
anchor='w', variable=var_option, value='b', command=xuanze_1)
option_c = Radiobutton(main_window, text='C. ' + random_question['content']['opt_c'],
anchor='w', variable=var_option, value='c', command=xuanze_1)
option_d = Radiobutton(main_window, text='D. ' + random_question['content']['opt_d'],
anchor='w', variable=var_option, value='d', command=xuanze_1)
label_question.place(relwidth=0.8, relheight=0.3, relx=0.1, rely=0.05)
option_a.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.35)
option_b.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.4)
option_c.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.45)
option_d.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.5)
def xuanze_1():
global next_button, label_answer, option_a_text, option_b_text, option_c_text, option_d_text
option_a.place_forget()
option_b.place_forget()
option_c.place_forget()
option_d.place_forget()
option_a_text = Label(main_window, text=' A. ' + random_question['content']['opt_a'], anchor='w')
option_b_text = Label(main_window, text=' B. ' + random_question['content']['opt_b'], anchor='w')
option_c_text = Label(main_window, text=' C. ' + random_question['content']['opt_c'], anchor='w')
option_d_text = Label(main_window, text=' D. ' + random_question['content']['opt_d'], anchor='w')
option_a_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.352)
option_b_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.4)
option_c_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.452)
option_d_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.5)
if var_option.get() != random_question['content']['ans'].lower():
label_answer = Label(main_window, text='答案是: ' + random_question['content']['ans'].upper(), anchor='w')
else:
label_answer = Label(main_window, text='答对了w', anchor='w')
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.65)
next_button = Button(main_window, text='下一题', command=xuanze_off)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
def xuanze_off():
label_question.place_forget()
option_a_text.place_forget()
option_b_text.place_forget()
option_c_text.place_forget()
option_d_text.place_forget()
label_answer.place_forget()
next_button.place_forget()
random_timu()
def tiankong_on():
global label_question, answer_get, label_question, answer_sheet, answer_get_button
label_question = Label(main_window, text=lingqiyihang(random_question['content']['title'], 38) + '\n\n请输入答案:',
anchor='w', justify='left')
answer_get = StringVar()
answer_sheet = Entry(main_window, show=None, textvariable=answer_get)
answer_get_button = Button(main_window, text='提交', command=tiankong_1)
label_question.place(relwidth=0.8, relheight=0.25, relx=0.1, rely=0.05)
answer_sheet.place(relwidth=0.45, relx=0.1, rely=0.3)
answer_get_button.place(relwidth=0.1, relheight=0.06, relx=0.6, rely=0.295)
def tiankong_1():
global label_answer, next_button, answer_print
answer_get_button.place_forget()
answer_sheet.place_forget()
if answer_get.get() == random_question['content']['ans'].lower():
label_answer = Label(main_window, text='答对了w', anchor='w')
else:
label_answer = Label(main_window, text='答案是: ' + random_question['content']['ans'], anchor='w')
answer_print = Label(main_window, text=answer_get.get(), anchor='w')
answer_print.place(relwidth=0.45, relx=0.1, rely=0.298)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.65)
next_button = Button(main_window, text='下一题', command=tiankong_off)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
def tiankong_off():
label_answer.place_forget()
next_button.place_forget()
label_question.place_forget()
answer_print.place_forget()
random_timu()
def panduan_on():
global label_question, var_option, option_a, option_b
label_question = Label(main_window, text=lingqiyihang(random_question['content']['title'], 38) + '\n\n请选择正误:',
anchor='w', justify='left')
var_option = StringVar()
option_a = Radiobutton(main_window, text='正确',
anchor='w', variable=var_option, value='a', command=panduan_1)
option_b = Radiobutton(main_window, text='错误',
anchor='w', variable=var_option, value='b', command=panduan_1)
label_question.place(relwidth=0.8, relheight=0.3, relx=0.1, rely=0.05)
option_a.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.3)
option_b.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.35)
def panduan_1():
global label_answer, next_button, answer_get, answer_sheet, answer_get_button, option_a_text, option_b_text
option_a.place_forget()
option_b.place_forget()
option_a_text = Label(main_window, text=' 正确', anchor='w')
option_b_text = Label(main_window, text=' 错误', anchor='w')
option_a_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.3)
option_b_text.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.352)
if var_option.get() == 'a' and random_question['content']['ans'].lower() == 'a':
label_answer = Label(main_window, text='答对了w', anchor='w')
next_button = Button(main_window, text='下一题', command=panduan_off_1)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.42)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
elif var_option.get() == 'a' and random_question['content']['ans'].lower() == 'b':
label_answer = Label(main_window, text='答案是:错误 请输入改正意见:', anchor='w')
answer_get = StringVar()
answer_sheet = Entry(main_window, show=None, textvariable=answer_get)
answer_get_button = Button(main_window, text='提交', command=panduan_2)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.42)
answer_sheet.place(relwidth=0.45, relx=0.1, rely=0.5)
answer_get_button.place(relwidth=0.1, relheight=0.06, relx=0.6, rely=0.495)
elif var_option.get() == 'b' and random_question['content']['ans'].lower() == 'a':
label_answer = Label(main_window, text='答案是:正确', anchor='w')
next_button = Button(main_window, text='下一题', command=panduan_off_1)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.42)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
elif var_option.get() == 'b' and random_question['content']['ans'].lower() == 'b':
label_answer = Label(main_window, text='答对了w 请输入改正意见:', anchor='w')
answer_get = StringVar()
answer_sheet = Entry(main_window, show=None, textvariable=answer_get)
answer_get_button = Button(main_window, text='提交', command=panduan_2)
label_answer.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.42)
answer_sheet.place(relwidth=0.45, relx=0.1, rely=0.5)
answer_get_button.place(relwidth=0.1, relheight=0.06, relx=0.6, rely=0.495)
def panduan_off_1():
label_question.place_forget()
option_a_text.place_forget()
option_b_text.place_forget()
label_answer.place_forget()
next_button.place_forget()
random_timu()
def panduan_2():
global label_answer_2, answer_print, next_button
answer_get_button.place_forget()
answer_sheet.place_forget()
answer_print = Label(main_window, text=answer_get.get(), anchor='w')
if answer_get.get() == random_question['content']['correct'].lower():
label_answer_2 = Label(main_window, text='答对了w', anchor='w')
else:
label_answer_2 = Label(main_window, text='答案是: ' + random_question['content']['correct'], anchor='w')
next_button = Button(main_window, text='下一题', command=panduan_off_2)
answer_print.place(relwidth=0.45, relx=0.1, rely=0.498)
label_answer_2.place(relwidth=0.8, relheight=0.05, relx=0.1, rely=0.65)
next_button.place(relwidth=0.15, relheight=0.08, relx=0.425, rely=0.85)
def panduan_off_2():
label_question.place_forget()
option_a_text.place_forget()
option_b_text.place_forget()
label_answer.place_forget()
next_button.place_forget()
answer_print.place_forget()
next_button.place_forget()
label_answer_2.place_forget()
random_timu()
main_window = Tk()
main_window.title('背题助手')
main_window.geometry('600x450')
qtype_meaning = ['选择', '填空', '判断']
choose_file()
label_welcome = Label(main_window, text='请选择题型与章节!', font=('宋体', 14, 'bold'), relief='solid')
qtype_checkbutton_list = []
qtype_var_list = []
qtype_chosed_list = []
chapter_checkbutton_list = []
chapter_var_list = []
chapter_chosed_list = []
entry_ok_button = Button(main_window, text='确认', command=entry_out)
all_chapter_button = Button(main_window, text='章节全选', command=entry_out_all_chapter)
for i in range(len(whole_qtype_list)):
qtype_var_list.append(IntVar())
qtype_checkbutton_list.append(Checkbutton(main_window, text=qtype_meaning[int(whole_qtype_list[i]) - 1],
variable=qtype_var_list[i], onvalue=1, offvalue=0))
for i in range(len(whole_chapter_list)):
chapter_var_list.append(IntVar())
chapter_checkbutton_list.append(Checkbutton(main_window, text=shuwei(int(whole_chapter_list[i]), ' ', 2, 'back'),
variable=chapter_var_list[i], onvalue=1, offvalue=0))
entry_in()
main_window.mainloop()