aboutsummaryrefslogtreecommitdiff
path: root/frames.py
diff options
context:
space:
mode:
Diffstat (limited to 'frames.py')
-rw-r--r--frames.py405
1 files changed, 405 insertions, 0 deletions
diff --git a/frames.py b/frames.py
new file mode 100644
index 0000000..216efa8
--- /dev/null
+++ b/frames.py
@@ -0,0 +1,405 @@
+import re
+from widgets import *
+from tkinter import ttk
+
+
+def showframe(frame):
+ frame.pack(fill=BOTH, expand=TRUE)
+ if hasattr(frame, 'content'):
+ frame.content.background.focus_set()
+ else:
+ frame.focus_set()
+
+
+# Result page
+class PTypePage(Frame):
+ ptypes = {'E':'Extrovert', 'S':'Sensing', 'T':'Thinking', 'J':'Judging',
+ 'I':'Introvert', 'N':'Intutive', 'F':'Feeling', 'P':'Perceiving'}
+ def __init__(self, lastframe, master, cursor, answers, *pargs):
+ Frame.__init__(self, master, *pargs)
+ # WIN_HEIGHT, WIN_WIDTH = 1200, 710
+ # self.master.geometry(f"{WIN_HEIGHT}x{WIN_WIDTH}")
+ # self.master.minsize(WIN_HEIGHT, WIN_WIDTH)
+ os.chdir(HOME)
+ os.chdir('ptypes')
+
+ self.lastframe = lastframe
+ self.cursor = cursor
+ self.answers = answers
+ self.fullanswers = ' , '.join([self.ptypes[x] for x in answers])
+ self.page_index = 0
+ self.hints = ("Well done {}! Tap anywhere to continue...".format(USERNAME),
+ "%s ( %s )" % (self.answers, self.fullanswers),
+ "That's it! Thanks for taking this test.")
+ self.hint = StringVar()
+ self.hint.set(self.hints[self.page_index])
+
+ self.statusbar = StatusBar(self, self.hint)
+ self.content = ContentBox(self, '%s%d.png' %(self.answers, self.page_index+1))
+ self.content.background.bind('<Button-1>', self.nextpage)
+ self.content.background.bind('<Button-2>', self.exit)
+ self.content.background.bind('<Button-3>', self.prevpage)
+ self.content.background.bind('<Return>', self.nextpage)
+ self.content.background.bind('<space>', self.nextpage)
+ self.content.background.bind('<BackSpace>', self.prevpage)
+ self.content.background.bind('<Left>', self.prevpage)
+ self.content.background.bind('<Right>', self.nextpage)
+ self.content.background.bind('<Escape>', self.exit)
+ self.content.background.focus_set()
+ self.content.pack(fill=BOTH, expand=True)
+ self.statusbar.pack(side=BOTTOM, fill=X)
+
+ def change_position(self):
+ os.chdir(HOME)
+ os.chdir('ptypes')
+ self.content.set('%s%d.png' %(self.answers, self.page_index+1))
+ self.hint.set(self.hints[self.page_index])
+
+ def prevpage(self, event=None):
+ if self.page_index > 0:
+ self.page_index -= 1
+ self.change_position()
+ else:
+ self.exit()
+
+ def nextpage(self, event=None):
+ if self.page_index < 2:
+ self.page_index += 1
+ self.change_position()
+ else:
+ self.exit(title="You are done!", message="Exit to main the main screen?")
+
+ def exit(self, event=None, title=None, message=None):
+ if title:
+ if messagebox.askokcancel(title, message):
+ self.destroy()
+ HomePage(self.master, self.cursor).pack(fill=BOTH, expand=TRUE)
+ else:
+ self.destroy()
+ showframe(self.lastframe)
+
+
+# Quiz page (4 questions)
+class TestPage(Frame):
+ options = (('E', 'S', 'T', 'J'), ('I', 'N', 'F', 'P'))
+ hints = ("Tap anywhere to continue...",
+ "First Option",
+ "Second Option",
+ "Choose your answer...")
+
+ def __init__(self, lastframe, master, cursor, *pargs):
+ Frame.__init__(self, master, *pargs)
+ self.lastframe = lastframe
+ self.master = master
+ self.cursor = cursor
+ # WIN_HEIGHT, WIN_WIDTH = 1200, 710
+ # self.master.geometry(f"{WIN_HEIGHT}x{WIN_WIDTH}")
+ # self.master.minsize(WIN_HEIGHT, WIN_WIDTH)
+ os.chdir(HOME)
+ os.chdir('quiz')
+
+ self.content = ContentBox(self, "Q-13.png")
+ self.content.background.bind('<Button-1>', self.nextpage)
+ self.content.background.bind('<Button-2>', self.exit)
+ self.content.background.bind('<Button-3>', self.prevpage)
+ self.content.background.bind('<Return>', self.nextpage)
+ self.content.background.bind('<space>', self.nextpage)
+ self.content.background.bind('<BackSpace>', self.prevpage)
+ self.content.background.bind('<Left>', self.prevpage)
+ self.content.background.bind('<Right>', self.nextpage)
+ self.content.background.bind('<Escape>', self.exit)
+ self.content.background.focus_set()
+
+ self.answers = ['']*4
+ self.answer = StringVar(self)
+ self.hint = StringVar(self)
+ self.position = StringVar(self)
+ self.positions = (" Intro ", "QUESTION #1", "QUESTION #2",
+ "QUESTION #3", "QUESTION #4")
+ self.statusbar = StatusBar(self, self.hint)
+ self.statusbar.addmenu(self.position, self.positions,
+ command=self.change_position)
+
+ self.content.pack(fill=BOTH, expand=YES)
+ self.statusbar.pack(side=BOTTOM, fill=X)
+
+ self.quest_index = -1
+ self.page_index = 3
+
+ global USERNAME
+ self.hint.set("Welcome {}! Tap anywhere to continue...".format(USERNAME))
+ self.position.set(self.positions[self.quest_index+1])
+
+ def get_selection(self):
+ if hasattr(self, 'selection'):
+ return
+ #self.selection.destroy()
+
+ bgcolor='#fdcc03'
+ fgcolor='black'
+ msgfont=("Times New Roman", 16, 'bold')
+ optfont=("Monospace", 12, 'bold')
+ self.answer.set(self.answers[self.quest_index])
+
+ def submit():
+ self.answers[self.quest_index] = self.answer.get()
+ self.nextpage()
+
+ self.selection = Frame(self, background=bgcolor)
+ message = Label(self.selection, text="I will go with...", font=msgfont,
+ width=40, height=2, background=bgcolor, foreground=fgcolor)
+ optA = Radiobutton(self.selection, text="First Option ", variable=self.answer,
+ value=self.options[0][self.quest_index], background=bgcolor, foreground=fgcolor, font=optfont,
+ highlightthickness=0, height=2, width=30)
+ optB = Radiobutton(self.selection, text="Second Option", variable=self.answer,
+ value=self.options[1][self.quest_index], background=bgcolor, foreground=fgcolor, font=optfont,
+ highlightthickness=0, height=2, width=30)
+ submitB = Button(self.selection, text="Submit", font=('', 12), width=10,
+ command=submit,
+ background=fgcolor, foreground=bgcolor, borderwidth=0, height=2)
+
+ message.pack(padx=40, pady=20)
+ optA.pack()
+ optB.pack()
+ submitB.pack(padx=20, pady=20)
+ self.selection.bind('<Button-3>', self.prevpage)
+ self.selection.place(relx=0.5, rely=0.5, x=-40, y=-40, anchor=CENTER)
+
+ def change_position(self, position=None):
+ os.chdir(HOME)
+ os.chdir('quiz')
+ if position:
+ self.quest_index = self.positions.index(position) - 1
+ self.page_index = 0
+ if self.quest_index == -1:
+ self.page_index = 3
+ self.hint.set("Tap anywhere to continue...")
+ else:
+ self.hint.set(self.hints[self.page_index])
+ # print('\n', self.quest_index, self.page_index, self.answers, self.answer)
+ if self.quest_index > 0 and self.page_index == 0:
+ answered = (4 - self.answers.count(''))
+ if answered < self.quest_index:
+ # print('no answer @', self.quest_index, self.page_index)
+ self.hint.set("Please sumbmit an answer to continue!")
+ self.statusbar.message.configure(foreground='darkred')
+ self.quest_index = answered
+ self.page_index = 3
+
+ if self.quest_index == 4:
+ self.quest_index = 3
+ self.page_index = 3
+ final = ''.join(self.answers)
+ self.cursor.execute("SELECT userid FROM records WHERE userid='{}'".format(USERNAME))
+ if self.cursor.fetchall():
+ self.cursor.execute(
+ "UPDATE records set ptype = '{}' WHERE userid='{}'".format(final, USERNAME))
+ else:
+ self.cursor.execute("INSERT INTO records values ('{}', '{}')".format(USERNAME, final))
+ self.pack_forget()
+ ptypepage = PTypePage(self, self.master, self.cursor, final)
+ ptypepage.pack(fill=BOTH, expand=TRUE)
+ return
+
+ self.position.set(self.positions[self.quest_index+1])
+ #print(self.quest_index, self.page_index, self.answers, self.answer)
+ self.content.set("Q%s%s.png" %
+ (self.quest_index, self.page_index))
+ if self.quest_index != -1 and self.page_index == 3:
+ self.get_selection()
+ elif hasattr(self, 'selection'):
+ self.selection.destroy()
+ del self.selection
+ self.statusbar.message.config(foreground='black')
+
+ def prevpage(self, event=None):
+ if self.quest_index == -1 and self.page_index == 3:
+ self.exit()
+ return
+ if self.page_index > 0:
+ self.page_index -= 1
+ self.change_position()
+ else:
+ self.page_index = 3
+ self.quest_index -= 1
+ self.change_position()
+
+ def nextpage(self, event=None):
+ if self.page_index < 3:
+ self.page_index += 1
+ self.change_position()
+ else:
+ self.page_index = 0
+ self.quest_index += 1
+ self.change_position()
+ self.content.background.focus_set()
+
+ def exit(self, event=None):
+ if messagebox.askokcancel("Exit",
+ "Do you really want to exit?\nAll answer data will be lost!"):
+ self.destroy()
+ showframe(self.lastframe)
+
+
+# Get user name
+class UserPage(Frame):
+ def __init__(self, lastframe, master, cursor, *pargs):
+ self.bgcolor='#ffcc33'
+ self.cursor = cursor
+ self.lastframe = lastframe
+ Frame.__init__(self, master, bg=self.bgcolor, *pargs)
+ self.master.configure(background=self.bgcolor)
+
+ self.username = StringVar()
+ self.usernameL = Label(self, font=20, background=self.bgcolor,
+ text="Enter User Name : ")
+ self.usernameE = Entry(self, font=30, textvariable=self.username)
+ self.message = Label(self, font=16, background=self.bgcolor,
+ text="User Name must be unique")
+ self.startB = Button(self, font=20, text="Start test",
+ background='black', foreground='white', command=self.start_test)
+ self.cancelB = Button(self, font=20, text="Cancel",
+ background='black', foreground='white', command=self.exit)
+
+ self.usernameL.place(relx=0.2, rely=0.4, height=40, width=200)
+ self.usernameE.place(relx=0.4, rely=0.4, height=40, width=400)
+ self.message.place(relx=0.4, rely=0.3)
+ self.startB.place(relx=0.4, rely=0.6, height=60, width=200)
+ self.cancelB.place(relx=0.6, rely=0.6, height=60, width=200)
+
+ self.usernameE.bind('<Return>', self.start_test)
+ self.usernameE.bind('<Escape>', lambda event: self.focus_set())
+ self.bind('<Escape>', self.exit)
+ self.bind('<Return>', lambda event: self.usernameE.focus())
+ self.bind('<space>', lambda event: self.usernameE.focus())
+ self.focus_set()
+
+ def start_test(self, event=None):
+ def print_warning(message):
+ Label(self, font=24, background=self.bgcolor, foreground='red',
+ text=message).place(relx=0.4, rely=0.2)
+ uname = self.username.get()
+ if uname == "":
+ print_warning("Please enter an user ID")
+ return
+ self.cursor.execute("SELECT * FROM records")
+ for user in self.cursor.fetchall():
+ if uname in user:
+ print_warning("A user with this ID already exists!" +\
+ "\nPlease try a different user ID.")
+ return
+
+ global USERNAME
+ USERNAME = uname
+ self.pack_forget()
+ TestPage(self, self.master, self.cursor).pack(fill=BOTH, expand=YES)
+
+ def exit(self, event=None):
+ self.destroy()
+ showframe(self.lastframe)
+
+
+class RecordsPage(Frame):
+ def __init__(self, lastframe, master, cursor, *pargs):
+ Frame.__init__(self, master, background='white', *pargs)
+ self.lastframe = lastframe
+ self.cursor = cursor
+
+ self.cursor.execute('DESCRIBE records')
+ columns = list()
+ for column in self.cursor.fetchall():
+ columns.append(column[0])
+
+ top = Frame(self)
+ bottom = Frame(self)
+ self.tree = ttk.Treeview(bottom, columns=columns, show='headings')
+ self.scrollbar = Scrollbar(bottom, orient=VERTICAL, borderwidth=0,
+ background='lightblue', troughcolor='white', highlightthickness=0,
+ activebackground='#0033aa', command=self.tree.yview)
+ self.tree.configure(yscroll=self.scrollbar.set)
+ self.search = StringVar()
+ self.searchbox = SearchBox(top, self.search, self.filter)
+ self.exitB = Button(top, text="❌", background='white', borderwidth=0,
+ highlightthickness=0, command=self.exit)
+
+ self.searchbox.pack(side=LEFT, fill=X, expand=TRUE)
+ self.exitB.pack(side=RIGHT)
+ self.tree.pack(side=LEFT, fill=BOTH, expand=TRUE)
+ self.scrollbar.pack(side=RIGHT, fill=Y)
+ top.pack(fill=X)
+ bottom.pack(fill=BOTH, expand=TRUE)
+
+ col_names = ('User ID', 'Personality Type')
+ for i in range(len(columns)):
+ self.tree.heading(columns[i], text=col_names[i])
+
+ self.cursor.execute('SELECT * FROM records')
+ self.records = self.cursor.fetchall()
+ for record in self.records:
+ self.tree.insert('', END, values=record)
+
+ self.tree.bind('<Double-1>', self.select_item)
+ self.tree.bind('<Return>', self.select_item)
+ self.tree.bind('<space>', self.select_item)
+ self.tree.bind('<Escape>', self.exit)
+ self.bind('<Escape>', self.exit)
+ self.tree.selection_set('I001')
+ self.focus_set()
+
+ def filter(self, event=None):
+ print(event)
+ filtertxt = self.search.get()
+ self.tree.delete(*self.tree.get_children())
+ for record in self.records:
+ for field in record:
+ if re.search(filtertxt, field.lower()):
+ self.tree.insert('', END, values=record)
+ break
+
+ def select_item(self, event=None):
+ selection = self.tree.selection()
+ item = self.tree.item(selection)
+ record = item['values']
+ print(record)
+ self.pack_forget()
+ global USERNAME
+ USERNAME = record[0]
+ PTypePage(self, self.master, self.cursor, record[1]).pack(
+ fill=BOTH, expand=TRUE)
+
+ def exit(self, event=None):
+ self.destroy()
+ showframe(self.lastframe)
+
+
+# Start app
+class HomePage(Frame):
+ def __init__(self, master, cursor, *pargs):
+ Frame.__init__(self, master, *pargs)
+ self.cursor = cursor
+ os.chdir(HOME)
+ WIN_HEIGHT, WIN_WIDTH = 1200, 675
+ self.master.geometry(f"{WIN_HEIGHT}x{WIN_WIDTH}")
+ self.master.minsize(WIN_HEIGHT, WIN_WIDTH)
+
+ self.content = ContentBox(self, "most-accurate-test.png")
+ self.content.pack(fill=BOTH, expand=YES)
+ self.mainmenu = ButtonMenu(self)
+ self.mainmenu.additem('SHOW RECORDS ', self.show_database)
+ self.mainmenu.additem('START TEST', self.start_test)
+ self.mainmenu.additem('QUIT', self.master.destroy)
+ self.content.background.bind("<space>", self.start_test)
+ self.content.background.bind("<Return>", self.start_test)
+ self.content.background.bind("1", self.show_database)
+ self.content.background.bind("2", self.start_test)
+ self.content.background.bind("3", lambda event: self.master.destroy())
+ self.content.background.focus_set()
+
+ def start_test(self, event=None):
+ print(self)
+ self.pack_forget()
+ UserPage(self, self.master, self.cursor).pack(fill=BOTH, expand=YES)
+
+ def show_database(self, event=None):
+ self.pack_forget()
+ RecordsPage(self, self.master, self.cursor).pack(fill=BOTH, expand=YES)