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('', self.nextpage) self.content.background.bind('', self.exit) self.content.background.bind('', self.prevpage) self.content.background.bind('', self.nextpage) self.content.background.bind('', self.nextpage) self.content.background.bind('', self.prevpage) self.content.background.bind('', self.prevpage) self.content.background.bind('', self.nextpage) self.content.background.bind('', 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('', self.nextpage) self.content.background.bind('', self.exit) self.content.background.bind('', self.prevpage) self.content.background.bind('', self.nextpage) self.content.background.bind('', self.nextpage) self.content.background.bind('', self.prevpage) self.content.background.bind('', self.prevpage) self.content.background.bind('', self.nextpage) self.content.background.bind('', 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('', 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('', self.start_test) self.usernameE.bind('', lambda event: self.focus_set()) self.bind('', self.exit) self.bind('', lambda event: self.usernameE.focus()) self.bind('', 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('', self.select_item) self.tree.bind('', self.select_item) self.tree.bind('', self.select_item) self.tree.bind('', self.exit) self.bind('', 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("", self.start_test) self.content.background.bind("", 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)