Dashboard

self.root = tk.Toplevel()
self.root.title("Dashboard")
self.root.configure(bg="#585858")
self.root.resizable(width=0, height=0)
win_width = 1280
win_height = int(1280 * 56.25 / 100)
self.root.geometry(str(win_width) + "x" + str(win_height))
Util.center(self.root)
login_root = None
if args.__sizeof__() > 0:
login_root = args[0]
# Get screen size
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
Util.set_font_size(screen_width, screen_height, win_width, win_height)
self.width = win_width * 96 / 100
self.height = win_height * 94 / 100
After creation of window, we will add a canvas background.
bg_canvas = RoundBackgroundFrame(self.root, self.width, self.height, padding, corner_radius, color, "#585858")
bg_canvas.place(width=self.width, height=self.height,x=win_width / 2 - self.width / 2, y=win_height / 2 - self.height / 2)
class RoundBackgroundFrame(tk.Canvas):
def __init__(self, parent, width, height, padding, cornerradius, color, bg):
tk.Canvas.__init__(self, parent, borderwidth=0, relief="flat", highlightthickness=0, bg=bg)
self.width = width
self.height = height
self.padding = padding
self.cornerradius = cornerradius
self.color = color
original = Image.open("images/corner.png")
resized = original.resize((int(40), int(40)), Image.ANTIALIAS)
self.image_r_t = ImageTk.PhotoImage(resized)
original = original.rotate(90, expand=0)
resized = original.resize((int(40), int(40)), Image.ANTIALIAS)
self.image_l_t = ImageTk.PhotoImage(resized)
original = original.rotate(90, expand=0)
resized = original.resize((int(40), int(40)), Image.ANTIALIAS)
self.image_l_b = ImageTk.PhotoImage(resized)
original = original.rotate(90, expand=0)
resized = original.resize((int(40), int(40)), Image.ANTIALIAS)
self.image_r_b = ImageTk.PhotoImage(resized)
self.shape(width, height, padding, cornerradius, color)
(x0, y0, x1, y1) = self.bbox("all")
width = (x1 - x0)
height = (y1 - y0)
self.configure(width=width, height=height)
def shape(self, width, height, padding, cornerradius, color):
self.create_polygon((padding, height - cornerradius - padding, padding, cornerradius + padding,
padding + cornerradius, padding, width - padding - cornerradius, padding,
width - padding, cornerradius + padding, width - padding,
height - cornerradius - padding, width - padding - cornerradius, height - padding,
padding + cornerradius, height - padding), fill=color, outline=color)
self.create_image(width - self.image_r_t.width(), 0, image=self.image_r_t, anchor=NW)
self.create_image(0, 0, image=self.image_l_t, anchor=NW)
self.create_image(0, height - self.image_l_b.width(), image=self.image_l_b, anchor=NW)
self.create_image(width - self.image_r_b.width(), height - self.image_r_b.width(), image=self.image_r_b, anchor=NW)
self.width = self.width * 98 / 100
self.height = self.height * 96 / 100
self.base_frame = Frame(self.root, width=self.width, height=self.height, bg=color)
bg_canvas.create_window(self.width / 100, self.height * 2 / 100, anchor=NW, window=self.base_frame)
#Add Heading
self.add_heading_label(self.base_frame, color, AppConstant.FONT_SIZE)
def add_heading_label(self, base_frame, color, font_size):
label_heading = Label(base_frame, text="Quiz App", anchor=CENTER, bg=color,font=("Lucida Grande", font_size + 6))
label_heading.place(width=self.width * 90 / 100, height=self.height * 7 / 100, x=self.width * 5 / 100,y=self.height * 0.5 / 100)
#Adding Line
self.add_line_border(self.base_frame, color, AppConstant.FONT_SIZE, self.root, login_root)
def add_line_border(self, base_frame, color, font_size, root, login_root):
line_canvas = Canvas(base_frame, bg=color, borderwidth=0, relief="flat", highlightthickness=0)
line_canvas.place(width=self.width - 4, height=5, x=2, y=self.height * 13 / 100)
line_canvas.create_line(0, 0, self.width, 0, fill="#787878")
line_canvas2 = Canvas(base_frame, bg=color, borderwidth=0, relief="flat", highlightthickness=0)
line_canvas2.place(width=self.width - 4, height=5, x=2, y=self.height * 20 / 100)
line_canvas2.create_line(0, 0, self.width, 0, fill="#787878")
frame_name = Frame(base_frame, bg=color)
frame_name.place(width=self.width * 94 / 100, x=self.width * 3 / 100, y=self.height * 14.3 / 100)
frame_name.grid_propagate(False)
label_name = Label(frame_name, font=("Lucida Grande", font_size - 6), text="Hi, " + AppConstant.USER_NAME,anchor=CENTER,bg=color)
label_name.pack(side="left", fill=None, expand=False)
button_logout = RoundedButton(frame_name, 130, 130 / 4.2, color, "images/button3.png", "Logout",font=("Lucida Grande", font_size - 6),
command=lambda: logout_click(root, login_root))
button_logout.pack(side="right", fill=None, expand=False)
Here Is logic for logout when click "Logout" Button.
def logout_click(root, login_root):
db = Util.connect_db()
cursor = db.cursor()
key_is_login = "IS_LOGIN"
cursor.execute("UPDATE system_setting SET value = ? WHERE key = ?",
(False, key_is_login,))
db.commit()
root.destroy()
Util.center(login_root)
login_root.deiconify()
class Util:
@staticmethod
def connect_db():
db = None
try:
db = sql.connect("quiz_db.db")
return db
except sql.Error as error:
print("Failed to insert data into sqlite table", error)
#Welcome UI
self.labelframe_welcome = LabelFrame(self.base_frame, text="", font=font.Font(family="Lucida Grande", size=14, weight='normal'),
pady=lvl_frame_width * 2 / 100, padx=lvl_frame_width * 2 / 100, bg=color)
self.welcome_lvl = Label(self.base_frame,text="WELCOME",anchor=CENTER, bg=color, fg="#00FF00",
font=("Lucida Grande", AppConstant.FONT_SIZE + 20,))
self.welcome_data_lvl = Label(self.base_frame,text="Happy to have you..!!",anchor=CENTER, bg=color, fg="#0000FF",
font=("Lucida Grande", AppConstant.FONT_SIZE))
Now We create Question UI for Quiz .
# Question ui
self.labelframe_question = LabelFrame(self.base_frame, text="",font=font.Font(family="Lucida Grande", size=13, weight='normal'),
pady=lvl_frame_width * 2 / 100, padx=lvl_frame_width * 2 / 100, bg=color)
self.question_number_lvl = Label(self.base_frame,text="Question No 1",anchor=W, bg=color,
font=("Lucida Grande", AppConstant.FONT_SIZE + 6))
self.timer_lvl = Label(self.base_frame,text="Time:",anchor=E, bg=color,
font=("Lucida Grande", AppConstant.FONT_SIZE))
self.question_data_lvl = Label(self.base_frame,text="Question Data",anchor=W, bg=color,
font=("Lucida Grande", AppConstant.FONT_SIZE - 6))
self.option1 = tk.Radiobutton(self.base_frame, text='Option A', variable=self.var, anchor=W, value='A',
command=self.save_answer)
self.option2 = tk.Radiobutton(self.base_frame, text='Option B', variable=self.var, anchor=W, value='B',
command=self.save_answer)
self.option3 = tk.Radiobutton(self.base_frame, text='Option C', variable=self.var, anchor=W, value='C',
command=self.save_answer)
self.option4 = tk.Radiobutton(self.base_frame, text='Option D', variable=self.var, anchor=W, value='D',
command=self.save_answer)
self.button_submit = RoundedButton(self.base_frame, 250, 130 / 2.9, color, "images/button3.png", "SUBMIT",
font=("Lucida Grande", 14),command=lambda: self.show_confirmation_dialog(self.height, lvl_frame_width))
self.button_next = RoundedButton(self.base_frame, 250, 130 / 2.9, color, "images/button3.png", "NEXT",font=("Lucida Grande", 14),
command=lambda: self.navigate_to_next_question())
self.button_previous = RoundedButton(self.base_frame, 250, 130 / 2.9, color, "images/button3.png", "PREVIOUS",font=("Lucida Grande", 14),
command=lambda: self.navigate_to_pre_question())
# result UI
self.labelframe_result = LabelFrame(self.base_frame, text="", font=font.Font(family="Lucida Grande", size=14, weight='normal'),
pady=lvl_frame_width * 2 / 100, padx=lvl_frame_width * 2 / 100, bg=color)
self.result_head_lvl = Label(self.base_frame, text="REPORT CARD", anchor=CENTER, bg=color, fg="#FF0000",
font=("Lucida Grande", AppConstant.FONT_SIZE + 25))
self.result_data_lvl = Label(self.base_frame, text="", anchor=CENTER, bg=color, fg="#00FF00",
font=("Lucida Grande", AppConstant.FONT_SIZE - 2))
self.result_data2_lvl = Label(self.base_frame, text="", anchor=CENTER, bg=color, fg="#FF00FF",
font=("Lucida Grande", AppConstant.FONT_SIZE))
Now All UI Complete, Here's Configration of Welcome UI And "Start Quiz" Button.
#Configration
self.button_start_quiz = RoundedButton(self.base_frame, 250, 130 / 2.56, color, "images/button3.png", "START QUIZ",font=("Lucida Grande", 14),
command=lambda: self.show_question_ui(self.width, self.height, lvl_frame_width))
self.show_welcome_ui(self.width, self.height, lvl_frame_width)
class RoundedButton(tk.Canvas):
def __init__(self, parent, width, height, bg, icon_path, text, font, command=None):
tk.Canvas.__init__(self, parent, borderwidth=0, relief="flat", highlightthickness=0, bg=bg)
self.command = command
self.width = width
self.height = height
self.text = text
self.font = font
original = Image.open(icon_path)
resized = original.resize((int(width), int(height)), Image.ANTIALIAS)
self.image = ImageTk.PhotoImage(resized)
self.shape(width, height)
(x0, y0, x1, y1) = self.bbox("all")
width = (x1 - x0)
height = (y1 - y0)
self.configure(width=width, height=height)
self.bind("", self._on_press)
self.bind("", self._on_release)
def shape(self, width, height):
self.create_image(0, 0, image=self.image, anchor=NW)
self.create_text(width / 2, height / 2, anchor=CENTER, font=self.font, text=self.text, fill="#FFFFFF")
def shape_press(self, width, height):
self.create_image(0, 0, image=self.image, anchor=NW)
self.create_text(width / 2, height / 2, anchor=CENTER, font=self.font, text=self.text, fill="#000000")
def _on_press(self, event):
self.configure(relief="sunken")
self.delete("all")
self.shape_press(self.width, self.height)
def _on_release(self, event):
self.configure(relief="raised")
self.delete("all")
self.shape(self.width, self.height)
if self.command is not None:
self.command()
Here is logic for show welocome UI.
def show_welcome_ui(self, width, height, lvl_frame_width):
# Welcome UI
# placing these data by place manager
self.labelframe_welcome.place(width=lvl_frame_width, height=height * 70 / 100,
x=width * 3 / 100, y=height * 22 / 100)
self.welcome_lvl.place(width=width * 90 / 100, height=height * 7 / 100,
x=width * 5 / 100, y=height * 30 / 100)
self.welcome_data_lvl.place(width=width * 90 / 100, height=height * 5 / 100,
x=width * 5 / 100, y=height * 45 / 100)
self.button_start_quiz.place(x=width / 2 - 250 / 2, y=height * 65 / 100)
Here Is logic of Show Question UI .
def show_question_ui(self, width, height, lvl_frame_width):
# Ask Question UI
self.hide_welcome_ui()
lfbw = lvl_frame_width * 13 / 100
# placing these data by place manager
self.labelframe_question.place(width=lvl_frame_width, height=lfbw + lvl_frame_width * 22 / 100,
x=self.width * 3 / 100,
y=self.height * 22 / 100)
self.question_number_lvl.place(width=self.width * 90 / 100, height=self.height * 7 / 100,
x=self.width * 5 / 100, y=self.height * 28 / 100)
self.timer_lvl.place(width=self.width * 90 / 100, height=self.height * 3 / 100,
x=self.width * 5 / 100, y=self.height * 25 / 100)
self.question_data_lvl.place(width=width * 90 / 100, height=height * 4 / 100,
x=width * 5 / 100, y=height * 35 / 100)
self.option1.place(width=width * 90 / 100, height=height * 4 / 100, x=width * 5 / 100,
y=height * 60 / 100)
self.option2.place(width=width * 90 / 100, height=height * 4 / 100, x=width * 5 / 100,
y=height * 65 / 100)
self.option3.place(width=width * 90 / 100, height=height * 4 / 100, x=width * 5 / 100,
y=height * 70 / 100)
self.option4.place(width=width * 90 / 100, height=height * 4 / 100, x=width * 5 / 100,
y=height * 75 / 100)
self.button_submit.place(x=width - 250 - 50, y=height * 0.85)
self.button_next.place(x=width - 250 - 50, y=height * 0.85)
self.button_previous.place(x=50, y=height * 0.85)
self.navigate_to_next_question()
self.submit(height, lvl_frame_width)
Here is logic of hide Welcome UI when Question UI Appear.
def hide_welcome_ui(self):
self.labelframe_welcome.place_forget()
self.welcome_lvl.place_forget()
self.welcome_data_lvl.place_forget()
self.button_start_quiz.place_forget()
Here Is logic of navigate to preVious question when click "Privious" Button.
def navigate_to_pre_question(self):
if self.current_question_number > 0:
self.current_question_number = self.current_question_number - 1
self.next_question()
Here Is logic of navigate to next question when click "Next" Button.
def navigate_to_next_question(self):
if self.current_question_number < 9:
self.current_question_number = self.current_question_number + 1
self.next_question()
Here Is logic of get Next Question
def next_question(self):
df = pd.read_excel('text1.xlsx', engine="openpyxl")
# Question No
self.question_number_lvl["text"] = "Question No: " + str(
df.iloc[self.current_question_number][0])
# Question data
self.question_data_lvl["text"] = "Question: " + str(
df.iloc[self.current_question_number][1])
# option 1
self.option1["text"] = "A. " + str(df.iloc[self.current_question_number][2])
# option 2
self.option2["text"] = "B. " + str(df.iloc[self.current_question_number][3])
# option 3
self.option3["text"] = "C. " + str(df.iloc[self.current_question_number][4])
# option 4
self.option4["text"] = "D. " + str(df.iloc[self.current_question_number][5])
if self.current_question_number == 0:
self.button_previous.place_forget()
elif self.current_question_number == 1:
self.button_previous.place(x=50, y=self.height * 0.85)
elif self.current_question_number == 8:
self.button_submit.place_forget()
self.button_next.place(x=self.width - 250 - 50, y=self.height * 0.85)
elif self.current_question_number == 9:
self.button_next.place_forget()
self.button_submit.place(x=self.width - 250 - 50, y=self.height * 0.85)
key = "question_number_" + str(df.iloc[self.current_question_number][0])
if key in self.dict:
self.var.set(self.dict[key][1])
else:
self.var.set("z")
def save_answer(self, ):
df = pd.read_excel('text1.xlsx', engine="openpyxl")
self.dict["question_number_" + str(self.current_question_number + 1)] = [
df.iloc[self.current_question_number][6], self.var.get()]
Here Is logic for show confirmation dialog When Click "Submit" Button.
def show_confirmation_dialog(self, height, lvl_frame_width):
msg_box = messagebox.askokcancel(title="Submit", message="Do you want to submit your Quiz?")
print(msg_box)
if msg_box:
self.show_result_ui(height, lvl_frame_width)
else:
pass
def submit(self, height, lvl_frame_width):
try:
# the input provided by the user is
temp = int(0) * 3600 + int(self.minutes) * 60 + int(self.seconds)
except:
pass
while temp > -1:
mins, secs = divmod(temp, 60)
# Converting the input entered in mins or secs to hours,
hours = 0
if mins > 60:
hours, mins = divmod(mins, 60)
# updating the GUI window after decrementing the
self.timer_lvl.config(
text="Time left:- " + str(mins).zfill(2) + ":" + str(secs).zfill(2))
self.base_frame.update()
time.sleep(1)
# when temp value = 0; then a messagebox pop's up
# with a message:"Time's up"
if temp == 0:
self.show_result_ui(height, lvl_frame_width)
# after every one sec the value of temp will be decremented
# by one
temp -= 1
Here Is logic for show Result UI And logic of Calculating Result.
def show_result_ui(self, height, lvl_frame_width):
# Show Result UI
self.hide_question_ui()
# placing these data by place manager
self.labelframe_result.place(width=lvl_frame_width, height=height * 70 / 100,x=self.width * 3 / 100,
y=self.height * 22 / 100)
self.result_head_lvl.place(width=self.width * 90 / 100, height=self.height * 10 / 100,
x=self.width * 5 / 100, y=self.height * 30 / 100)
self.result_data_lvl.place(width=self.width * 90 / 100, height=self.height * 4 / 100,
x=self.width * 5 / 100, y=self.height * 50 / 100)
self.result_data2_lvl.place(width=self.width * 90 / 100, height=self.height * 4 / 100,
x=self.width * 5 / 100, y=self.height * 60 / 100)
# calculating result
total = 0
for key in self.dict:
if str(self.dict[key][0]) == str(self.dict[key][1]):
total = total + 10
self.result_data_lvl["text"] = "Marks obtained " + str(total) + " out of 100"
if total <= 50:
self.result_data2_lvl["text"] = "Hard Luck..!! Try next time"
elif total == 100:
self.result_data2_lvl["text"] = "Excellent..!!"
elif 50 < total < 100:
self.result_data2_lvl["text"] = "Try Harder..!!"
Here Is logic for hide question UI When Result UI Appear.
def hide_question_ui(self):
self.labelframe_question.place_forget()
self.question_number_lvl.place_forget()
self.question_data_lvl.place_forget()
self.option1.place_forget()
self.option2.place_forget()
self.option3.place_forget()
self.option4.place_forget()
self.button_submit.place_forget()
self.button_next.place_forget()
self.button_previous.place_forget()
At last we will manage closing of window
def on_closing():
self.root.destroy()
args[0].deiconify()
self.root.protocol("WM_DELETE_WINDOW", on_closing)
Programmer Mirta is for learning and training. Projects might be simple to improve learning. Projects are constantly reviewed to avoid errors, but we cannot assure full correctness of all content. While using Programmer Mitra, you agree to have read and accepted our terms of use, cookie and privacy policy.
Copyright 2021 by Programmer Mitra. All Rights Reserved.