Tkinter:多项选择测验应用程序,无法更改问题(和其他问题)



我想用tkinter创建一个选择题应用程序,但我有三个问题,我不能自己解决:

  1. 问题没有改变,它停留在第一个问题上。
  2. 我有一个文件,我所有的问题(超过50),我想做的是从列表中随机选择10个(5个来自easy_question列表和5个来自hard_question列表)。
  3. 是否有一种方法可以在excel文件中保存选择的问题的十个代码,并知道那个人回答了什么(错或对不重要)?像这样:
1  2  3 [...]
question 1e 3h 2e
answer   2  3  4

这是我所有的问题,选项和正确答案的文件的简单版本:

easy_questions2=[
"1e. Name?",
"2e. Last name?",
"3e. Birthdate?",
"4e. Food?"
]
easy_options=[
['Marck', 'Mary','Joseph','John'],
['Smith', 'Hartnett','Pitt','Pacino'],
['June', 'October','November','April'],
['All', 'Fries','Pasta','Chicken']
]
easy_answers=[
1,
2,
3,
3
]
hard_questions2=[
"1h. Number?",
"2h. Word?",
"3h. Hour?",
"4h. Color?"
]
hard_options=[
['10', '11','21','55'],
['Book', 'Table','en','Pacino'],
['11', '21','24','18'],
['Yellow', 'Blue','Red','Green']
]
hard_answers=[
3,
4,
1,
2
]

这是我的代码:

import tkinter as tk
import tkinter.ttk as ttk
from questionslist import easy_questions2, easy_answers, easy_options
from openpyxl import load_workbook
from tkinter import messagebox as mb


class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)        
self.q_no=0        
self.display_title()
self.display_question()

self.opt_selected=tk.IntVar()

self.opts=self.radio_buttons()

self.display_options()

self.buttons()

self.data_size=len(question)

self.correct=0

def display_result(self):        
wrong_count = self.data_size - self.correct
correct = f"Correct: {self.correct}"
wrong = f"Wrong: {wrong_count}"

score = int(self.correct / self.data_size * 100)
result = f"Score: {score}%"

mb.showinfo("Result", f"{result}n{correct}n{wrong}")

def check_ans(self, q_no):      
if self.opt_selected.get() == answer[q_no]:
return True

def next_button(self):
if self.check_ans(self.q_no):            

self.correct += 1        
self.q_no += 1

if self.q_no==self.data_size:

self.display_result()
self.submit()

self.destroy()
else:
self.display_question()
self.display_options()

def buttons(self):        
next_button = tk.Button(self, text="Next",command=self.next_button, width=10)        
next_button.pack(pady=50, side="bottom")    

def display_options(self):
val=0

self.opt_selected.set(0)
for option in options[self.q_no]:
self.opts[val]['text']=option
val+=1

def display_question(self):        
q_no = tk.Label(self, text=question[self.q_no], width=60)
q_no.pack(padx=19, pady=31, anchor="w")   
def radio_buttons(self):

q_list = []

while len(q_list) < 4:

radio_button = ttk.Radiobutton(self,text=" ",variable=self.opt_selected,
value = len(q_list)+1)

q_list.append(radio_button)

radio_button.pack(padx=19, anchor="w")            

return q_list

def submit(self):
wb = load_workbook('D:\Python\quiz\template.xlsx')
sheet = wb.active
sheet.cell(row=1, column=2).value  = "first_name"
sheet.cell(row=1, column=3).value  = "correct"
sheet.cell(row=1, column=4).value  = "wrong"  
sheet.cell(row=2, column=3).value  = self.correct
sheet.cell(row=2, column=4).value  = self.data_size - self.correct   

excel_filename = "D:\Python\quiz\" + "data" + ".xlsx"
wb.save(excel_filename) 
question = easy_questions2
options = easy_options
answer = easy_answers
if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack(side="top", fill="both", expand=True)
root.title("Quiz")
root.geometry('800x450')
root.mainloop()

如果您想从一个文件(或多个)中读取问题,您可以使用(假设该文件是.txt文件,并且您每行写一个问题):

question_list = []
with open('filename.txt', 'r+') as question_file:
lines = question_file.readlines()
# Let's move the pointer of the file back to the start to resave the questions 
# as we don't want to lose them.
question_file.seek(0)
question_file.truncate()
for line in lines:
question_list.append(line)    # Put each question at the end of the list.
question_file.write(line)

使用此方法从所有文件中检索所有问题和答案,并将它们放入列表中。

现在您应该有一个简单问题列表和一个困难问题列表,因此,要从一个列表中选择一个随机问题,您可以使用随机模块中的特定函数randint(a, b),该函数返回'a'和'b'之间的值(包括'a'和'b')。试试这样:

from random import randint
# You have a list of 25 hard question, let's call it hard_list
# and a list of 25 easy question, let's call it easy_list
# Now let's use our randint function to retrieve 10 random value between 0 and 24.
# As you haven't done any statement about how to choose the order of the questions, 
# I'll take the first five from the hards one and the last 5 from the easy,
# but you can do it in any way you want. 
# It may be a little tricky to manage the possibility of same random numbers to come out,
# surely there are better ways to do it, but this works fine.
random_questions = []        # Here I write the questions randomly chosen.
random_numbers = []          # I use this to take into account the random values.
i = 0                        # Our counter.
while i < 10:
# If 5 questions have already been chosens, we change the list 
# and clear the random values counter once.
if i >= 5:
if i == 5:
random_numbers.clear()
val = randint(0, 24)
if val not in random_numbers:
i += 1
random_numbers.append(val)
random_questions.append(easy_list[val])

else:
val = randint(0, 24)
if val not in random_numbers:
i += 1
random_numbers.append(val)
random_questions.append(hard_list[val])
现在,在你的代码中,我看到'check_button'函数不会检查用户是否选择了一个选项,但也许这就是你想要的,其次,你的按钮不会改变问题,因为…你给q_no

分配了一个新标签(我想,到目前为止回答的问题数量是多少)?您应该将Label分配给另一个变量,并在用户每次单击该按钮时更新其文本值。 例如:

self.question_label = tk.Label(self, text=question[self.q_no], ....)
self.question_label.pack(...)

当用户按下下一个问题的按钮时,你检查答案是否正确,然后:

self.q_no += 1
if self.q_no==(self.data_size + 1):
#
# Do what you want to do if that was the last question.
#
else:
self.question_label['text'] = question[self.q_no]
#
# Here change the value of the buttons with the answers.
#

第三个问题,你想要什么样的格式?.csv、。xlsx、。xlsb等文件之间存在差异。但是对于转换,您可以使用pandas模块。

这些方法需要一个特定类型的对象进行转换,所以在使用它们之前,请务必以特定的方式格式化数据:从CSV到xlsx。这个类可以用作数据结构。

从个人经验来看,我知道你可以将你的数据格式为json转换为csv,但我不确定它是否适用于xlsx和其他格式。

希望我帮了你一点忙。

最新更新