Python Forum
[Tkinter] TKINTER quiz using sqlite3 database
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] TKINTER quiz using sqlite3 database
#44
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()
Reply


Messages In This Thread
TKINTER quiz using sqlite3 database - by hezza_23 - Apr-01-2019, 01:02 PM
RE: TKINTER quiz using sqlite3 database - by Larz60+ - Apr-15-2019, 11:12 AM
RE: TKINTER quiz using sqlite3 database - by Hilal - Nov-29-2021, 09:42 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  PyQt5 form not displaying my data from SQLite3 Database Linuxdesire 2 5,002 Jan-10-2023, 09:51 PM
Last Post: gradlon93
  Can't get tkinter database aware cascading comboboxes to update properly dford 6 3,671 Jan-11-2022, 08:37 PM
Last Post: deanhystad
Question [Tkinter] data enterred through gui is not storing in sqlite3 database Hilal 21 7,620 Dec-15-2021, 08:48 PM
Last Post: Hilal
  Help with PySimpleGUI INSERT INTO sqlite3 database jrbond 5 7,186 Jul-20-2020, 01:24 PM
Last Post: jrbond
  sQlite3 output to tkinter treeview - how do I set / increase width of the output? dewijones67 5 6,689 Jan-23-2019, 08:45 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020