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()