You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
7.7 KiB
229 lines
7.7 KiB
import tkinter as tk |
|
from tkinter import ttk |
|
import customtkinter as ctk |
|
import csv, random |
|
|
|
|
|
def updatePage(): |
|
question_from.configure(text= question_list[current_question-1][7]) |
|
question_label.configure(text= question_list[current_question-1][1], ) |
|
optionA.configure(text= "(A) " + question_list[current_question-1][2]) |
|
optionB.configure(text= "(B) " + question_list[current_question-1][3]) |
|
optionC.configure(text= "(C) " + question_list[current_question-1][4]) |
|
optionD.configure(text= "(D) " + question_list[current_question-1][5]) |
|
|
|
|
|
def nextPageCallback(): |
|
global current_question |
|
|
|
if(current_question < question_count): |
|
current_question += 1 |
|
select_question.set(current_question) |
|
option_var.set(ans[current_question-1]) |
|
checkAnswerFinish() |
|
setOptionColor() |
|
updatePage() |
|
|
|
|
|
def prevPageCallback(): |
|
global current_question |
|
|
|
if(current_question > 1): |
|
current_question -= 1 |
|
select_question.set(current_question) |
|
option_var.set(ans[current_question-1]) |
|
checkAnswerFinish() |
|
setOptionColor() |
|
updatePage() |
|
|
|
|
|
def selectQuestionCallback(choice): |
|
global current_question |
|
current_question = int(choice) |
|
option_var.set(ans[current_question-1]) |
|
checkAnswerFinish() |
|
setOptionColor() |
|
updatePage() |
|
|
|
|
|
def selectOptionCallback(): |
|
global current_question |
|
ans[current_question-1] = option_var.get() |
|
checkAnswerFinish() |
|
|
|
|
|
def checkAnswerFinish(): |
|
for i in ans: |
|
if(i == None): |
|
return False |
|
if(optionA.cget("state") != "disabled"): |
|
submit_btn.place(x= screen_width - 70, y= 25, anchor="center") |
|
return True |
|
|
|
|
|
def setOptionColor(): |
|
global current_question |
|
if(optionA.cget("state") == "disabled"): |
|
clearColor() |
|
if(correct[current_question-1] == True): |
|
#print("correct") |
|
match(ans[current_question-1]): |
|
case "A": |
|
optionA.configure(fg_color= "green", text_color= "green") |
|
case "B": |
|
optionB.configure(fg_color= "green", text_color= "green") |
|
case "C": |
|
optionC.configure(fg_color= "green", text_color= "green") |
|
case "D": |
|
optionD.configure(fg_color= "green", text_color= "green") |
|
else: |
|
#print("wrong") |
|
match(ans[current_question-1]): |
|
case "A": |
|
optionA.configure(fg_color= "red", text_color= "red") |
|
case "B": |
|
optionB.configure(fg_color= "red", text_color= "red") |
|
case "C": |
|
optionC.configure(fg_color= "red", text_color= "red") |
|
case "D": |
|
optionD.configure(fg_color= "red", text_color= "red") |
|
|
|
match(question_list[current_question-1][6]): |
|
case "A": |
|
option_mask.place(x= int(optionA.place_info()["x"]), y= int(optionA.place_info()["y"]), anchor="w") |
|
case "B": |
|
option_mask.place(x= int(optionB.place_info()["x"]), y= int(optionB.place_info()["y"]), anchor="w") |
|
case "C": |
|
option_mask.place(x= int(optionC.place_info()["x"]), y= int(optionC.place_info()["y"]), anchor="w") |
|
case "D": |
|
option_mask.place(x= int(optionD.place_info()["x"]), y= int(optionD.place_info()["y"]), anchor="w") |
|
|
|
|
|
def clearColor(): |
|
#print(optionA.cget("text_color")) |
|
option_mask.place_forget() |
|
optionA.configure(fg_color= ['#3B8ED0', '#1F6AA5'], text_color= ['gray10', '#DCE4EE']) |
|
optionB.configure(fg_color= ['#3B8ED0', '#1F6AA5'], text_color= ['gray10', '#DCE4EE']) |
|
optionC.configure(fg_color= ['#3B8ED0', '#1F6AA5'], text_color= ['gray10', '#DCE4EE']) |
|
optionD.configure(fg_color= ['#3B8ED0', '#1F6AA5'], text_color= ['gray10', '#DCE4EE']) |
|
|
|
|
|
def submitCallback(): |
|
global question_count |
|
submit_btn.place_forget() |
|
optionA.configure(state="disabled") |
|
optionB.configure(state="disabled") |
|
optionC.configure(state="disabled") |
|
optionD.configure(state="disabled") |
|
|
|
idx = 0 |
|
corrent_count = 0 |
|
for i in range(0, question_count): |
|
if(ans[i] != question_list[i][6]): |
|
correct[idx] = False |
|
#print("Wrong", idx) |
|
else: |
|
correct[idx] = True |
|
corrent_count += 1 |
|
idx += 1 |
|
print(correct) |
|
score.place(x= screen_width - 70, y= 25, anchor="center") |
|
score.configure(text= str(corrent_count)+ "/" +str(question_count)) |
|
setOptionColor() |
|
|
|
|
|
|
|
|
|
|
|
|
|
# Config |
|
question_count = 20 |
|
|
|
screen_height = 500 |
|
screen_width = 600 |
|
|
|
|
|
# Variable |
|
current_question = 1 |
|
ans = [None] * question_count |
|
correct = [None] * question_count |
|
#print(ans) |
|
|
|
|
|
|
|
# Read Data |
|
csv_file = open("output.csv", mode="r", encoding="UTF-8", newline='') |
|
data = list(csv.reader(csv_file)) |
|
question_list = random.sample(data, 20) |
|
|
|
|
|
# Init Window |
|
screen_height_str = str(screen_height) |
|
screen_width_str = str(screen_width) |
|
|
|
ctk.set_appearance_mode("System") |
|
ctk.set_default_color_theme("blue") |
|
window = ctk.CTk() |
|
window.title('GUI') |
|
window.resizable(False, False) |
|
window.geometry(screen_width_str + "x" + screen_height_str) |
|
|
|
|
|
# Font Settings |
|
title_font = ctk.CTkFont(family= "Microsoft JhengHei", size= 20, weight="bold") |
|
function_font = ctk.CTkFont(family= "Microsoft JhengHei", size= 18, weight="bold") |
|
option_font = ctk.CTkFont(family= "Microsoft JhengHei", size= 16, weight="bold") |
|
|
|
|
|
# Select Question |
|
next_question_btn = ctk.CTkButton(window, text="下一題", font= function_font, width= 100, command= nextPageCallback) |
|
next_question_btn.place(x= screen_width/2 + 150, y= screen_height - 50, anchor="center") |
|
|
|
prev_question_btn = ctk.CTkButton(window, text="上一題", font= function_font, width= 100, command= prevPageCallback) |
|
prev_question_btn.place(x= screen_width/2 - 150, y= screen_height - 50, anchor="center") |
|
|
|
question_num_list = str(list(range(1, question_count+1))).strip('][').split(', ') |
|
select_question = ctk.CTkOptionMenu(window, values= question_num_list, width= 100, font= function_font, dropdown_font = function_font, command= selectQuestionCallback) |
|
select_question.place(x= screen_width/2, y= screen_height - 50, anchor="center") |
|
|
|
|
|
# Question From |
|
question_from = ctk.CTkLabel(window, font= title_font) |
|
question_from.place(x= screen_width/2, y= 30, anchor="center") |
|
|
|
|
|
# Question |
|
question_label = ctk.CTkLabel(window, wraplength= screen_width - 100, font= title_font) |
|
question_label.place(x= screen_width/2, y= 80, anchor="center") |
|
|
|
|
|
# Options |
|
option_var = ctk.StringVar() |
|
optionA = ctk.CTkRadioButton(window, variable= option_var, value= "A", font= option_font, command= selectOptionCallback) |
|
optionA.place(x= 80, y= 200, anchor="w") |
|
optionB = ctk.CTkRadioButton(window, variable= option_var, value= "B", font= option_font, command= selectOptionCallback) |
|
optionB.place(x= 80, y= 250, anchor="w") |
|
optionC = ctk.CTkRadioButton(window, variable= option_var, value= "C", font= option_font, command= selectOptionCallback) |
|
optionC.place(x= 80, y= 300, anchor="w") |
|
optionD = ctk.CTkRadioButton(window, variable= option_var, value= "D", font= option_font, command= selectOptionCallback) |
|
optionD.place(x= 80, y= 350, anchor="w") |
|
|
|
|
|
# Submit |
|
submit_btn = ctk.CTkButton(window, text="完成", font= function_font, width= 100, command= submitCallback) |
|
#submit_btn.place(x= screen_width - 70, y= 25, anchor="center") |
|
|
|
score = ctk.CTkLabel(window, wraplength= screen_width - 100, font= title_font) |
|
#score.place(x= screen_width - 70, y= 25, anchor="center") |
|
|
|
|
|
# Correct Mask |
|
option_mask = ctk.CTkRadioButton(window, text= "", font= option_font, fg_color= "green", text_color= "green", state="disable", width= 0) |
|
option_mask.select() |
|
#option_mask.place(x= 150, y= 350, anchor="w") |
|
|
|
updatePage() |
|
#print(optionD.place_info()["x"]) |
|
|
|
|
|
window.mainloop() |