I have added a student info class, store the DataEntry.py script in same directory as quiz.py script.
This isn't quite how I think it should be, I'll work on it when I have time, also, the information
isn't saved anywhere yet. I'll incorporate that into the file that stores quiz results (again as I find time).
So you will be getting this piece meal
** NOTE ** There are changes to quiz.py to load new class.
DataEntry.py:
import tkinter as tk
class GetStudentInfo:
def __init__(self, parent):
self.fields = ['Student Id', 'Last Name', 'First Name', 'Date']
self.entry_widgets = []
self.parent = parent
self.parent.geometry('600x400+100+100')
self.parent.title('Student Information')
self.entry_widgets = self.create_form()
def get_entries(self, entry_widgets):
content = []
for element in entry_widgets:
field = element[0]
content.append(element[1].get())
return content
def create_form(self):
entry_widgets = []
for field in self.fields:
bgcolor = '#ffcc99'
ent_frame = tk.Frame(self.parent, bg=bgcolor, padx=2, pady=2, relief=tk.RAISED)
ent_label = tk.Label(ent_frame, bg=bgcolor, width=15, padx=2, pady=2, text=field, anchor='w')
ent_entry = tk.Entry(ent_frame, relief=tk.SUNKEN)
ent_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
ent_label.pack(side=tk.LEFT)
ent_entry.pack(side=tk.RIGHT, expand=True, fill=tk.X)
entry_widgets.append([field, ent_entry])
subbtn = tk.Button(self.parent, padx=2, pady=2, text='Submit', command=self.GetData)
subbtn.pack(side=tk.TOP)
return entry_widgets
def GetData(self):
content = self.get_entries(self.entry_widgets)
for n, field in enumerate(self.fields):
print(f'{field}: {content[n]}')
self.parent.destroy()
def main():
root = tk.Tk()
GetStudentInfo(root)
root.mainloop()
if __name__ == '__main__':
main()
Quiz.py:
import tkinter as tk
import tkinter.ttk as ttk
import sqlite3
import os
import DataEntry
from pathlib import Path
import sys
class QuizGui:
def __init__(self, parent, title='Generic Title'):
# create directory anchor
os.chdir(os.path.abspath(os.path.dirname(__file__)))
homepath = Path('.')
datadir = homepath / 'QuestionsDatabase'
self.database = datadir / 'Questions.db'
self.parent = parent
self.get_student_info = DataEntry.GetStudentInfo(self.parent)
self.dbcon = None
self.db_connect()
self.question = None
self.choices = None
self.answer = None
self.current_question = 1
self.question_text = tk.StringVar()
self.rb_control = tk.StringVar()
self.rb_control.set('A')
self.rb = {}
self.youranswer = tk.StringVar()
self.youranswer.set('Please make choice, press select when ready')
self.rbval = []
self.parent.geometry('600x400+50+50')
self.parent.title(title)
self.build_gui()
def build_gui(self):
frame1 = tk.Frame(self.parent, bd=5, relief=tk.SUNKEN, padx=5, pady=5)
frame1.pack(fill=tk.BOTH)
qlabel = tk.Label(frame1, textvariable=self.question_text)
qlabel.pack(anchor='w')
self.get_next_question()
self.question_text.set(f'{self.current_question} {self.question}')
rb = self.rb = {}
for n, choice in enumerate(self.choices):
rb[n] = {}
rb[n]['txt'] = tk.StringVar()
rb[n]['txt'].set(f'{choice[0]} {choice[1]}')
rb[n]['val'] = tk.StringVar()
rb[n]['widget'] = tk.Radiobutton(frame1, textvariable=rb[n]['txt'], padx=5,
variable=self.rb_control, value=n)
rb[n]['widget'].pack(anchor='w')
frame2 = tk.Frame(frame1, height=5, bg='gray', padx=10, pady=10, relief=tk.RAISED)
frame2.pack(fill=tk.BOTH)
btn1 = tk.Button(frame1, text='Select', bd=2, relief=tk.RAISED,
padx=5, pady=5, width=25, command=self.ChoiceMade)
btn1.pack(anchor='w')
btn2 = tk.Button(frame1, text='Next Question', bd=2, relief=tk.RAISED,
padx=5, pady=5, width=25, command=self.set_next_question)
btn2.pack(anchor='w')
btn3 = tk.Button(frame1, text='Quit', bd=2, relief=tk.RAISED,
padx=5, pady=5, width=25, command=self.quit)
btn3.pack(anchor='w')
frame3 = tk.Frame(frame1, height=5, bg='gray', padx=10, pady=10, relief=tk.RAISED)
frame3.pack(fill=tk.BOTH)
response = tk.Label(frame1, textvariable=self.youranswer)
response.pack(anchor='w')
def set_next_question(self):
self.current_question += 1
self.get_next_question()
self.question_text.set(f'{self.current_question} {self.question}')
for n, choice in enumerate(self.choices):
self.rb[n]['txt'].set(f'{choice[0]} {choice[1]}')
def get_next_question(self):
question_number = self.current_question
self.question, self.choices, self.answer = self.get_current_question()
self.question_text.set(self.question)
def ChoiceMade(self):
item_index = int(self.rb_control.get())
if self.choices[item_index][0] == self.answer:
self.youranswer.set('Correct Answer')
else:
self.youranswer.set('Sorry Wrong Answer')
def db_connect(self):
try:
self.dbcon = sqlite3.connect(self.database)
except sqlite3.Error as e:
print(e)
def get_current_question(self):
question_number = self.current_question
qsql = f''' SELECT Question FROM Questions WHERE QuestionId = '{question_number}' '''
csql = f''' SELECT SeqLetter, Choice FROM Choices WHERE QuestionId = '{question_number}' ORDER BY SeqLetter '''
asql = f''' SELECT Answer FROM Answers WHERE QuestionId = '{question_number}' '''
try:
cursor = self.dbcon.cursor()
cursor.execute(qsql)
question = cursor.fetchone()[0]
choices = []
cursor.execute(csql)
while True:
choice = cursor.fetchmany()
if not len(choice):
break
choices.append(list(choice[0]))
cursor.execute(asql)
answer = cursor.fetchone()[0]
return question, choices, answer
except TypeError:
print(f'Invalid question_number {question_number}')
def quit(self):
self.db_close()
self.parent.destroy()
sys.exit(0)
def db_close(self):
self.dbcon.close()
if __name__ == '__main__':
root = tk.Tk()
QuizGui(root, title='Quiz Program')
root.mainloop()