Posts: 12,038
Threads: 487
Joined: Sep 2016
Start by writing down what you want the logger to do, step by step.
Posts: 23
Threads: 1
Joined: Apr 2019
Apr-09-2019, 11:42 AM
(This post was last modified: Apr-09-2019, 11:42 AM by hezza_23.)
import tkinter as tk
import tkinter.ttk as ttk
import sqlite3
import os
from pathlib import Path
import sys
from tkinter import *
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.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):
##root.destroy()
##root = tk.Tk()
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()
def login():
root =Tk()
l1 = Label(root, text='User: ')
l2 = Label(root, text='password: ')
t1=Entry(root, textvariable=StringVar())
t2=Entry(root, show= '*', textvariable=StringVar())
def valid():
u=t1.get()
p=t2.get()
if (u=='admin') and (p=='admin'):
l4 = Label(root, text='Welcome Admin - Hello All')
l4.pack()
if __name__ == '__main__':
QuizGui(root, title='Quiz Program')
root.mainloop()
else:
l3 = Label(root, text='Invalid Username and Password')
l3.pack()
b1=Button(root, text= 'Log-in', command=valid)
l1.pack()
t1.pack()
l2.pack()
t2.pack()
b1.pack()
login() Hi I have the log in working but i cant clear the GUI after the log in is finished can you help with this?
Posts: 23
Threads: 1
Joined: Apr 2019
Apr-12-2019, 06:04 PM
(This post was last modified: Apr-12-2019, 06:40 PM by hezza_23.)
Hi, also could you add some notation from your original code? There are some parts that I don't understand, as I want to understand what it is you did to make it work?
id like to know how you completed it so I can learn to replicate it myself in future circumstances
Posts: 12,038
Threads: 487
Joined: Sep 2016
I'd be glad to, but Which parts? as I don't have a lot of time.
Posts: 23
Threads: 1
Joined: Apr 2019
I have sufficient knowledge of Tkinter gui's but Id like to know how you called the questions from the database and then connected them to each of the buttons
Posts: 23
Threads: 1
Joined: Apr 2019
Also, at which part of the code could I output the results of the quiz into a textfile
Posts: 12,038
Threads: 487
Joined: Sep 2016
the database has three tables, Question, Choices and Answers
If you run sqlite3 from command line, you can see the different tables:
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE Questions (QuestionId, QuizCode, Unused, Question);
CREATE TABLE Choices (QuestionId, QuizCode, SeqLetter, Choice);
CREATE TABLE Answers (QuestionId, QuizCode, Answer, Unused); As you can see, each table has QuestionId in common, yo you can link everything together using that:
sqlite> select * from Questions where QuestionId = '1';
1|Q||Which Of these describes an element best?
sqlite>
sqlite> select * from choices where QuestionId = '1';
1|C|A|Building Block
1|C|B|Made Of Only One Type Of Atom
1|C|C|Contains No Chemical Bonds
1|C|D|Pure Substance
sqlite>
sqlite>
sqlite> select * from answers where QuestionId = '1';
1|A|B|
sqlite> The second column contains the quiz code (same as spreadsheet, Q, C or A for question, choice, or answer)
def get_question(self, question_number):
# Set up SQL statements (based on question_number)
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:
# create a cursor
cursor = self.dbcon.cursor()
# fetch question using SQL statement qsql
cursor.execute(qsql)
# fetch result of query into variable question
question = cursor.fetchone()[0]
# Create a list to hold all choices
choices = []
# fetch choices using SQL statement csql
cursor.execute(csql)
# move results into choices list
while True:
choice = cursor.fetchmany()
if not len(choice):
break
choices.append(list(choice[0]))
# fetch answer using SQL statement asql
cursor.execute(asql)
# fetch result of query into variable answer
answer = cursor.fetchone()[0]
return question, choices, answer
except TypeError:
print(f'Invalid question_number {question_number}') Variables are set from the query
for example line 39:
qlabel = tk.Label(frame1, textvariable=self.current_question)
uses textvariable self.current_question which is set on line 69:
self.current_question.set(f'Question {question_number}: {question}')
the others are similar
on line 62:
response = tk.Label(frame1, textvariable=self.get_next_question)
textvariable is self.get_next_question
Posts: 23
Threads: 1
Joined: Apr 2019
Okay, thank you very much, any suggestions on how I can export the results. What part of the code should I go to output them?
Posts: 12,038
Threads: 487
Joined: Sep 2016
I'm not sure of what you mean by export results?
Posts: 23
Threads: 1
Joined: Apr 2019
I want to have a document with a record of how the user answered the questions and weather or not they were correct
|