diff options
Diffstat (limited to 'frames.py')
-rw-r--r-- | frames.py | 405 |
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) |