class Widget_: def __init__(self, parent_frame, row, column, width=50, height=50): self.widget_frame = Frame(parent_frame, width=width, height=height) self.widget_frame.grid(row=row, column=column) self.width, self.height = width, height return def add_tag(self, tag_library, string): tag_library[string] = self def delete_widget(self): for child in self.widget_frame.winfo_children(): child.destroy() self.widget_frame.destroy() def hide_widget(self): self.widget_frame.grid_forget() def get_info(self): return def set_field(self): return pass
class MainController(Tk): def __init__(self, *args, **kwargs): Tk.__init__(self, *args, **kwargs) # The main container that contains the current frame self.container = Frame(self) self.container.pack(side=TOP, fill=BOTH, expand=True) self.container.grid_rowconfigure(0, weight=1) self.container.grid_columnconfigure(0, weight=1) # for mapping the spelling of the listed items with class names self.pages = { 'MainPage': MainPage, 'Caesar': Caesar, 'Vigenere': Vigenere, 'One-time pad': OTP, 'MD5 Hash': MD5, 'Base64 encode': Base64, 'ASCII chart': ASCIIChart, 'URL encode': URL, 'UTF-8 encode': UTF8, 'Unsigned Binary': Arithmetic, 'Sign and Magnitude': Arithmetic, "One's Complement": Arithmetic, "Two's Complement": Arithmetic, 'Hexadecimal': Arithmetic, 'Modulus Calculator': Modulus, 'All Numbers': AllNumbers, 'All Numbers (alternate)': AllNumbersAlt, 'Binary Representation': BinRep, 'Data Storage Units': DUnits, 'String to Binary': StrToBin, 'Prime Number Checker': Prime, 'RSA': rsa, 'RSA Key Generator': RSAKeys, 'Hexdump': Hdump } self.current_frame = Frame() self.show_frame("MainPage") def show_frame(self, page_name): """Change current page Show a frame given the page name and communicate to the frames with an optional option parameter """ self.current_frame.grid_forget() # clear frame's widgets self.current_frame = self.pages[page_name](parent=self.container, controller=self) self.current_frame.grid(row=0, column=0, sticky=N + E + S + W) if self.pages[ page_name].__name__ == 'Arithmetic': # set an option when the frame is loaded self.current_frame.set_option(page_name) return
class TelaInicial(): #================================================================== def __init__(self, janela): janela.title("Furo Pit") self.janela = janela #=Criação e posicionamento de elementos da tela self.frm_upper = Frame(janela) self.frm_down = Frame(janela) self.lb_title = Label(self.frm_upper, text="Furo Pit") self.btn_plotar = Button(self.frm_down, text="Novo ajuste", command=self.proxJanelaNovo) self.btn_sair = Button(self.frm_down, text="Sair", command=self.janela.destroy) self.frm_upper.grid() self.frm_down.grid() self.lb_title.grid() self.btn_plotar.pack(side=TOP) self.btn_sair.pack(side=BOTTOM) #================================================================== #=Passa para a próxima janela, limpando a anterior antes def proxJanelaNovo(self): self.limparJanela() TelaPontos(self.janela, self) #================================================================== #= Caso seja necessário retornar a essa janela, os objetos devem ser #= redesenhados. def redesenhar(self): self.frm_upper.grid() self.frm_down.grid() self.lb_title.grid() self.btn_plotar.pack(side=TOP) self.btn_sair.pack(side=BOTTOM) #================================================================== #= Caso seja necessário sair dessa janela, os objetos devem ser apagados. def limparJanela(self): self.lb_title.grid_forget() self.btn_plotar.pack_forget() self.btn_sair.pack_forget() self.frm_upper.grid_forget() self.frm_down.grid_forget()
class GuiController: window = None frame_tablero = None def __init__(self): self.window = Tk() self.window.title("Buscaminas") self.frame_tablero = Frame(self.window) self.frame_tablero.grid() def launch(self): self.window.mainloop() def add_celda_tablero(self, celda, left_click_action, right_click_action): button = Button(self.frame_tablero, bg=Color.CELDA_DEFAULT, activebackground=Color.CELDA_DEFAULT_OVER) button.bind("<Button-1>", left_click_action) button.bind("<Button-3>", right_click_action) button.config(height=1, width=1) button.grid(row=celda.posicion_x, column=celda.posicion_y) return button def revela_celda_con_mina(self, celda): celda.gui.configure(bg=Color.CELDA_MINA, state="disabled", text="X") def revela_celda_sin_mina(self, celda): celda.gui.configure(bg=Color.CELDA_LIBRE, state="disabled", text=str(celda.minas_cercanas)) def bloquear_celda(self, celda): celda.gui.configure(bg=Color.CELDA_DEFAULT, activebackground=Color.CELDA_DEFAULT_OVER) def desbloquear_celda(self, celda): celda.gui.configure(bg=Color.CELDA_SEGURA, activebackground=Color.CELDA_SEGURA_OVER) def reset_tablero(self): self.frame_tablero.grid_forget() self.frame_tablero.destroy() self.frame_tablero = Frame(self.window) self.frame_tablero.grid() def game_over(self, game_controller): if messagebox.askretrycancel("Game over", "BOOM!"): game_controller.set_new_game() else: quit() def winner(self, game_controller): if messagebox.askquestion("You win", "¿Jugar de nuevo?"): game_controller.set_new_game() else: quit()
class PlayerView: directories = [] def __init__(self, parent_window): self.parent_window = parent_window self.frame = Frame(parent_window.window) self.button_play = Button(self.frame, text=f"Play", command=self.__button_play_clicked) self.button_stop = Button(self.frame, text=f"Stop", command=self.__button_stop_clicked) self.button_open = Button(self.frame, text=f"Open", command=self.__button_open_clicked) self.song_list = Listbox(self.frame) self.player = Player() self.song_list.grid(column=0, row=0) self.button_open.config(width=8) self.button_open.grid(column=0, row=1) self.button_stop.config(width=8) self.button_stop.grid(column=1, row=1) self.button_play.config(width=8) self.button_play.grid(column=2, row=1) def show(self): self.frame.grid(column=0, row=0) def hide(self): self.frame.grid_forget() def __button_open_clicked(self): open_file_dialog = OpenFileDialog() self.directories = open_file_dialog.show() for index, directory in enumerate(self.directories): self.song_list.insert(index, directory) def __button_play_clicked(self): if self.song_list.curselection(): selected_song = self.song_list.get(self.song_list.curselection()) self.player.play(selected_song) def __button_stop_clicked(self): self.player.stop()
class FormParentClassification: def __init__(self, window, connection): self.frm_parent = Frame(window) self.initialize_components() self.frm_child = FormChildClassification(self.frm_parent, connection) def initialize_components(self): lbl_title = Label(self.frm_parent, text='Classifications') lbl_title.config(fg=TEXT_COLOR, font=TITLE_FONT) lbl_title.grid(row=0, column=0, pady=20, padx=20) def show_frm(self): self.frm_parent.grid(row=0, column=0) self.frm_child.show_frm() def hide_frm(self): self.frm_parent.grid_forget() self.frm_child.hide_frm()
class FormParentAED: def __init__(self, window, title, connection): self.frm_parent = Frame(window) self.title = title self.initialize_components() self.frm_child = FormChildAED(self.frm_parent, title, connection) def initialize_components(self): lbl_experimenter_title = Label(self.frm_parent, text=self.title + 's') lbl_experimenter_title.config(fg=TEXT_COLOR, font=TITLE_FONT) lbl_experimenter_title.grid(row=0, column=0, pady=20) def show_frm(self): self.frm_parent.grid(row=0, column=0) self.frm_child.show_frm() def hide_frm(self): self.frm_parent.grid_forget() self.frm_child.hide_frm()
class FenetrePymafia(Tk): def __init__(self, nombre_de_joueurs): """ Initialisation de pyMafia GUI :param nombre_de_joueurs: Nombre de joueurs humains """ super().__init__() self.geometry("900x800") self.title("PyMafia") self.rondes = 1 self.resizable(0, 0) self.framesJoueurs = list() self.main_container = Frame(self) self.main_container.grid(row=3, rowspan=10, column=0, columnspan=300, sticky="nsew") self.partie = self.créer_partie(nombre_de_joueurs) self.frameEtat = Frame(self.main_container) self.frameEtat.grid(row=0, column=8, columnspan=300, sticky="nsew") self.debuter_la_partie() self.partie_en_cours = True self.statusFrameJoueurs = list() self.intvar = IntVar() self.menu = Menu(self) self.optionMenu = OptionMenu(self, self.intvar, 3, 4, 5, 6) self.premier_menu = Menu(self.menu, tearoff=0) self.menu = Menu(self) self.optionMenu = OptionMenu(self, self.intvar, 3, 4, 5, 6) self.premier_menu = Menu(self.menu, tearoff=0) self.premier_menu.add_command(label='Relancer une partie', command=self.nouvelle_partie) self.premier_menu.add_separator() self.premier_menu.add_command(label='Quitter', command=self.validation_de_sortie) self.menu.add_cascade(label='Fichier', menu=self.premier_menu) self.config(menu=self.menu) def validation_de_sortie(self): """ fonction qui demande de valider si on veut vraiment quitter la partie en cours. :return: None """ message = "Vous avez une partie en cours. Désirez-vous réellement quitter la partie?" if messagebox.askokcancel("Annuler", message, default="cancel", icon="warning"): self.partie_en_cours = True self.destroy() else: pass def créer_partie(self, nombre_de_joueurs): """ Crée les sous-frames contenant les joueurs :param nombre_de_joueurs: :return: référence vers la partie créée """ partie = Partie(nombre_de_joueurs, nombre_de_joueurs) self.framesJoueurs.append( FrameJoueurGaucheHaut(self, partie.joueurs[0])) self.framesJoueurs.append(FrameJoueurDroitHaut(self, partie.joueurs[1])) self.framesJoueurs[0].grid(row=0, column=0, padx=15, pady=5) self.framesJoueurs[1].grid(row=0, column=2, padx=15, pady=5) if nombre_de_joueurs >= 3: self.framesJoueurs.append( FrameJoueurDroitBas(self, partie.joueurs[2])) self.framesJoueurs[2].grid(row=2, column=2, padx=15, pady=5) if nombre_de_joueurs == 4: self.framesJoueurs.append( FrameJoueurGaucheBas(self, partie.joueurs[3])) self.framesJoueurs[3].grid(row=2, column=0, padx=15, pady=5) return partie def debuter_la_partie(self): self.déterminer_premier_joueur() self.demander_sens() def déterminer_premier_joueur(self): self.partie.premier_joueur = self.framesJoueurs[ randint(1, (len(self.framesJoueurs))) - 1].joueur self.partie.joueur_courant = self.partie.premier_joueur def demander_sens(self): """ Demande au joueur qui débute dans quel sens il désire débuter normalement j'aurais gossé pour que si y'ait deux joueurs ça ne demande pas le sens mais ça ne me tente pas :return: """ label_txt = f"Le Joueur {self.partie.premier_joueur.identifiant} jouera en premier. " \ f"Veuillez choisir dans quel sens nous devons jouer." demande_de_sens = Label(self, text=label_txt, font=("courrier", 12), relief=FLAT) demande_de_sens.grid(row=0, column=0, padx=10, pady=10) bouton_select1 = Button(self, text="Sens horaire", font=("courrier", 12), pady=5, padx=5) bouton_select2 = Button(self, text="Sens anti-horaire", font=("courrier", 12), pady=5, padx=5) bouton_select1.bind( "<ButtonRelease-1>", lambda event: self.choix_sens( 1, bouton_select1, bouton_select2, demande_de_sens)) bouton_select1.grid(row=1, column=0, sticky=E) bouton_select2.bind( "<ButtonRelease-1>", lambda event: self.choix_sens( -1, bouton_select1, bouton_select2, demande_de_sens)) bouton_select2.grid(row=1, column=0, sticky=W) for fj in self.framesJoueurs: fj.last_grid = fj.grid_info() fj.grid_forget() self.frameEtat.grid_forget() def choix_sens(self, direction, bouton_select1, bouton_select2, demande_de_sens): """ Effectue le choix du sens (anti) horaire pour le jeu. Événementiel aux boutons de choix de sens :param direction: 1 - horaire, -1 antihoraire :param bouton_select1: référence au bouton à détruire :param bouton_select2: référence au bouton à détruire :param demande_de_sens: référence au label à détruire :return: None """ bouton_select1.destroy() bouton_select2.destroy() demande_de_sens.destroy() self.partie.sens = direction self.partie.determiner_joueur_suivant() for fj in self.framesJoueurs: fj.grid(column=fj.last_grid['column'], row=fj.last_grid['row'], padx=fj.last_grid['padx'], pady=fj.last_grid['pady']) self.partie.reinitialiser_dés_joueurs() for fj in self.framesJoueurs: fj.mettre_a_jour_affichage_dés(fj.joueur) self.créer_état( f"Joueur {self.partie.premier_joueur.identifiant} débutera la partie" ) def créer_état(self, message_etat=" " * 40): """ Créer frame en bas de fenêtre pour afficher le score et les messages du jeu :param message_etat: Message optionnel qui doit être afficher dans la fenêtre de jeu :return: """ for child in self.frameEtat.winfo_children(): child.destroy() self.frameEtat.grid(row=3, column=0, rowspan=300, sticky="nsew") self.statusFrameJoueurs = list() ligne = 0 self.statusFrameJoueurs.append( Label(self.frameEtat, text=f"Score", justify=LEFT).grid(row=0, column=0)) for fj in self.framesJoueurs: self.statusFrameJoueurs.append( Label(self.frameEtat, text=f"Joueur {fj.joueur.identifiant}" f"-->\t{fj.joueur.score}", justify=LEFT).grid(row=2 + ligne, column=0)) ligne += 1 self.statusFrameJoueurs.append( Label(self.frameEtat, text=f"Nombre de rondes\t{self.partie.ronde}\n\n", justify=LEFT).grid(row=3 + ligne, column=0)) self.statusFrameJoueurs.append( Label(self.frameEtat, text=f"\n\nMessages\t\t\n\n{message_etat}", justify=LEFT).grid(row=4 + ligne, column=0)) self.debuter_rondes() def debuter_rondes(self): """ débute une ronde et mets à jour l'affichage de dés :return: None """ if self.partie_en_cours: self.activer_dés_joueur_courant() self.maj_des() def gérer_dés_1_et_6(self): """ Effectue la gestion des dés 1 à 6 :return: None """ nombre_1, nombre_6 = self.partie.verifier_dés_joueur_courant_pour_1_et_6( ) for joueur in self.framesJoueurs: joueur.mettre_a_jour_affichage_dés(joueur.joueur) if nombre_1 > 0: f"Vous avez obtenu {nombre_1} dé 1" if nombre_6 > 0: f"Vous avez obtenu {nombre_1} dé 6" self.afficher_déplacement_dés(nombre_1, nombre_6) self.partie.deplacer_les_dés_1_et_6(nombre_1, nombre_6) def gérer_fin_de_ronde(self): """ Gère la fin de la ronde, joue les dés et attribut les points au gagnant :return: None """ self.partie.jouer_dés_en_fin_de_ronde() self.maj_des() message = self.partie.messages_pour_points_fin_de_ronde() messagebox.showinfo("Calcul de points", message) points_au_gagnant = self.partie.ajuster_points_des_perdants_en_fin_de_ronde( ) self.partie.ajuster_points_du_gagnant(points_au_gagnant) self.partie.passer_a_la_ronde_suivante() self.partie.retirer_joueurs_sans_points() def passer_prochaine_ronde(self): """ Vérifie si nous pouvons passer à la prochaine ronde :return: booléen """ return self.partie.ronde <= RONDEMAX and self.nombre_joueur_actifs( ) > 1 def créer_message_fin_de_partie(self): """ Retourne chaine de caractère indiquant qui est le joueur gagnant :return: message définissant le joueur gagnant """ indices_gagnant = self.partie.determiner_liste_gagnants() if len(indices_gagnant) == 1: gagnant = self.partie.joueurs[indices_gagnant[0]] message = f"Le gagnant est le Joueur {gagnant.identifiant}." else: message = f"Les joueurs gagnants sont les joueurs " for indice in indices_gagnant: gagnant = self.partie.joueurs[indice] message = message + f"Joueur {gagnant.identifiant} " return message def gérer_fin_partie_ou_ronde(self): """ Valide si c'est une fin de partie. :return: """ if self.passer_prochaine_ronde(): self.créer_état() self.partie.reinitialiser_dés_joueurs() self.maj_des() else: self.partie_en_cours = False self.désactiver_tous_les_dés() message = str(self.créer_message_fin_de_partie()) self.créer_état(message) message = self.partie.message_points_en_fin_de_partie() message = message + "\nPour démarrer une nouvelle partie ou pour quitter le jeu, utiliser le menu." messagebox.showinfo("Fin de la partie", message) def rouler_dé_complet(self): """ Routine du jeu au complet Permet de voir si le jeu est encore en cours, ronde terminée, fin de la partie. :return: """ self.gérer_dés_1_et_6() for joueur in self.framesJoueurs: joueur.mettre_a_jour_affichage_dés(joueur.joueur) if self.partie.verifier_si_fin_de_ronde(): for joueur in self.framesJoueurs: joueur.désactiver_dés() message = f"Le joueur {self.partie.joueur_courant.identifiant} a gagné la ronde " \ f"{self.partie.ronde}. Cliquer OK pour calculer jouer les dés de fin de ronde et " \ f"calculer les points." messagebox.showinfo("Fin de ronde", message) self.gérer_fin_de_ronde() self.gérer_fin_partie_ou_ronde() else: self.partie.passer_au_prochain_joueur() self.activer_dés_joueur_courant() self.maj_des() def nombre_joueur_actifs(self): """ Cette fonction retourne le nombre de joueurs actifs d'une partie :return: int : Nombre de joueurs actifs """ return len(self.partie.joueurs_actifs) def afficher_déplacement_dés(self, nombre_1, nombre_6): """ Ouvre un message box pour informer le joueur que des dés 1 et 6 ont étés pigés. :nombre_1 (int): nombre de dés 1 :nombre_6 (int): nombre de dés 6 :return: None """ message_final = f"Le Joueur {self.partie.joueur_courant.identifiant} roule ses dés!\n" message_1 = "" message_6 = "" if nombre_1 + nombre_6 > 0: if nombre_1 > 0: pluriel = '' if nombre_1 == 1 else 's' message_1 = f"Il obtient {nombre_1} dé{pluriel} 1.\n" \ f"Ce{pluriel} dé{pluriel} {'seront' if pluriel == 's' else 'sera'} retiré{pluriel}.\n" if nombre_6 > 0: pluriel = '' if nombre_1 == 1 else 's' message_6 = f"Il obtient {nombre_6} dé{pluriel} 6.\n Ce{pluriel} dé{pluriel} sera donc transféré au " \ f"joueur suivant: Joueur {self.partie.joueur_suivant.identifiant}.\n" if nombre_1 > 0: message_final = message_final + message_1 if nombre_6 > 0: message_final = message_final + message_6 self.créer_état(message_final) def maj_des(self): """ Mets à jour le label contenant les valeurs des dés :return: None """ for joueur in self.framesJoueurs: joueur.mettre_a_jour_affichage_dés(joueur.joueur) def désactiver_tous_les_dés(self): """ Désactive le bouton Lancer dés pour tous les joueurs sur le frame :return: None """ for joueur in self.framesJoueurs: joueur.désactiver_dés() def activer_dés_joueur_courant(self): """ Cette fonction parcours les frames contenant des joueurs et active le bouton Lancer dés que si la partie est encore en cours. :return: """ if self.partie_en_cours: for joueur in self.framesJoueurs: if self.partie.joueur_courant == joueur.joueur: joueur.activer_dés() else: joueur.désactiver_dés() else: self.désactiver_tous_les_dés() def nouvelle_partie(self): """ Menu du logiciel - Relancer une partie - Permet de relancer une partie :return: None """ if self.partie_en_cours: message = "Vous avez une partie en cours. Désirez-vous réellement lancer une nouvelle partie?" if messagebox.askokcancel("Annuler", message, default="cancel", icon="warning"): self.partie_en_cours = False self.destroy() DebutPartie() else: self.destroy() DebutPartie()
class Graphics(object): def __init__(self, canvas, rows, cols, size, window): '''initialises the graphics object and its properties''' self.canvas = canvas self.window = window self.rows = rows*2+1 self.cols = cols*2+1 self.size = size/2 self.label = {} self.label_vars = {} self.icons = (ImageTk.PhotoImage(file='png/faceicon0.png'), ImageTk.PhotoImage(file='png/faceicon1.png')) self.draw_static_grid() self.draw_changing_grid() self.info_labels() self.make_creator_label() def make_creator_label(self): self.canvas.create_text(self.cols*self.size/2+self.size/2, self.rows*self.size+self.size*2/3+2, text='Created by Abel Svoboda, 08/07/15') def draw_static_grid(self): '''draws the grid that is made at the start of the game''' hardblock = PhotoImage(file='gifs/hardblock.gif') label = Label(image=hardblock) label.image = hardblock #keeping a reference self.regular = {} self.absolute = {} for col in range(self.cols): for row in range(self.rows): left = col * self.size right = left + self.size+.5*self.size top = row * self.size bot = top + self.size+.5*self.size left += .5*self.size top += .5*self.size if row%2==0 and col%2==0 or \ row==0 or col==0 or \ row==self.rows-1 or col==self.cols-1: #hardblock self.absolute[(col-1,row-1)] = self.canvas.create_image( (left+right)/2,(top+bot)/2,image=hardblock) else: #walkable self.regular[(col-1,row-1)] = self.canvas.create_rectangle( left,top,right,bot,fill='#307100',width=0) def draw_changing_grid(self): '''draws the grid that is made at the start of each round''' softblock = PhotoImage(file='gifs/softblock.gif') label = Label(image=softblock) label.image = softblock #keeping a reference self.rocks = {} for col in range(self.cols): for row in range(self.rows): left = col * self.size right = left + self.size+.5*self.size top = row * self.size bot = top + self.size+.5*self.size left += .5*self.size top += .5*self.size if (row==1 or row==2) and (col==1 or col==2) or \ (row==self.rows-2 or row==self.rows-3) and (col==self.cols-2 or col==self.cols-3) or \ row%2==0 and col%2==0 or \ row==0 or col==0 or row==self.rows-1 or col==self.cols-1: pass elif randint(0,100) < 50: #soft block density self.rocks[(col-1,row-1)] = self.canvas.create_image( (left+right)/2,(top+bot)/2,image=softblock) def info_labels(self): '''creates some labels on the UI''' self.time_var = StringVar() self.time_var.set(0) time_label = Label(self.window,textvariable=self.time_var, fg='white', bg='black', font=('DINPro-Black',20), width=8) time_label.grid(row=0,column=2) self.pause_label = Label(self.window,text='PAUSE', fg='white',bg='black', font=('DINPro-Black',20),width=8) def pause_game(self): '''changes the UI to show the game is paused''' if 'row' in self.pause_label.grid_info(): self.pause_label.grid_forget() else: self.pause_label.grid(row=0,column=2) def end_round_kill_screen(self, canvas, string, player): '''creates the end of round kill screen''' self.end_round_frame = Frame(self.window, background='#AF0000',bd=4) self.end_round_frame.grid(row=1, column=0, columnspan=6) if player is not None: winner_image = Label(self.end_round_frame, image=self.icons[player.player_number-1], borderwidth=18) winner_image.grid(row=0, column=0) end_kill_label=Label(self.end_round_frame, text=string+' ', font=('DINPro-Black',25),borderwidth=9) end_kill_label.grid(row=0, column=1) def kill_end_round_screen(self): '''removes the end of round screen''' self.end_round_frame.grid_forget() def create_player_score(self, player_num): '''creates a score counter for a player''' col = player_num*3 string = 'player'+str(player_num+1) self.label_vars[string] = IntVar() self.label_vars[string].set(0) self.label[string] = [] self.label[string].append(Label(self.window, image=self.icons[player_num])) self.label[string][0].grid(row=0,column=col,sticky='e') self.label[string][0].configure(background='black') self.label[string].append(col) self.label[string].append(Label(self.window, textvariable=self.label_vars[string], borderwidth=6, padx=3, font=('DINPro-Black', 16), fg='black', bg='green')) self.label[string][2].grid(row=0,column=col+1,sticky='w',padx=0) self.label[string][2].configure(highlightcolor='white') def settings(self): '''settings button (not complete)''' button = Button(self.window, text='settings') button.grid(row=0, column=4,sticky='e',columnspan=2, padx=(0,5)) button.columnconfigure(10,weight=9)
class Graphics(object): def __init__(self, canvas, rows, cols, size, window): '''initialises the graphics object and its properties''' self.canvas = canvas self.window = window self.rows = rows * 2 + 1 self.cols = cols * 2 + 1 self.size = size / 2 self.label = {} self.label_vars = {} self.icons = (ImageTk.PhotoImage(file='png/faceicon0.png'), ImageTk.PhotoImage(file='png/faceicon1.png')) self.draw_static_grid() self.draw_changing_grid() self.info_labels() self.make_creator_label() def make_creator_label(self): self.canvas.create_text(self.cols * self.size / 2 + self.size / 2, self.rows * self.size + self.size * 2 / 3 + 2, text='Created by Abel Svoboda, 08/07/15') def draw_static_grid(self): '''draws the grid that is made at the start of the game''' hardblock = PhotoImage(file='gifs/hardblock.gif') label = Label(image=hardblock) label.image = hardblock #keeping a reference self.regular = {} self.absolute = {} for col in range(self.cols): for row in range(self.rows): left = col * self.size right = left + self.size + .5 * self.size top = row * self.size bot = top + self.size + .5 * self.size left += .5 * self.size top += .5 * self.size if row%2==0 and col%2==0 or \ row==0 or col==0 or \ row==self.rows-1 or col==self.cols-1: #hardblock self.absolute[(col - 1, row - 1)] = self.canvas.create_image( (left + right) / 2, (top + bot) / 2, image=hardblock) else: #walkable self.regular[(col - 1, row - 1)] = self.canvas.create_rectangle( left, top, right, bot, fill='#307100', width=0) def draw_changing_grid(self): '''draws the grid that is made at the start of each round''' softblock = PhotoImage(file='gifs/softblock.gif') label = Label(image=softblock) label.image = softblock #keeping a reference self.rocks = {} for col in range(self.cols): for row in range(self.rows): left = col * self.size right = left + self.size + .5 * self.size top = row * self.size bot = top + self.size + .5 * self.size left += .5 * self.size top += .5 * self.size if (row==1 or row==2) and (col==1 or col==2) or \ (row==self.rows-2 or row==self.rows-3) and (col==self.cols-2 or col==self.cols-3) or \ row%2==0 and col%2==0 or \ row==0 or col==0 or row==self.rows-1 or col==self.cols-1: pass elif randint(0, 100) < 50: #soft block density self.rocks[(col - 1, row - 1)] = self.canvas.create_image( (left + right) / 2, (top + bot) / 2, image=softblock) def info_labels(self): '''creates some labels on the UI''' self.time_var = StringVar() self.time_var.set(0) time_label = Label(self.window, textvariable=self.time_var, fg='white', bg='black', font=('DINPro-Black', 20), width=8) time_label.grid(row=0, column=2) self.pause_label = Label(self.window, text='PAUSE', fg='white', bg='black', font=('DINPro-Black', 20), width=8) def pause_game(self): '''changes the UI to show the game is paused''' if 'row' in self.pause_label.grid_info(): self.pause_label.grid_forget() else: self.pause_label.grid(row=0, column=2) def end_round_kill_screen(self, canvas, string, player): '''creates the end of round kill screen''' self.end_round_frame = Frame(self.window, background='#AF0000', bd=4) self.end_round_frame.grid(row=1, column=0, columnspan=6) if player is not None: winner_image = Label(self.end_round_frame, image=self.icons[player.player_number - 1], borderwidth=18) winner_image.grid(row=0, column=0) end_kill_label = Label(self.end_round_frame, text=string + ' ', font=('DINPro-Black', 25), borderwidth=9) end_kill_label.grid(row=0, column=1) def kill_end_round_screen(self): '''removes the end of round screen''' self.end_round_frame.grid_forget() def create_player_score(self, player_num): '''creates a score counter for a player''' col = player_num * 3 string = 'player' + str(player_num + 1) self.label_vars[string] = IntVar() self.label_vars[string].set(0) self.label[string] = [] self.label[string].append( Label(self.window, image=self.icons[player_num])) self.label[string][0].grid(row=0, column=col, sticky='e') self.label[string][0].configure(background='black') self.label[string].append(col) self.label[string].append( Label(self.window, textvariable=self.label_vars[string], borderwidth=6, padx=3, font=('DINPro-Black', 16), fg='black', bg='green')) self.label[string][2].grid(row=0, column=col + 1, sticky='w', padx=0) self.label[string][2].configure(highlightcolor='white') def settings(self): '''settings button (not complete)''' button = Button(self.window, text='settings') button.grid(row=0, column=4, sticky='e', columnspan=2, padx=(0, 5)) button.columnconfigure(10, weight=9)
class BannerFrame(Frame): ''' Frame inheritance class for banner. ''' def __init__(self, app, *args, **kwargs): ''' Constructor. ''' self.__app = app # Reference to main application class self.__master = self.__app.get_master() # Reference to root class (Tk) Frame.__init__(self, self.__master, *args, **kwargs) self._time = StringVar() self._lat = StringVar() self._lon = StringVar() self._alt = StringVar() self._speed = StringVar() self._alt_u = StringVar() self._speed_u = StringVar() self._track = StringVar() self._dop = StringVar() self._hvdop = StringVar() self._hvacc = StringVar() self._fix = StringVar() self._siv = StringVar() self._sip = StringVar() self._status = False self._show_advanced = True self._bgcol = BGCOL self._fgcol = FGCOL self.config(bg=self._bgcol) self._img_conn = ImageTk.PhotoImage(Image.open(ICON_CONN)) self._img_connfile = ImageTk.PhotoImage(Image.open(ICON_LOGREAD)) self._img_disconn = ImageTk.PhotoImage(Image.open(ICON_DISCONN)) self.width, self.height = self.get_size() self._body() self._do_layout() self._attach_events() def _body(self): ''' Set up frame and widgets. ''' for i in range(2, 5): self.grid_columnconfigure(i, weight=1) self.grid_rowconfigure(0, weight=1) self.grid_rowconfigure(1, weight=1) self._frm_connect = Frame(self, bg=BGCOL) self._frm_toggle = Frame(self, bg=BGCOL) self._frm_basic = Frame(self, bg=BGCOL, relief=SUNKEN) self._frm_advanced = Frame(self, bg=BGCOL) self.option_add("*Font", self.__app.font_md2) self._lbl_ltime = Label(self._frm_basic, text="utc:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_llat = Label(self._frm_basic, text="lat:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_llon = Label(self._frm_basic, text="lon:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_lalt = Label(self._frm_basic, text="alt:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_lspd = Label(self._frm_basic, text="speed:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_ltrk = Label(self._frm_basic, text="track:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._btn_toggle = Button(self._frm_toggle, text=ADVON, width=3, command=self._toggle_advanced) self._lbl_lfix = Label(self._frm_basic, text="fix:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_lsiv = Label(self._frm_advanced, text="siv:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_lsip = Label(self._frm_advanced, text="sip:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_lpdop = Label(self._frm_advanced, text="pdop:", bg=self._bgcol, fg=self._fgcol, anchor=N) self._lbl_lacc = Label(self._frm_advanced, text="acc:", bg=self._bgcol, fg=self._fgcol, anchor=N) self.option_add("*Font", self.__app.font_lg) self._lbl_status_preset = Label(self._frm_connect, bg=self._bgcol, image=self._img_conn, fg="blue") self._lbl_time = Label(self._frm_basic, textvariable=self._time, bg=self._bgcol, fg="cyan") self._lbl_lat = Label(self._frm_basic, textvariable=self._lat, bg=self._bgcol, fg="orange") self._lbl_lon = Label(self._frm_basic, textvariable=self._lon, bg=self._bgcol, fg="orange") self._lbl_alt = Label(self._frm_basic, textvariable=self._alt, bg=self._bgcol, fg="orange") self._lbl_spd = Label(self._frm_basic, textvariable=self._speed, bg=self._bgcol, fg="deepskyblue") self._lbl_trk = Label(self._frm_basic, textvariable=self._track, bg=self._bgcol, fg="deepskyblue") self._lbl_fix = Label(self._frm_basic, textvariable=self._fix, bg=self._bgcol, fg="white") self._lbl_siv = Label(self._frm_advanced, textvariable=self._siv, bg=self._bgcol, fg="yellow") self._lbl_sip = Label(self._frm_advanced, textvariable=self._sip, bg=self._bgcol, fg="yellow") self._lbl_pdop = Label(self._frm_advanced, textvariable=self._dop, bg=self._bgcol, fg="mediumpurple2") self.option_add("*Font", self.__app.font_sm) self._lbl_lalt_u = Label(self._frm_basic, textvariable=self._alt_u, bg=self._bgcol, fg="orange", anchor=S) self._lbl_lspd_u = Label(self._frm_basic, textvariable=self._speed_u, bg=self._bgcol, fg="deepskyblue", anchor=S) self._lbl_hvdop = Label(self._frm_advanced, textvariable=self._hvdop, bg=self._bgcol, fg="mediumpurple2") self._lbl_hvacc = Label(self._frm_advanced, textvariable=self._hvacc, bg=self._bgcol, fg="aquamarine2") self._lbl_lacc_u = Label(self._frm_advanced, textvariable=self._alt_u, bg=self._bgcol, fg="aquamarine2", anchor=N) def _do_layout(self): ''' Position widgets in frame. ''' self._lbl_status_preset.grid(column=0, row=0, padx=8, pady=3, sticky=W) self._lbl_ltime.grid(column=1, row=0, pady=3, sticky=W) self._lbl_time.grid(column=2, row=0, pady=3, sticky=W) self._lbl_llat.grid(column=3, row=0, pady=3, sticky=W) self._lbl_lat.grid(column=4, row=0, pady=3, sticky=W) self._lbl_llon.grid(column=5, row=0, pady=3, sticky=W) self._lbl_lon.grid(column=6, row=0, pady=3, sticky=W) self._lbl_lalt.grid(column=7, row=0, pady=3, sticky=W) self._lbl_alt.grid(column=8, row=0, pady=3, sticky=W) self._lbl_lalt_u.grid(column=9, row=0, pady=0, sticky=W) self._lbl_lspd.grid(column=10, row=0, pady=3, sticky=W) self._lbl_spd.grid(column=11, row=0, pady=3, sticky=W) self._lbl_lspd_u.grid(column=12, row=0, pady=0, sticky=W) self._lbl_ltrk.grid(column=13, row=0, pady=3, sticky=W) self._lbl_trk.grid(column=14, row=0, pady=3, sticky=W) self._lbl_lfix.grid(column=15, row=0, pady=3, sticky=W) self._lbl_fix.grid(column=16, row=0, pady=3, sticky=W) self._lbl_lsiv.grid(column=0, row=0, pady=3, sticky=W) self._lbl_siv.grid(column=1, row=0, pady=3, sticky=W) self._lbl_lsip.grid(column=2, row=0, pady=3, sticky=W) self._lbl_sip.grid(column=3, row=0, pady=3, sticky=W) self._lbl_lpdop.grid(column=4, row=0, pady=3, sticky=W) self._lbl_pdop.grid(column=5, row=0, pady=3, sticky=W) self._lbl_hvdop.grid(column=6, row=0, pady=0, sticky=W) self._lbl_lacc.grid(column=7, row=0, pady=3, sticky=W) self._lbl_hvacc.grid(column=8, row=0, pady=0, sticky=W) self._lbl_lacc_u.grid(column=9, row=0, pady=0, sticky=W) self._btn_toggle.grid(column=0, row=0, padx=8, pady=3, sticky=(N, E)) self._toggle_advanced() def _toggle_advanced(self): ''' Toggle advanced banner frame on or off. ''' self._frm_connect.grid(column=0, row=0, rowspan=2, pady=3, ipadx=3, ipady=3, sticky=(N, W)) self._frm_basic.grid(column=1, row=0, pady=3, sticky=(W)) self._frm_toggle.grid(column=5, row=0, rowspan=2, pady=3, sticky=(N, E)) self._show_advanced = not self._show_advanced if self._show_advanced: self._frm_advanced.grid(column=1, row=1, pady=3, sticky=(W)) self._btn_toggle.config(text=ADVON) else: self._frm_advanced.grid_forget() self._btn_toggle.config(text=ADVOFF) def _attach_events(self): ''' Bind events to frame. ''' self.bind("<Configure>", self._on_resize) def update_banner(self, **kwargs): ''' Sets text of banner from keyword parms. ''' settings = self.__app.frm_settings.get_settings() disp_format = settings['format'] units = settings['units'] if 'time' in kwargs: self._time.set(kwargs['time']) if 'lat' in kwargs: if kwargs['lat'] == '': self._lat.set('N/A') else: if disp_format == DMS: self._lat.set(deg2dms(kwargs['lat'], 'lat')) elif disp_format == DMM: self._lat.set(deg2dmm(kwargs['lat'], 'lat')) else: self._lat.set(round(kwargs['lat'], 5)) if 'lon' in kwargs: if kwargs['lon'] == '': self._lon.set('N/A') else: if disp_format == DMS: self._lon.set(deg2dms(kwargs['lon'], 'lon')) elif disp_format == DMM: self._lon.set(deg2dmm(kwargs['lon'], 'lon')) else: self._lon.set(round(kwargs['lon'], 5)) if 'alt' in kwargs: if kwargs['alt'] is None: self._alt.set('N/A') self._alt_u.set('') else: if units in (UI, UIK): self._alt.set(round(m2ft(float(kwargs['alt'])), 1)) self._alt_u.set('ft') else: self._alt.set(round(kwargs['alt'], 1)) self._alt_u.set('m') if 'speed' in kwargs: if kwargs['speed'] is None: self._speed.set('N/A') self._speed_u.set('') else: if units == UI: self._speed.set(round(ms2mph(float(kwargs['speed'])), 1)) self._speed_u.set('mph') elif units == UIK: self._speed.set(round(ms2knots(float(kwargs['speed'])), 1)) self._speed_u.set('knots') elif units == UMK: self._speed.set(round(ms2kmph(float(kwargs['speed'])), 1)) self._speed_u.set('kmph') else: self._speed.set(round(kwargs['speed'], 1)) self._speed_u.set('m/s') if 'track' in kwargs: if kwargs['track'] is None: self._track.set('N/A') else: self._track.set(str(round(kwargs['track'], 1))) if 'siv' in kwargs: self._siv.set(str(kwargs['siv']).zfill(2)) if 'sip' in kwargs: self._sip.set(str(kwargs['sip']).zfill(2)) if 'dop' in kwargs: dop = kwargs['dop'] self._dop.set(str(dop) + " " + UBXMessage.dop2str(dop)) if 'hdop' in kwargs and 'vdop' in kwargs: self._hvdop.set("hdop " + str(kwargs['hdop']) + "\nvdop " + str(kwargs['vdop'])) if 'hacc' in kwargs and 'vacc' in kwargs: if units in (UI, UIK): hacc = round(m2ft(kwargs['hacc']), 1) vacc = round(m2ft(kwargs['vacc']), 1) else: hacc = round(kwargs['hacc'], 1) vacc = round(kwargs['vacc'], 1) self._hvacc.set("hacc " + str(hacc) + "\nvacc " + str(vacc)) if 'fix' in kwargs: if kwargs['fix'] in ('3D', '3D + DR'): self._lbl_fix.config(fg="green2") elif kwargs['fix'] in ('2D', 'DR'): self._lbl_fix.config(fg="orange") else: self._lbl_fix.config(fg="red") self._fix.set(kwargs['fix']) if 'status' in kwargs: self._status = kwargs['status'] if self._status == CONNECTED: self._lbl_status_preset.configure(image=self._img_conn) elif self._status == CONNECTED_FILE: self._lbl_status_preset.configure(image=self._img_connfile) else: self._lbl_status_preset.configure(image=self._img_disconn) def _set_fontsize(self): ''' Adjust font sizes according to frame size ''' w = self.width # Cater for slightly different font behaviour on Linux if system() in ("W32", "Darwin"): val = 55 lbl = 75 sup = 85 else: val = 70 lbl = 85 sup = 95 sz = min(int(w / val), 18) self._lbl_status_preset.config(font=font.Font(size=sz)) self._lbl_time.config(font=font.Font(size=sz)) self._lbl_lat.config(font=font.Font(size=sz)) self._lbl_lon.config(font=font.Font(size=sz)) self._lbl_alt.config(font=font.Font(size=sz)) self._lbl_spd.config(font=font.Font(size=sz)) self._lbl_trk.config(font=font.Font(size=sz)) self._lbl_pdop.config(font=font.Font(size=sz)) self._lbl_fix.config(font=font.Font(size=sz)) self._lbl_sip.config(font=font.Font(size=sz)) self._lbl_siv.config(font=font.Font(size=sz)) sz = min(int(w / lbl), 14) self._lbl_ltime.config(font=font.Font(size=sz)) self._lbl_llat.config(font=font.Font(size=sz)) self._lbl_llon.config(font=font.Font(size=sz)) self._lbl_lalt.config(font=font.Font(size=sz)) self._lbl_lspd.config(font=font.Font(size=sz)) self._lbl_ltrk.config(font=font.Font(size=sz)) self._lbl_lpdop.config(font=font.Font(size=sz)) self._lbl_lfix.config(font=font.Font(size=sz)) self._lbl_lsip.config(font=font.Font(size=sz)) self._lbl_lsiv.config(font=font.Font(size=sz)) self._lbl_lacc.config(font=font.Font(size=sz)) sz = min(int(w / sup), 12) self._lbl_lalt_u.config(font=font.Font(size=sz)) self._lbl_lspd_u.config(font=font.Font(size=sz)) self._lbl_hvdop.config(font=font.Font(size=sz)) self._lbl_hvacc.config(font=font.Font(size=sz)) def _on_resize(self, event): ''' Resize frame ''' self.width, self.height = self.get_size() self._set_fontsize() def get_size(self): ''' Get current frame size. ''' self.update_idletasks() # Make sure we know about any resizing width = self.winfo_width() height = self.winfo_height() return (width, height)
class ToggleFrame(Frame): """ Creates a toggle frame for optional functions """ def __init__(self, parent): Frame.__init__(self, parent) self.show = IntVar() self.show.set(0) # if MY_OS == 'Windows': xpad = 0 ypad = 5 basefont = 10 spacepad = 152 elif MY_OS == 'Linux': xpad = 7 ypad = 5 basefont = 12 spacepad = 172 else: xpad = 7 ypad = 5 basefont = 14 spacepad = 175 # self.show_frame = Frame(self) self.space = Label(self.show_frame, text='') self.space.configure(fg=hokiestone, bg=hokiestone, relief='flat') self.space.grid(column=0, row=0, pady=0, padx=spacepad, sticky='e') self.togButton = Checkbutton(self.show_frame, text='Show Options', command=self.tog_options, variable=self.show, fg='black', bg=hokiestone, bd=4, font=('Arial', basefont), justify='left') self.togButton.grid(column=1, row=0, pady=0, padx=xpad, sticky='w') self.prompt = IntVar() self.prompt.set(0) self.promptButton = Checkbutton(self.show_frame, text='Prompt after Each Action?', variable=self.prompt, fg='black', bg=hokiestone, bd=4, font=('Arial', basefont), justify='left') self.promptButton.grid(column=2, row=0, pady=0, padx=xpad, sticky='w') # self.sub_frame = Frame(self) labl4 = Label(self.sub_frame, text='Options:') labl4.configure(fg='black', bg=vtgray, bd=0, font=('Arial', basefont), height=2, width=9, justify='center') labl4.grid(column=0, row=0, pady=5, padx=5, sticky='w') # Options checkbuttons # Metadata self.metavar = IntVar(self.sub_frame) meta_chk = Checkbutton(self.sub_frame, text='Create min\nmetadata files', variable=self.metavar, fg='black', bg=hokiestone, relief='flat', bd=4, font=('Arial', basefont), justify='left') meta_chk.grid(column=1, row=0, pady=5, padx=xpad) # Register objects self.regisvar = IntVar(self) regis_chk = Checkbutton(self.sub_frame, text='Register\nObjects', variable=self.regisvar, fg='black', bg=hokiestone, relief='flat', bd=4, font=('Arial', basefont), justify='left') regis_chk.grid(column=2, row=0, pady=5, padx=xpad) # Inventory self.invenvar = IntVar(self) inv_chk = Checkbutton(self.sub_frame, text='Generate\n\'manifest.csv\'', variable=self.invenvar, fg='black', bg=hokiestone, relief='flat', bd=4, font=('Arial', basefont), justify='left') inv_chk.grid(column=3, row=0, pady=5, padx=xpad) # BagIt self.bagitvar = IntVar(self) bagit_chk = Checkbutton(self.sub_frame, text='BagIt\n', variable=self.bagitvar, fg='black', bg=hokiestone, relief='flat', bd=4, font=('Arial', basefont), justify='left') bagit_chk.grid(column=4, row=0, pady=5, padx=xpad) # Tar self.tarvar = IntVar(self) tar_chk = Checkbutton(self.sub_frame, text='TAR\nObjects', variable=self.tarvar, fg='black', bg=hokiestone, relief='flat', bd=4, font=('Arial', basefont), justify='left') tar_chk.grid(column=5, row=0, pady=5, padx=xpad) # Transfer manifest self.transvar = IntVar(self) trans_chk = Checkbutton(self.sub_frame, text='Transfer\nManifest', variable=self.transvar, fg='black', bg=hokiestone, relief='flat', bd=4, font=('Arial', basefont), justify='left') trans_chk.grid(column=6, row=0, pady=5, padx=xpad) # Set defaults to "checked" self.metavar.set(1) self.regisvar.set(1) self.invenvar.set(1) self.bagitvar.set(1) self.tarvar.set(1) self.transvar.set(1) # self.sub_frame.configure(bd=2, bg=hokiestone, relief='raised') self.show_frame.configure(bd=2, bg=hokiestone, relief='flat') self.show_frame.grid(column=0, row=3, pady=0, padx=0, sticky='nsew') def tog_options(self): if self.show.get() == 1: self.sub_frame.grid(column=0, row=0, pady=0, padx=0, sticky='nsew') self.togButton.configure(text='Hide Options') else: self.sub_frame.grid_forget() self.togButton.configure(text='Show Options')
class SettingsFrame(Frame): ''' Frame inheritance class for application settings and controls. ''' def __init__(self, app, *args, **kwargs): ''' Constructor. ''' self.__app = app # Reference to main application class self.__master = self.__app.get_master() # Reference to root class (Tk) Frame.__init__(self, self.__master, *args, **kwargs) self._show_advanced = False self._settings = {} self._ports = () self._port = StringVar() self._port_desc = StringVar() self._baudrate = IntVar() self._databits = IntVar() self._stopbits = DoubleVar() self._parity = StringVar() self._rtscts = IntVar() self._xonxoff = IntVar() self._protocol = IntVar() self._raw = IntVar() self._autoscroll = IntVar() self._maxlines = IntVar() self._webmap = IntVar() self._mapzoom = IntVar() self._units = StringVar() self._format = StringVar() self._datalog = IntVar() self._record_track = IntVar() self._noports = True self._validsettings = True self._logpath = None self._trackpath = None self._img_conn = ImageTk.PhotoImage(Image.open(ICON_CONN)) self._img_disconn = ImageTk.PhotoImage(Image.open(ICON_DISCONN)) self._img_ubxconfig = ImageTk.PhotoImage(Image.open(ICON_UBXCONFIG)) self._img_dataread = ImageTk.PhotoImage(Image.open(ICON_LOGREAD)) self._body() self._do_layout() self._get_ports() self._reset() def _body(self): ''' Set up frame and widgets. ''' for i in range(4): self.grid_columnconfigure(i, weight=1) self.grid_rowconfigure(0, weight=1) self.option_add("*Font", self.__app.font_sm) # Serial port settings self._frm_basic = Frame(self) self._lbl_port = Label(self._frm_basic, text="Port") self._lbx_port = Listbox(self._frm_basic, border=2, relief="sunken", bg=ENTCOL, width=28, height=5, justify=LEFT, exportselection=False) self._scr_portv = Scrollbar(self._frm_basic, orient=VERTICAL) self._scr_porth = Scrollbar(self._frm_basic, orient=HORIZONTAL) self._lbx_port.config(yscrollcommand=self._scr_portv.set) self._lbx_port.config(xscrollcommand=self._scr_porth.set) self._scr_portv.config(command=self._lbx_port.yview) self._scr_porth.config(command=self._lbx_port.xview) self._lbx_port.bind("<<ListboxSelect>>", self._on_select_port) self._lbl_baudrate = Label(self._frm_basic, text="Baud rate") self._spn_baudrate = Spinbox(self._frm_basic, values=(BAUDRATES), width=8, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._baudrate) self._btn_toggle = Button(self._frm_basic, text=ADVOFF, width=3, command=self._toggle_advanced) self._frm_advanced = Frame(self) self._lbl_databits = Label(self._frm_advanced, text="Data Bits") self._spn_databits = Spinbox(self._frm_advanced, values=(8, 7, 6, 5), width=3, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._databits) self._lbl_stopbits = Label(self._frm_advanced, text="Stop Bits") self._spn_stopbits = Spinbox(self._frm_advanced, values=(2, 1.5, 1), width=3, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._stopbits) self._lbl_parity = Label(self._frm_advanced, text="Parity") self._spn_parity = Spinbox(self._frm_advanced, values=("None", "Even", "Odd", "Mark", "Space"), width=6, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._parity) self._chk_rts = Checkbutton(self._frm_advanced, text="RTS/CTS", variable=self._rtscts) self._chk_xon = Checkbutton(self._frm_advanced, text="Xon/Xoff", variable=self._xonxoff) self._frm_buttons = Frame(self) self._btn_connect = Button(self._frm_buttons, width=45, height=35, image=self._img_conn, command=lambda: self.__app.serial_handler.connect()) self._btn_disconnect = Button(self._frm_buttons, width=45, height=35, image=self._img_disconn, command=lambda: self.__app.serial_handler.disconnect(), state=DISABLED) self._btn_connect_file = Button(self._frm_buttons, width=45, height=35, image=self._img_dataread, command=lambda: self._on_data_stream()) self._lbl_status_preset = Label(self._frm_buttons, font=self.__app.font_md2, text='') # Other configuration options self._frm_options = Frame(self) self._lbl_protocol = Label(self._frm_options, text=LBLPROTDISP) self._rad_nmea = Radiobutton(self._frm_options, text="NMEA", variable=self._protocol, value=NMEA_PROTOCOL) self._rad_ubx = Radiobutton(self._frm_options, text="UBX", variable=self._protocol, value=UBX_PROTOCOL) self._rad_all = Radiobutton(self._frm_options, text="ALL", variable=self._protocol, value=MIXED_PROTOCOL) self._lbl_consoledisplay = Label(self._frm_options, text=LBLDATADISP) self._rad_parsed = Radiobutton(self._frm_options, text="Parsed", variable=self._raw, value=0) self._rad_raw = Radiobutton(self._frm_options, text="Raw", variable=self._raw, value=1) self._lbl_format = Label(self._frm_options, text="Degrees Format") self._spn_format = Spinbox(self._frm_options, values=(DDD, DMS, DMM), width=6, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._format) self._lbl_units = Label(self._frm_options, text="Units") self._spn_units = Spinbox(self._frm_options, values=(UMM, UIK, UI, UMK), width=13, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._units) self._chk_scroll = Checkbutton(self._frm_options, text="Autoscroll", variable=self._autoscroll) self._spn_maxlines = Spinbox(self._frm_options, values=("100", "200", "500", "1000", "2000"), width=6, readonlybackground=ENTCOL, wrap=True, textvariable=self._maxlines, state=READONLY) self._chk_webmap = Checkbutton(self._frm_options, text="Web Map Zoom", variable=self._webmap) self._scl_mapzoom = Scale(self._frm_options, from_=1, to=20, orient=HORIZONTAL, relief="sunken", bg=ENTCOL, variable=self._mapzoom) self._chk_datalog = Checkbutton(self._frm_options, text=LBLDATALOG, variable=self._datalog, command=lambda: self._on_data_log()) self._chk_recordtrack = Checkbutton(self._frm_options, text=LBLTRACKRECORD, variable=self._record_track, command=lambda: self._on_record_track()) self._lbl_ubxconfig = Label(self._frm_options, text=LBLUBXCONFIG) self._btn_ubxconfig = Button(self._frm_options, width=45, height=35, text='UBX', image=self._img_ubxconfig, command=lambda: self._on_ubx_config(), state=DISABLED) def _do_layout(self): ''' Position widgets in frame. ''' self._frm_basic.grid(column=0, row=0, columnspan=4, sticky=(W, E)) self._lbl_port.grid(column=0, row=0, sticky=(W)) self._lbx_port.grid(column=1, row=0, sticky=(W, E), padx=3, pady=3) self._scr_portv.grid(column=2, row=0, sticky=(N, S)) self._scr_porth.grid(column=1, row=1, sticky=(E, W)) self._lbl_baudrate.grid(column=0, row=2, sticky=(W)) self._spn_baudrate.grid(column=1, row=2, sticky=(W), padx=3, pady=3) self._btn_toggle.grid(column=2, row=2, sticky=(E)) self._frm_advanced.grid_forget() self._lbl_databits.grid(column=0, row=0, sticky=(W)) self._spn_databits.grid(column=1, row=0, sticky=(W), padx=3, pady=3) self._lbl_stopbits.grid(column=2, row=0, sticky=(W)) self._spn_stopbits.grid(column=3, row=0, sticky=(W), padx=3, pady=3) self._lbl_parity.grid(column=0, row=1, sticky=(W)) self._spn_parity.grid(column=1, row=1, sticky=(W), padx=3, pady=3) self._chk_rts.grid(column=2, row=1, sticky=(W)) self._chk_xon.grid(column=3, row=1, sticky=(W), padx=3, pady=3) ttk.Separator(self).grid(column=0, row=2, columnspan=4, padx=3, pady=3, sticky=(W, E)) self._frm_buttons.grid(column=0, row=3, columnspan=4, sticky=(W, E)) self._btn_connect.grid(column=0, row=0, padx=3, pady=3) self._btn_connect_file.grid(column=1, row=0, padx=3, pady=3) self._btn_disconnect.grid(column=3, row=0, padx=3, pady=3) ttk.Separator(self).grid(column=0, row=7, columnspan=4, padx=3, pady=3, sticky=(W, E)) self._frm_options.grid(column=0, row=8, columnspan=4, sticky=(W, E)) self._lbl_protocol.grid(column=0, row=0, padx=3, pady=3, sticky=(W)) self._rad_nmea.grid(column=1, row=0, padx=0, pady=0, sticky=(W)) self._rad_ubx.grid(column=2, row=0, padx=0, pady=0, sticky=(W)) self._rad_all.grid(column=3, row=0, padx=0, pady=0, sticky=(W)) self._lbl_consoledisplay.grid(column=0, row=1, padx=2, pady=3, sticky=(W)) self._rad_parsed.grid(column=1, row=1, padx=1, pady=3, sticky=(W)) self._rad_raw.grid(column=2, row=1, padx=2, pady=3, sticky=(W)) self._lbl_format.grid(column=0, row=2, padx=3, pady=3, sticky=(W)) self._spn_format.grid(column=1, row=2, padx=2, pady=3, sticky=(W)) self._lbl_units.grid(column=0, row=3, padx=3, pady=3, sticky=(W)) self._spn_units.grid(column=1, row=3, columnspan=3, padx=2, pady=3, sticky=(W)) self._chk_scroll.grid(column=0, row=4, padx=3, pady=3, sticky=(W)) self._spn_maxlines.grid(column=1, row=4, columnspan=3, padx=3, pady=3, sticky=(W)) self._chk_webmap.grid(column=0, row=5, sticky=(W)) self._scl_mapzoom.grid(column=1, row=5, columnspan=3, sticky=(W)) self._chk_datalog.grid(column=0, row=6, padx=3, pady=3, sticky=(W)) self._chk_recordtrack.grid(column=0, row=7, padx=3, pady=3, sticky=(W)) ttk.Separator(self._frm_options).grid(column=0, row=8, columnspan=4, padx=3, pady=3, sticky=(W, E)) self._lbl_ubxconfig.grid(column=0, row=9, padx=3, pady=3, sticky=(W)) self._btn_ubxconfig.grid(column=1, row=9, padx=3, pady=3, sticky=(W)) def _on_select_port(self, *args, **kwargs): ''' Get selected port from listbox and set global variable. ''' idx = self._lbx_port.curselection() if idx == "": idx = 0 port_orig = self._lbx_port.get(idx) port = port_orig[0:port_orig.find(":")] desc = port_orig[port_orig.find(":") + 1:] if desc == '': desc = "device" self._port.set(port) self._port_desc.set(desc) def _on_ubx_config(self, *args, **kwargs): ''' Open UBX configuration dialog panel. ''' self.__app.ubxconfig() def _on_data_log(self): ''' Start or stop data logger ''' if self._datalog.get() == 1: self._logpath = self.__app.file_handler.set_logfile_path() if self._logpath is not None: self.__app.set_status("Data logging enabled: " + self._logpath, "green") else: self._datalog.set(False) else: self._logpath = None self._datalog.set(False) # self.__app.file_handler.close_logfile() self.__app.set_status("Data logging disabled", "blue") def _on_record_track(self): ''' Start or stop track recorder ''' if self._record_track.get() == 1: self._trackpath = self.__app.file_handler.set_trackfile_path() if self._trackpath is not None: self.__app.set_status("Track recording enabled: " + self._trackpath, "green") else: self._record_track.set(False) else: self._trackpath = None self._record_track.set(False) # self.__app.file_handler.close_trackfile() self.__app.set_status("Track recording disabled", "blue") def _on_data_stream(self): ''' Start data file streamer ''' self._logpath = self.__app.file_handler.open_logfile_input() if self._logpath is not None: self.__app.set_status("") self.__app.serial_handler.connect_file() def _toggle_advanced(self): ''' Toggle advanced serial port settings panel on or off ''' self._show_advanced = not self._show_advanced if self._show_advanced: self._frm_advanced.grid(column=0, row=1, columnspan=3, sticky=(W, E)) self._btn_toggle.config(text=ADVON) else: self._frm_advanced.grid_forget() self._btn_toggle.config(text=ADVOFF) def _get_ports(self): ''' Populate list of available serial ports using pyserial comports tool. If no ports found, disable all connection-dependent widgets. Attempt to preselect the first port that has a recognisable GPS designation in its description (usually only works on Posix platforms - Windows doesn't parse UART device desc or HWID) ''' self._ports = sorted(comports()) init_idx = 0 port = '' desc = '' if len(self._ports) > 0: for idx, (port, desc, _) in enumerate(self._ports, 1): self._lbx_port.insert(idx, port + ": " + desc) for kgp in KNOWNGPS: if kgp in desc: init_idx = idx break self._noports = False else: self._noports = True self.set_controls(NOPORTS) self._lbx_port.activate(init_idx) self._port.set(port) self._port_desc.set(desc) def _reset(self): ''' Reset settings to defaults. ''' self._baudrate.set(BAUDRATES[4]) # 9600 self._databits.set(8) self._stopbits.set(1) self._parity.set("None") self._rtscts.set(False) self._xonxoff.set(False) self._protocol.set(MIXED_PROTOCOL) self._format.set(DDD) self._units.set(UMM) self._autoscroll.set(1) self._maxlines.set(300) self._raw.set(False) self._webmap.set(False) self._mapzoom.set(10) self._datalog.set(False) self._record_track.set(False) def set_controls(self, status): ''' ...for the heart of the sun. Public method to enable and disable serial port controls depending on connection status. ''' self._lbl_port.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._lbx_port.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._lbl_baudrate.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._spn_baudrate.configure(state=(READONLY if status == DISCONNECTED else DISABLED)) self._lbl_databits.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._spn_databits.configure(state=(READONLY if status == DISCONNECTED else DISABLED)) self._lbl_stopbits.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._spn_stopbits.configure(state=(READONLY if status == DISCONNECTED else DISABLED)) self._lbl_parity.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._spn_parity.configure(state=(READONLY if status == DISCONNECTED else DISABLED)) self._chk_rts.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._chk_xon.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._btn_connect.config(state=(DISABLED if status in \ (CONNECTED, CONNECTED_FILE, NOPORTS) \ else NORMAL)) self._btn_disconnect.config(state=(DISABLED if status in \ (DISCONNECTED, NOPORTS) else NORMAL)) self._chk_datalog.config(state=(DISABLED if status in \ (CONNECTED, CONNECTED_FILE, NOPORTS) \ else NORMAL)) self._chk_recordtrack.config(state=(DISABLED if status in \ (CONNECTED, CONNECTED_FILE) \ else NORMAL)) self._btn_connect_file.config(state=(DISABLED if status in \ (CONNECTED, CONNECTED_FILE) \ else NORMAL)) self._btn_ubxconfig.config(state=(DISABLED if status in \ (DISCONNECTED, CONNECTED_FILE, NOPORTS) \ else NORMAL)) self.__app.menu.options_menu.entryconfig(0, state=(DISABLED if status in \ (CONNECTED_FILE, DISCONNECTED, NOPORTS) \ else NORMAL)) def get_settings(self): ''' Public method returns all settings as a dict. ''' self._settings['port'] = self._port.get() self._settings['noports'] = self._noports self._settings['port_desc'] = self._port_desc.get() self._settings['baudrate'] = self._baudrate.get() self._settings['databits'] = self._databits.get() self._settings['stopbits'] = self._stopbits.get() self._settings['parity'] = self._parity.get() self._settings['rtscts'] = self._rtscts.get() self._settings['xonxoff'] = self._xonxoff.get() self._settings['protocol'] = self._protocol.get() self._settings['raw'] = self._raw.get() self._settings['autoscroll'] = self._autoscroll.get() self._settings['maxlines'] = self._maxlines.get() self._settings['webmap'] = self._webmap.get() self._settings['mapzoom'] = self._mapzoom.get() self._settings['units'] = self._units.get() self._settings['format'] = self._format.get() self._settings['logpath'] = self._logpath self._settings['datalogging'] = self._datalog.get() self._settings['recordtrack'] = self._record_track.get() return self._settings def get_size(self): ''' Get current frame size. ''' self.update_idletasks() # Make sure we know about any resizing return (self.winfo_width(), self.winfo_height())
class FormChildSection: def __init__(self, frm_parent, connection): self.connection = connection self.directive = Message() self.decide = True self.id_selected = 0 self.frm_child_list = LabelFrame(frm_parent) self.frm_child_crud = LabelFrame(frm_parent) self.frm_child_crud.config(fg=TEXT_COLOR, font=SUBTITLE_FONT) self.initialize_components() def initialize_components(self): """ Method that initialize the visual components for each form associated with the local administration """ # Resources for the Forms self.new_icon = PhotoImage(file=r"./Resources/create.png") self.view_icon = PhotoImage(file=r"./Resources/view.png") self.modify_icon = PhotoImage(file=r"./Resources/modify.png") self.remove_icon = PhotoImage(file=r"./Resources/delete.png") self.save_icon = PhotoImage(file=r"./Resources/save.png") self.cancel_icon = PhotoImage(file=r"./Resources/cancel.png") self.back_icon = PhotoImage(file=r"./Resources/back.png") # Components for List FRM lbl_sep1 = Label(self.frm_child_list) lbl_sep1.grid(row=0, column=0, padx=10, pady=25) self.trv_available = Treeview(self.frm_child_list, height=15, columns=('N', 'Name', 'Description', 'Data Type')) self.trv_available.heading('#0', text='ID', anchor=CENTER) self.trv_available.heading('#1', text='N', anchor=CENTER) self.trv_available.heading('#2', text='Name', anchor=CENTER) self.trv_available.heading('#3', text='Description', anchor=CENTER) self.trv_available.heading('#4', text='Data Type', anchor=CENTER) self.trv_available.column('#0', width=0, minwidth=50, stretch=NO) self.trv_available.column('#1', width=20, minwidth=20, stretch=NO) self.trv_available.column('#2', width=200, minwidth=200, stretch=NO) self.trv_available.column('#3', width=400, minwidth=400, stretch=NO) self.trv_available.column('#4', width=200, minwidth=200, stretch=NO) self.trv_available.grid(row=0, column=1, sticky=W, pady=25) vsb_trv_av = Scrollbar(self.frm_child_list, orient="vertical", command=self.trv_available.yview) vsb_trv_av.grid(row=0, column=2, pady=25, sticky=NS) self.trv_available.configure(yscrollcommand=vsb_trv_av.set) frm_aux4 = Frame(self.frm_child_list) btn_new = Button(frm_aux4, image=self.new_icon, command=self.click_new) btn_new.grid(row=0, column=0, pady=5, padx=5, sticky=E) btn_new_ttp = CreateToolTip(btn_new, 'New section') btn_view = Button(frm_aux4, image=self.view_icon, command=self.click_view) btn_view.grid(row=1, column=0, pady=5, padx=5, sticky=E) btn_view_ttp = CreateToolTip(btn_view, 'View section') btn_edit = Button(frm_aux4, image=self.modify_icon, command=self.click_update) btn_edit.grid(row=2, column=0, pady=5, padx=5, sticky=E) btn_edit_ttp = CreateToolTip(btn_edit, 'Edit section') btn_delete = Button(frm_aux4, image=self.remove_icon, command=self.click_delete) btn_delete.grid(row=3, column=0, pady=5, padx=5, sticky=E) btn_delete_ttp = CreateToolTip(btn_delete, 'Delete section') frm_aux4.grid(row=0, column=4, pady=25, padx=25, sticky=NW) # Components for CRUD FRM self.frm_aux1 = Frame(self.frm_child_crud) lbl_type = Label(self.frm_aux1, text='Data type*') lbl_type.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_type.grid(row=0, column=0, pady=10, padx=20, sticky=W) lbl_name = Label(self.frm_aux1, text='Name*') lbl_name.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_name.grid(row=1, column=0, pady=10, padx=20, sticky=W) lbl_description = Label(self.frm_aux1, text='Description*\t') lbl_description.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_description.grid(row=2, column=0, pady=10, padx=20, sticky=NW) self.cbx_data = Combobox(self.frm_aux1, state="readonly") self.cbx_data['values'] = ['Text', 'File', 'Classification'] self.cbx_data.grid(row=0, column=2, pady=10, sticky=W) self.cbx_data.bind("<<ComboboxSelected>>", self.cbx_data_selected) self.txt_name = Entry(self.frm_aux1, width=50, font=TEXT_FONT) self.txt_name.grid(row=1, column=2, pady=10, sticky=W) lbl_sep2 = Label(self.frm_aux1) lbl_sep2.grid(row=0, column=1, rowspan=3, padx=10, pady=10) self.txt_description = Text(self.frm_aux1, height=6, width=50, font=TEXT_FONT) self.txt_description.grid(row=2, column=2, pady=10, sticky=W) vsb_txt_desc = Scrollbar(self.frm_aux1, orient="vertical", command=self.txt_description.yview) vsb_txt_desc.grid(row=2, column=3, pady=10, sticky=NS) self.txt_description.configure(yscrollcommand=vsb_txt_desc.set) sep_aux1 = Separator(self.frm_aux1, orient=VERTICAL) sep_aux1.grid(row=0, column=4, sticky=NS, rowspan=4, padx=20) self.btn_save = Button(self.frm_aux1, image=self.save_icon, command=self.click_save) btn_save_ttp = CreateToolTip(self.btn_save, 'Save section') self.btn_back = Button(self.frm_aux1, image=self.back_icon, command=self.click_back) btn_back_ttp = CreateToolTip(self.btn_back, 'Go back') self.btn_cancel = Button(self.frm_aux1, image=self.cancel_icon, command=self.click_cancel) btn_cancel_ttp = CreateToolTip(self.btn_cancel, 'Cancel') self.frm_aux1.grid() # Frame for showing available classifications self.frm_aux2 = Frame(self.frm_aux1) lbl_class = Label(self.frm_aux2, text='Classification\t') lbl_class.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_class.grid(row=0, column=0, pady=10, padx=20, sticky=W) lbl_category = Label(self.frm_aux2, text='Categories') lbl_category.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_category.grid(row=1, column=0, pady=10, padx=20, sticky=NW) lbl_sep3 = Label(self.frm_aux2) lbl_sep3.grid(row=0, column=1, rowspan=2, padx=10, pady=10) self.cbx_classification = Combobox(self.frm_aux2, state="readonly") self.cbx_classification.bind("<<ComboboxSelected>>", self.cbx_class_selected) self.cbx_classification.grid(row=0, column=2, pady=10, sticky=NW) self.lbx_category = Listbox(self.frm_aux2, font=TEXT_FONT, height=10, width=50, selectmode='none') self.lbx_category.config(bg=DISABLED_COLOR) self.lbx_category.grid(row=1, column=2, pady=10, sticky=W) vsb_lbx_cat = Scrollbar(self.frm_aux2, orient="vertical", command=self.lbx_category.yview) vsb_lbx_cat.grid(row=1, column=3, pady=10, sticky=NS) self.lbx_category.configure(yscrollcommand=vsb_lbx_cat.set) def retrieve_list(self): # Remove existing elements in the list for item in self.trv_available.get_children(): self.trv_available.delete(item) self.directive = Message(action=32) self.connection = self.directive.send_directive(self.connection) # Adding elements into the list for index, item in enumerate(self.connection.message.information): elements = item.split('¥') self.trv_available.insert('', 'end', text=elements[0], values=(index + 1, summarize_text(elements[1], 200), summarize_text(elements[2], 400), summarize_text(elements[3], 200))) if len(self.trv_available.get_children()) != 0: self.trv_available.selection_set( self.trv_available.get_children()[0]) def show_frm(self): self.retrieve_list() self.frm_child_list.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def hide_frm(self): self.clear_fields() self.frm_child_list.grid_forget() self.frm_child_crud.grid_forget() def click_new(self): self.section = Section() self.txt_name.focus_set() self.frm_child_crud['text'] = 'New section' self.btn_save.grid(row=0, column=5, padx=20) self.btn_cancel.grid(row=1, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def click_view(self): if len(self.trv_available.selection()) == 1: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) self.directive = Message(action=35, information=[id_selected]) self.connection = self.directive.send_directive(self.connection) self.section = Section( section_id=id_selected, name=self.connection.message.information[0], description=self.connection.message.information[1], data_type=self.connection.message.information[2]) self.txt_name.insert(0, self.section.name) self.txt_description.insert('1.0', self.section.description) self.cbx_data.set(self.section.data_type) if self.section.data_type == 'Classification': self.section.classification_id = self.connection.message.information[ 3] self.retrieve_classifications() self.directive = Message( action=70, information=[self.section.classification_id]) self.connection = self.directive.send_directive( self.connection) self.cbx_classification.set( self.connection.message.information[0]) self.cbx_class_selected() self.frm_aux2.grid(row=3, column=0, columnspan=4, sticky=W) self.txt_name['bg'] = DISABLED_COLOR self.txt_description['bg'] = DISABLED_COLOR self.lbx_category['bg'] = DISABLED_COLOR self.txt_name['state'] = DISABLED self.txt_description['state'] = DISABLED self.cbx_data['state'] = DISABLED self.cbx_classification['state'] = DISABLED self.lbx_category['state'] = DISABLED self.frm_child_crud['text'] = 'View section' self.btn_back.grid(row=0, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_update(self): if len(self.trv_available.selection()) == 1: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) self.directive = Message(action=35, information=[id_selected, 'validate']) self.connection = self.directive.send_directive(self.connection) if self.connection.message.action == 5: # An error ocurred while trying to update the item messagebox.showerror( parent=self.frm_child_list, title='Can not update the item', message=self.connection.message.information[0]) else: self.section = Section( section_id=id_selected, name=self.connection.message.information[0], description=self.connection.message.information[1], data_type=self.connection.message.information[2]) self.txt_name.insert(0, self.section.name) self.txt_description.insert('1.0', self.section.description) self.cbx_data.set(self.section.data_type) if self.section.data_type == 'Classification': self.section.classification_id = self.connection.message.information[ 3] self.retrieve_classifications() self.directive = Message( action=70, information=[self.section.classification_id]) self.connection = self.directive.send_directive( self.connection) self.cbx_classification.set( self.connection.message.information[0]) self.cbx_class_selected() self.frm_aux2.grid(row=3, column=0, columnspan=4, sticky=W) self.frm_child_crud['text'] = 'Update section' self.btn_save.grid(row=0, column=5, padx=20) self.btn_cancel.grid(row=1, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_delete(self): if len(self.trv_available.selection()) == 1: decision = messagebox.askyesno( parent=self.frm_child_list, title='Confirmation', message='Are you sure you want to delete the item?') if decision: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) self.directive = Message(action=34, information=[id_selected]) self.connection = self.directive.send_directive( self.connection) if self.connection.message.action == 5: # An error ocurred while deleting the item messagebox.showerror( parent=self.frm_child_list, title='Can not delete the item', message=self.connection.message.information[0]) else: self.retrieve_list() else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_save(self): if self.validate_fields(): self.section.name = self.txt_name.get() self.section.description = self.txt_description.get( '1.0', 'end-1c') self.section.data_type = self.cbx_data.get() if self.section.section_id == 0: # If creating a section if self.section.data_type == 'Classification': id_class = self.classifications[ self.cbx_classification.current()] self.directive = Message(action=31, information=[ self.section.name, self.section.description, self.section.data_type, id_class ]) else: self.directive = Message(action=31, information=[ self.section.name, self.section.description, self.section.data_type ]) else: # If updating a section if self.section.data_type == 'Classification': id_class = self.classifications[ self.cbx_classification.current()] self.directive = Message(action=33, information=[ self.section.section_id, self.section.name, self.section.description, self.section.data_type, id_class ]) else: self.directive = Message(action=33, information=[ self.section.section_id, self.section.name, self.section.description, self.section.data_type ]) self.connection = self.directive.send_directive(self.connection) self.click_back() def click_back(self): self.clear_fields() self.frm_child_crud.grid_forget() self.show_frm() def click_cancel(self): decision = True if self.txt_name.get() != self.section.name or \ self.txt_description.get('1.0', 'end-1c') != self.section.description or \ self.cbx_data.get() != self.section.data_type: decision = messagebox.askyesno( parent=self.frm_child_crud, title='Cancel', message='Are you sure you want to cancel?') if decision: self.click_back() def cbx_data_selected(self, event): if self.cbx_data.get() == 'Classification': self.retrieve_classifications() self.frm_aux2.grid(row=3, column=0, columnspan=4, sticky=W) else: self.frm_aux2.grid_forget() self.txt_name.focus_set() def cbx_class_selected(self, event=None): id_class = self.classifications[self.cbx_classification.current()] self.directive = Message(action=72, information=[id_class]) self.connection = self.directive.send_directive(self.connection) self.lbx_category.delete(0, END) for index, item in enumerate(self.connection.message.information): item = item.split('¥') self.lbx_category.insert(END, '{}) {}'.format(index + 1, item[1])) def retrieve_classifications(self): self.classifications = [] self.lbx_category.delete(0, END) self.directive = Message(action=67) self.connection = self.directive.send_directive(self.connection) classifications = [] for item in self.connection.message.information: elements = item.split('¥') classifications.append(elements[1]) self.classifications.append(int(elements[0])) self.cbx_classification['values'] = [] self.cbx_classification['values'] = classifications def validate_fields(self): if len(self.txt_name.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert a name for the section') return False if len(self.txt_description.get('1.0', 'end-1c')) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert a description for the section') return False if len(self.cbx_data.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must select data type for the section') return False if self.cbx_data.get() == 'Classification' and len( self.cbx_classification.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must select a classification for this section') return False return True def clear_fields(self): self.btn_save.grid_forget() self.btn_cancel.grid_forget() self.btn_back.grid_forget() self.txt_name['state'] = NORMAL self.txt_description['state'] = NORMAL self.cbx_data['state'] = NORMAL self.cbx_classification['state'] = NORMAL self.lbx_category['state'] = NORMAL self.txt_name['bg'] = ENABLED_COLOR self.txt_description['bg'] = ENABLED_COLOR self.lbx_category['bg'] = ENABLED_COLOR self.txt_name.delete(0, END) self.txt_description.delete('1.0', 'end-1c') self.cbx_data.set('') self.cbx_classification.set('') self.lbx_category.delete(0, END) self.frm_aux2.grid_forget()
class Verfahren(): def __init__(self, tkobj): #Label - Verfahren self.lblVerf = Label(tkobj, text='Verfahren \n', font=('Arial', 15)) self.lblVerf.grid(column=0, row=0, pady=5, padx=5, sticky=(NW)) #Buttons für Verf Entries und Textfeld #Ausgabe der Entries als Liste self.all_Verf = [] self.addVerfahren = Button(tkobj, text='+', fg='Red', command=self.__addVerf) self.addVerfahren.grid(column=0, row=1, pady=5, padx=5, sticky=(NW)) self.remVerfahren = Button(tkobj, text='-', fg='Dark Blue', command=self.__remVerf) self.remVerfahren.grid(column=1, row=1, pady=5, padx=5, sticky=(NW)) self.EntryVerf = Frame(tkobj) self.EntryVerf.grid(column=0, row=2, pady=5, padx=5, sticky=(NW)) #Frame Checkbutton + Latex-Befehle self.boxframe = Frame(tkobj) self.boxframe.grid(column=1, row=2, pady=10, padx=10, sticky=NW) #Hinzufügen eines Checkbuttons self.c = BooleanVar() self.c.set(False) self.latexctn = Checkbutton(self.boxframe, text='LaTeX-Befehl aktivieren', var=self.c, command=self.LaFrhide) self.latexctn.grid(column=0, row=0, pady=5, padx=5, sticky=NW) #Frame - LaTeX-Befehle aktivieren self.LaFr = Frame(self.boxframe) self.LaFr.grid(column=2, row=0, pady=10, padx=10, sticky=N) #Button für LaTeX-Befehle self.btnit = Button(self.LaFr, text='kursiv', font=('Arial', 10, 'italic'), command=self.LaTeXitalic) self.btnit.grid(column=0, row=0, pady=5, sticky=(NW)) self.btnbd = Button(self.LaFr, text='fett', font=('Arial', 10, 'bold'), command=self.LaTeXbold) self.btnbd.grid(column=0, row=1, pady=5, sticky=(NW)) self.btnun = Button(self.LaFr, text='unterstrichen', font=('Arial', 10, 'underline'), command=self.LaTeXundl) self.btnun.grid(column=0, row=2, pady=5, sticky=(NW)) self.btntl = Button(self.LaFr, text='~', font=('Arial', 10, 'bold'), command=self.LaTeXTilde) self.btntl.grid(column=0, row=3, pady=5, sticky=(NW)) self.btntg = Button(self.LaFr, text='<', font=('Arial', 10, 'bold'), command=self.LaTeXless) self.btntg.grid(column=1, row=3, pady=5, sticky=(NW)) self.btntd = Button(self.LaFr, text='>', font=('Arial', 10, 'bold'), command=self.LaTeXgreater) self.btntd.grid(column=2, row=3, pady=5, sticky=(NW)) self.btnLi = Button(self.LaFr, text='Aufzählung', font=('Arial', 10), command=self.LaTeXBullet) self.btnLi.grid(column=0, row=4, pady=5, sticky=(NW)) self.btnim = Button(self.LaFr, text='Item', font=('Arial', 10), command=self.LaTeXItem) self.btnim.grid(column=1, row=4, pady=5, sticky=(NW)) self.btnNum = Button(self.LaFr, text='Nummerierung', font=('Arial', 10), command=self.LaTeXNum) self.btnNum.grid(column=0, row=5, pady=5, sticky=(NW)) self.LaFr.grid_forget() def __addVerf(self): self.frameVerf = Frame(self.EntryVerf) #Erstellung eines Frames self.frameVerf.pack() self.frameVeAb = Frame(self.frameVerf) self.frameVeAb.grid(row=1, column=0, sticky=(NW)) self.frameVeTe = Frame(self.frameVerf) self.frameVeTe.grid(row=2, column=0, sticky=(NW)) Label(self.frameVeAb, text='Abschnitt', font=12, justify=LEFT).grid(row=0, column=0, padx=5, pady=5, sticky=(NW)) #Bezeichnung des Entries self.entVerf = Entry(self.frameVeAb, width=60, background='white') #Entry-Feld self.entVerf.grid(column=1, row=0, padx=36, pady=5, sticky=(EW)) Label(self.frameVeTe, text='Beschreibung', font=12).grid(column=0, row=2, padx=5, pady=5, sticky=(NW)) #Bezeichnung der Textbox self.txtVerf = scrolledtext.ScrolledText(self.frameVeTe, relief='sunken', width=60, height=5, background='white') #Textbox self.txtVerf.insert(INSERT, 'Bitte geben sie Text ein! ') #Vorgegebener Text self.txtVerf.grid(column=1, row=2, padx=5, pady=5, sticky=(EW)) self.all_Verf.append( (self.entVerf, self.txtVerf, self.frameVerf )) # Plus-Button hängt o.g. Objekte an die Bestehenden an. def __remVerf(self): if len(self.all_Verf) > 0: #wenn elemente in all_Verf vorhanden sind self.all_Verf[-1][2].forget( ) #vergessen des übergeordneten Frames (frameVerf) des graphischen Objektes (pack/grid) self.all_Verf[-1][2].destroy( ) #zerstören des Frameobjektes (Unterobjekte werden mitzerstört) self.all_Verf.pop( -1) #letztes Element der Liste wird aus dem Speicher entfernt else: pass def get(self): temp = [] for e in self.all_Verf: #Element dieser Liste = Liste mit zwei Elementen ['', ''] nlist = [e[0].get(), e[1].get(1.0, END) ] #Erstellung einer Hilfslist aus den Sublisten temp.append(nlist) #Liste von Daten wird an Liste angehängt return temp def set(self, arg): while len(self.all_Verf) > 0: self.__remVerf() #entfernt alle Entryfelder for index, elem in enumerate( arg): #iterieren durch die übergebenen Elemente self.__addVerf() #hinzufügen der Entries self.all_Verf[index][0].insert( 0, elem[0]) #einfügen des str aus der Liste Position 0 von TVerf self.all_Verf[index][1].delete(1.0, END) #löschen des initialen Inhalts self.all_Verf[index][1].insert( 1.0, elem[1]) #einfügen des str aus der Liste Position 1 von TVerf def insert(self, *args): self.txtVerf.insert(*args) def delete(self, *args): self.txtVerf.delete(*args) def getflag(self): return self.c.get() def setflag(self, flag): self.c.set(flag) self.LaFrhide() def LaFrhide(self): if self.c.get() == False: self.LaFr.grid_forget() else: self.LaFr.grid(column=0, row=1, pady=10, padx=10, sticky=(N)) #------------------------------------ def LaTeXitalic(self): try: self.EntryVerf.focus_get().insert(INSERT, '\\textit{}') except: pass #------------------------------------ def LaTeXbold(self): try: self.EntryVerf.focus_get().insert(INSERT, '\\textbf{}') except: pass #------------------------------------ def LaTeXundl(self): try: self.EntryVerf.focus_get().insert(INSERT, '\\underline{}') except: pass #------------------------------------ def LaTeXTilde(self): try: self.EntryVerf.focus_get().insert(INSERT, r'$\sim$') except: pass #------------------------------------ def LaTeXless(self): try: self.EntryVerf.focus_get().insert(INSERT, '\\textless{}') except: pass #------------------------------------ def LaTeXgreater(self): try: self.EntryVerf.focus_get().insert(INSERT, '\\textgreater{}') except: pass #------------------------------------ def LaTeXBullet(self): try: self.EntryVerf.focus_get().insert( INSERT, '\\begin{itemize}\n\\item lorem ipsum\n\\end{itemize}') except: pass #------------------------------------ def LaTeXNum(self): try: self.EntryVerf.focus_get().insert( INSERT, '\\begin{enumerate}\n\\item lorem ipsum\n\\end{enumerate}') except: pass #------------------------------------ #def LaTeXGrafic(self): #try: #self.EntryVerf.focus_get().insert(INSERT, '\\begin{figure}[h]\n\\centering\n\\includegraphics[width=4cm]{Dateiname}\n\\caption{Bildunterschrift}\n\\end{figure}') #except: #pass #------------------------------------ def LaTeXItem(self): try: self.EntryVerf.focus_get().insert(INSERT, '\\item ') except: pass
class MyLogin(Dialog): def __init__(self, master, server=['', 0]): self.server = server super().__init__(master, title='Login Datenbank') def login(self): ''' Wenn Datenbank == True, dann erscheint die Login-Option. ''' if self.a.get() == True: self.dbnCbtn.config(state=DISABLED) self.EntryFrame.grid(column=0, row=5, pady=5, padx=5, sticky=NW) else: self.dbnCbtn.config(state=NORMAL) self.EntryFrame.grid_forget() def nologin(self): ''' Wenn option Datei gewählt ist ''' if self.b.get() == True: self.dbjCbtn.config(state=DISABLED) else: self.dbjCbtn.config(state=NORMAL) def body(self, master): ''' Auswahloption ''' self.GFrame = Frame(master) self.GFrame.pack() #self.GFrame.grid(column=0, row=0, pady=5, padx=5, sticky=NW) self.cbtnLabel = Label( self.GFrame, text='Möchten Sie sich mit der Datenbank verbinden?', font=13) self.cbtnLabel.grid(column=0, row=0, pady=5, padx=5, sticky=(NW)) self.a = BooleanVar() self.a.set(False) self.dbjCbtn = Checkbutton(self.GFrame, text='Ja, weiter zum Login.', var=self.a, command=self.login) self.dbjCbtn.grid(column=0, row=1, pady=5, padx=5, sticky=NW) self.dbjCbtn.config(state=DISABLED) self.b = BooleanVar() self.b.set(True) self.dbnCbtn = Checkbutton(self.GFrame, text='Nein, SOPs lokal verwalten.', var=self.b, command=self.nologin) self.dbnCbtn.grid(column=0, row=2, pady=5, padx=5, sticky=NW) ''' Login-Option erscheint, wenn Checkbox "Ja" ausgewählt ist. ''' self.EntryFrame = Frame(self.GFrame) self.EntryFrame.grid(column=0, row=5, pady=5, padx=5, sticky=NW) self.userLabel = Label(self.EntryFrame, text='Benutzername', font=13) self.userLabel.grid(column=0, row=9, pady=5, padx=5, sticky=(NW)) self.userEntry = Entry(self.EntryFrame, width=15, background='white') #Entry Feld self.userEntry.grid(column=1, row=9, pady=5, padx=5, sticky=(NW)) self.pwLabel = Label(self.EntryFrame, text='Passwort', font=13) self.pwLabel.grid(column=0, row=10, pady=5, padx=5, sticky=(NW)) self.pwEntry = Entry(self.EntryFrame, width=15, background='white') #Entry Feld self.pwEntry.grid(column=1, row=10, pady=5, padx=5, sticky=(NW)) self.hostLabel = Label(self.EntryFrame, text='Host', font=13) self.hostLabel.grid(column=0, row=11, pady=5, padx=5, sticky=(NW)) self.hostEntry = Entry(self.EntryFrame, width=15, background='white') #Entry Feld self.hostEntry.insert(0, self.server[0]) self.hostEntry.grid(column=1, row=11, pady=5, padx=5, sticky=(NW)) self.portLabel = Label(self.EntryFrame, text='Port', font=13) self.portLabel.grid(column=0, row=12, pady=5, padx=5, sticky=(NW)) self.portEntry = Entry(self.EntryFrame, width=15, background='white', text=self.server[1]) #Entry Feld self.portEntry.insert(0, self.server[1]) self.portEntry.grid(column=1, row=12, pady=5, padx=5, sticky=(NW)) self.EntryFrame.grid_forget() def apply(self): if self.a.get() == True: cred = [ self.userEntry.get(), self.pwEntry.get(), \ self.hostEntry.get(), int(self.portEntry.get()) ] else: cred = None self.result = cred
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("EGUANA") self.style = ttk.Style() self.style.theme_use("alt") self.photoName = "eguana.gif" self.frame = Frame(self, relief=FLAT, borderwidth=10,bg='#FADC46') self.frame.pack(fill=BOTH, expand=True) self.pack(fill=BOTH, expand=True) self.setupMenuBar() self.setupTopBar() def setupMenuBar(self): self.menubar = EguanaMenu(self.parent,self) self.parent.config(menu=self.menubar) def setupTopBar(self): self.openButton3D = Button(self.frame,text="Select Directory for 3D EMA",relief=RAISED,command=self.askDirectory) self.openButton3D.grid(row=0,column=0, sticky=N+S+E+W,padx=2,pady =2) self.openButton2D = Button(self.frame,text="Select Directory for 2D EMA",relief=RAISED,command=self.askDirectory); self.openButton2D.grid(row=2,column=2, sticky=N+S+E+W,padx=2,pady =2) self.p1Button = Button(self.frame,text="Placeholder",relief=RAISED) self.p1Button.grid(row=0,column=1, sticky=N+S+E+W,padx=2,pady =2) self.p2Button = Button(self.frame,text="Placeholder",relief=RAISED) self.p2Button.grid(row=0,column=2, sticky=N+S+E+W,padx=2,pady =2) self.p3Button = Button(self.frame,text="Placeholder",relief=RAISED) self.p3Button.grid(row=1,column=0, sticky=N+S+E+W,padx=2,pady =2) self.p4Button = Button(self.frame,text="Placeholder",relief=RAISED) self.p4Button.grid(row=1,column=2, sticky=N+S+E+W,padx=2,pady =2) self.p5Button = Button(self.frame,text="Placeholder",relief=RAISED) self.p5Button.grid(row=2,column=0, sticky=N+S+E+W,padx=2,pady =2) self.p6Button = Button(self.frame,text="Placeholder",relief=RAISED) self.p6Button.grid(row=2,column=1, sticky=N+S+E+W,padx=2,pady =2) self.openButton3D.bind('<Motion>',self.cursorPosition) self.openButton2D.bind('<Motion>',self.cursorPosition) self.photo = PhotoImage(file="eguana.gif") self.photo = self.photo.subsample(2); self.photo_label = Label(self.frame,image=self.photo,borderwidth=0,highlightthickness=0) self.photo_label.configure(bg='#FADC46') self.photo_label.grid(row=1,column=1, sticky=N+S+E+W,padx=2,pady =2) self.photo_label.image = self.photo self.frame.columnconfigure(0, weight=1) self.frame.columnconfigure(1, weight=1) self.frame.columnconfigure(2, weight=1) self.frame.rowconfigure(0, weight=1) self.frame.rowconfigure(1, weight=1) self.frame.rowconfigure(2, weight=1) def askDirectory(self): dirStr = filedialog.askdirectory() if len(dirStr): self.openButton3D.destroy() self.openButton2D.destroy() self.p1Button.destroy() self.p2Button.destroy() self.p3Button.destroy() self.p4Button.destroy() self.p5Button.destroy() self.p6Button.destroy() self.menubar.entryconfigure('Filter', state = 'active') self.photo_label.destroy() dirStr = 'Input Path : '+dirStr self.frame.grid_forget() self.infoFrame = Frame(self.frame, relief=FLAT, bg='#FADC46') self.infoFrame.grid(row=0,column=0,columnspan=3, sticky=N+S+E+W,padx=2,pady =2) self.directoryLabel = Label(self.infoFrame, text="No project currently selected",relief=FLAT) self.directoryLabel.grid(row=0,column=0,columnspan=2, sticky=N+S+E+W,padx=2,pady =2) self.directoryLabel.config(text=dirStr) self.outputDirButton = Button(self.infoFrame,text="No output directory selected. Click to select an output directory ",relief=RAISED,fg='red',command=self.askOutputDirectory) self.outputDirButton.grid(row=1,column=0,columnspan=2, sticky=N+S+E+W,padx=2,pady =2) self.filterButton = Button(self.infoFrame,text="No filter selected. Click to select a filter",relief=RAISED,fg='red',command=self.selectFilter) self.filterButton.grid(row=2,column=0,columnspan=2, sticky=N+S+E+W,padx=2,pady =2) self.trialLabel = Label(self.infoFrame,text="Trial Number",relief=FLAT,justify=RIGHT,anchor=E) self.trialLabel.grid(row=3,column=0, sticky=N+S+E+W,padx=2,pady =2) vcmd = (self.master.register(self.validate),'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W') self.trialEntry = Entry(self.infoFrame,validate = 'key', validatecommand = vcmd) self.trialEntry.grid(row=3,column=1, sticky=N+S+E+W,padx=2,pady =2) self.infoFrame.columnconfigure(0, weight=1) self.infoFrame.columnconfigure(1, weight=1) self.infoFrame.rowconfigure(0, weight=1) self.infoFrame.rowconfigure(1, weight=1) self.infoFrame.rowconfigure(2, weight=1) self.infoFrame.rowconfigure(3, weight=1) self.showPlotTools() def validate(self, action, index, value_if_allowed, prior_value, text, validation_type, trigger_type, widget_name): if len(value_if_allowed)==0 : return True if text in '0123456789.-+ ': try: float(value_if_allowed) return True except ValueError: return False else: return False def askOutputDirectory(self): dirStr = filedialog.askdirectory() if len(dirStr): dirStr = 'Output Path : '+dirStr self.outputDirButton.destroy() self.outputDirLabel = Label(self.infoFrame, relief=FLAT) self.outputDirLabel.grid(row=1,column=0,columnspan=2, sticky=N+S+E+W,padx=2,pady =2) self.outputDirLabel.config(text=dirStr) def showPlotTools(self): f2= Frame(self.frame, relief=FLAT,bg='#FADC46') f2.grid(row=1,column=0,rowspan=2,columnspan=3,sticky=N+S+E+W,padx=10,pady =10) b1 = Button(f2,text='3D K',relief=RAISED,command= lambda:self.plotButtonPressed(1)) b1.grid(row=0, column=0,sticky=N+S+E+W,padx=5,pady =5) b2 = Button(f2,text='3D Dist',relief=RAISED,command=lambda:self.plotButtonPressed(2)) b2.grid(row=0, column=1,sticky=N+S+E+W,padx=5,pady =5) b3 = Button(f2,text='3D DP',relief=RAISED,command=lambda:self.plotButtonPressed(3)) b3.grid(row=0, column=2,sticky=N+S+E+W,padx=5,pady =5) b4 = Button(f2,text='2D K',relief=RAISED,command=lambda:self.plotButtonPressed(4)) b4.grid(row=1, column=0,sticky=N+S+E+W,padx=5,pady =5) b5 = Button(f2,text='2D Dist',relief=RAISED,command=lambda:self.plotButtonPressed(5)) b5.grid(row=1, column=1,sticky=N+S+E+W,padx=5,pady =5) b6 = Button(f2,text='2D DP',relief=RAISED,command=lambda:self.plotButtonPressed(6)) b6.grid(row=1, column=2,sticky=N+S+E+W,padx=5,pady =5) f2.columnconfigure(0, weight=1) f2.columnconfigure(1, weight=1) f2.columnconfigure(2, weight=1) f2.rowconfigure(0, weight=1) f2.rowconfigure(1, weight=1) def plotButtonPressed(self,number): trialNum = self.trialEntry.get() try: trialNum = float(trialNum) if trialNum < 16 and trialNum > 0: self.plotFigure(number) return True else: messagebox.showerror( "Trial Number Error", "The trial number is out of range" ) return False except ValueError: messagebox.showerror( "Trial Number Error", "Error with the trial number" ) return False def plotFigure(self,number): m = CoilNumDialog(self.frame) if m.isSet(): print(m.getValues()) def selectFilter(self): self.top = FilterPopup(self); def speech3DButtonPressed(self): self.menubar.filterSelected(0) self.top.destroy() if hasattr(self, 'filterLabel'): self.filterLabel.config(text="Filter : speech3D") else: self.filterLabel = Label(self.infoFrame, text="Filter : speech3D",relief=FLAT) self.filterLabel.grid(row=2,column=0,columnspan=2, sticky=N+S+E+W,padx=2,pady =2) self.filterButton.destroy() def speech2DButtonPressed(self): self.menubar.filterSelected(1) self.top.destroy() if hasattr(self, 'filterLabel'): self.filterLabel.config(text="Filter : speech2D") else: self.filterLabel = Label(self.infoFrame, text="Filter : speech2D ",relief=FLAT) self.filterLabel.grid(row=2,column=0,columnspan=2, sticky=N+S+E+W,padx=2,pady =2) self.filterButton.destroy() def swallow3DButtonPressed(self): self.menubar.filterSelected(2) self.top.destroy() if hasattr(self, 'filterLabel'): self.filterLabel.config(text="Filter : swallow3D") else: self.filterLabel = Label(self.infoFrame, text="Filter : swallow3D ",relief=FLAT) self.filterLabel.grid(row=2,column=0,columnspan=2, sticky=N+S+E+W,padx=2,pady =2) self.filterButton.destroy() def swallow2DButtonPressed(self): self.menubar.filterSelected(3) self.top.destroy() if hasattr(self, 'filterLabel'): self.filterLabel.config(text="Filter : swallow2D") else: self.filterLabel = Label(self.infoFrame, text="Filter : swallow2D ",relief=FLAT) self.filterLabel.grid(row=2,column=0,columnspan=2, sticky=N+S+E+W,padx=2,pady =2) self.filterButton.destroy() def changeImage(self): self.photo = PhotoImage(file=self.photoName) self.photo = self.photo.subsample(2); self.photo_label.image = self.photo self.photo_label.config(image=self.photo) def cursorPosition(self,event): if event.widget == self.openButton3D: if self.photoName == "eguana2.gif": self.photoName = "eguana.gif" self.changeImage() elif event.widget == self.openButton2D: if self.photoName == "eguana.gif": self.photoName = "eguana2.gif" self.changeImage()
class BannerFrame(Frame): """ Banner frame class. """ def __init__(self, app, *args, **kwargs): """ Constructor. :param Frame app: reference to main tkinter application :param args: optional args to pass to Frame parent class :param kwargs: optional kwargs to pass to Frame parent class """ self.__app = app # Reference to main application class self.__master = self.__app.get_master() # Reference to root class (Tk) Frame.__init__(self, self.__master, *args, **kwargs) self._time = StringVar() self._lat = StringVar() self._lon = StringVar() self._alt = StringVar() self._speed = StringVar() self._alt_u = StringVar() self._speed_u = StringVar() self._track = StringVar() self._dop = StringVar() self._hvdop = StringVar() self._hvacc = StringVar() self._fix = StringVar() self._siv = StringVar() self._sip = StringVar() self._status = False self._show_advanced = True self._bgcol = BGCOL self._fgcol = FGCOL self.config(bg=self._bgcol) self._img_conn = ImageTk.PhotoImage(Image.open(ICON_CONN)) self._img_connfile = ImageTk.PhotoImage(Image.open(ICON_LOGREAD)) self._img_disconn = ImageTk.PhotoImage(Image.open(ICON_DISCONN)) self.width, self.height = self.get_size() self._body() self._do_layout() self._attach_events() def _body(self): """ Set up frame and widgets. """ for i in range(2, 5): self.grid_columnconfigure(i, weight=1) self.grid_rowconfigure(0, weight=1) self.grid_rowconfigure(1, weight=1) self._frm_connect = Frame(self, bg=BGCOL) self._frm_toggle = Frame(self, bg=BGCOL) self._frm_basic = Frame(self, bg=BGCOL, relief=SUNKEN) self._frm_advanced = Frame(self, bg=BGCOL) self.option_add("*Font", self.__app.font_md2) self._lbl_ltime = Label( self._frm_basic, text="utc:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_llat = Label( self._frm_basic, text="lat:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_llon = Label( self._frm_basic, text="lon:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_lalt = Label( self._frm_basic, text="alt:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_lspd = Label( self._frm_basic, text="speed:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_ltrk = Label( self._frm_basic, text="track:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._btn_toggle = Button( self._frm_toggle, text=ADVON, width=3, command=self._toggle_advanced ) self._lbl_lfix = Label( self._frm_basic, text="fix:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_lsiv = Label( self._frm_advanced, text="siv:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_lsip = Label( self._frm_advanced, text="sip:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_lpdop = Label( self._frm_advanced, text="pdop:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self._lbl_lacc = Label( self._frm_advanced, text="acc:", bg=self._bgcol, fg=self._fgcol, anchor=N ) self.option_add("*Font", self.__app.font_lg) self._lbl_status_preset = Label( self._frm_connect, bg=self._bgcol, image=self._img_conn, fg="blue" ) self._lbl_time = Label( self._frm_basic, textvariable=self._time, bg=self._bgcol, fg="cyan" ) self._lbl_lat = Label( self._frm_basic, textvariable=self._lat, bg=self._bgcol, fg="orange" ) self._lbl_lon = Label( self._frm_basic, textvariable=self._lon, bg=self._bgcol, fg="orange" ) self._lbl_alt = Label( self._frm_basic, textvariable=self._alt, bg=self._bgcol, fg="orange" ) self._lbl_spd = Label( self._frm_basic, textvariable=self._speed, bg=self._bgcol, fg="deepskyblue" ) self._lbl_trk = Label( self._frm_basic, textvariable=self._track, bg=self._bgcol, fg="deepskyblue" ) self._lbl_fix = Label( self._frm_basic, textvariable=self._fix, bg=self._bgcol, fg="white" ) self._lbl_siv = Label( self._frm_advanced, textvariable=self._siv, bg=self._bgcol, fg="yellow" ) self._lbl_sip = Label( self._frm_advanced, textvariable=self._sip, bg=self._bgcol, fg="yellow" ) self._lbl_pdop = Label( self._frm_advanced, textvariable=self._dop, bg=self._bgcol, fg="mediumpurple2", ) self.option_add("*Font", self.__app.font_sm) self._lbl_lalt_u = Label( self._frm_basic, textvariable=self._alt_u, bg=self._bgcol, fg="orange", anchor=S, ) self._lbl_lspd_u = Label( self._frm_basic, textvariable=self._speed_u, bg=self._bgcol, fg="deepskyblue", anchor=S, ) self._lbl_hvdop = Label( self._frm_advanced, textvariable=self._hvdop, bg=self._bgcol, fg="mediumpurple2", ) self._lbl_hvacc = Label( self._frm_advanced, textvariable=self._hvacc, bg=self._bgcol, fg="aquamarine2", ) self._lbl_lacc_u = Label( self._frm_advanced, textvariable=self._alt_u, bg=self._bgcol, fg="aquamarine2", anchor=N, ) def _do_layout(self): """ Position widgets in frame. """ self._lbl_status_preset.grid(column=0, row=0, padx=8, pady=3, sticky=W) self._lbl_ltime.grid(column=1, row=0, pady=3, sticky=W) self._lbl_time.grid(column=2, row=0, pady=3, sticky=W) self._lbl_llat.grid(column=3, row=0, pady=3, sticky=W) self._lbl_lat.grid(column=4, row=0, pady=3, sticky=W) self._lbl_llon.grid(column=5, row=0, pady=3, sticky=W) self._lbl_lon.grid(column=6, row=0, pady=3, sticky=W) self._lbl_lalt.grid(column=7, row=0, pady=3, sticky=W) self._lbl_alt.grid(column=8, row=0, pady=3, sticky=W) self._lbl_lalt_u.grid(column=9, row=0, pady=0, sticky=W) self._lbl_lspd.grid(column=10, row=0, pady=3, sticky=W) self._lbl_spd.grid(column=11, row=0, pady=3, sticky=W) self._lbl_lspd_u.grid(column=12, row=0, pady=0, sticky=W) self._lbl_ltrk.grid(column=13, row=0, pady=3, sticky=W) self._lbl_trk.grid(column=14, row=0, pady=3, sticky=W) self._lbl_lfix.grid(column=15, row=0, pady=3, sticky=W) self._lbl_fix.grid(column=16, row=0, pady=3, sticky=W) self._lbl_lsiv.grid(column=0, row=0, pady=3, sticky=W) self._lbl_siv.grid(column=1, row=0, pady=3, sticky=W) self._lbl_lsip.grid(column=2, row=0, pady=3, sticky=W) self._lbl_sip.grid(column=3, row=0, pady=3, sticky=W) self._lbl_lpdop.grid(column=4, row=0, pady=3, sticky=W) self._lbl_pdop.grid(column=5, row=0, pady=3, sticky=W) self._lbl_hvdop.grid(column=6, row=0, pady=0, sticky=W) self._lbl_lacc.grid(column=7, row=0, pady=3, sticky=W) self._lbl_hvacc.grid(column=8, row=0, pady=0, sticky=W) self._lbl_lacc_u.grid(column=9, row=0, pady=0, sticky=W) self._btn_toggle.grid(column=0, row=0, padx=8, pady=3, sticky=(N, E)) self._toggle_advanced() def _toggle_advanced(self): """ Toggle advanced banner frame on or off. """ self._frm_connect.grid( column=0, row=0, rowspan=2, pady=3, ipadx=3, ipady=3, sticky=(N, W) ) self._frm_basic.grid(column=1, row=0, pady=3, sticky=(W)) self._frm_toggle.grid(column=5, row=0, rowspan=2, pady=3, sticky=(N, E)) self._show_advanced = not self._show_advanced if self._show_advanced: self._frm_advanced.grid(column=1, row=1, pady=3, sticky=(W)) self._btn_toggle.config(text=ADVON) else: self._frm_advanced.grid_forget() self._btn_toggle.config(text=ADVOFF) def _attach_events(self): """ Bind events to frame. """ self.bind("<Configure>", self._on_resize) def update_conn_status(self, status: int): """ Update connection status icon :param int status: connection status as integer (0,1,2) """ if status == CONNECTED: self._lbl_status_preset.configure(image=self._img_conn) elif status == CONNECTED_FILE: self._lbl_status_preset.configure(image=self._img_connfile) else: self._lbl_status_preset.configure(image=self._img_disconn) def update_banner(self, **kwargs): """ Sets text of banner from keyword parms. :param kwargs: optional key value pairs for each displayed parameter """ disp_format = self.__app.frm_settings.format units = self.__app.frm_settings.units self._update_time(**kwargs) self._update_pos(disp_format, units, **kwargs) self._update_track(units, **kwargs) self._update_fix(**kwargs) self._update_siv(**kwargs) self._update_dop(units, **kwargs) def _update_time(self, **kwargs): """ Update GNSS time of week :param kwargs: optional key value pairs """ if "time" in kwargs: tim = kwargs["time"] if tim in (None, ""): self._time.set("N/A") else: self._time.set(tim) def _update_pos(self, disp_format, units, **kwargs): """ Update position :param str disp_format: degrees display format as string (DMS, DMM, DDD) :param str units: distance units as string (UMM, UMK, UI, UIK) :param kwargs: optional key value pairs """ if "lat" in kwargs: lat = kwargs["lat"] if lat in (None, ""): self._lat.set("N/A") else: if disp_format == DMS: self._lat.set(deg2dms(lat, "lat")) elif disp_format == DMM: self._lat.set(deg2dmm(lat, "lat")) else: self._lat.set(round(lat, 5)) if "lon" in kwargs: lon = kwargs["lon"] if lon in (None, ""): self._lon.set("N/A") else: if disp_format == DMS: self._lon.set(deg2dms(lon, "lon")) elif disp_format == DMM: self._lon.set(deg2dmm(lon, "lon")) else: self._lon.set(round(lon, 5)) if "alt" in kwargs: alt = kwargs["alt"] if alt in (None, ""): self._alt.set("N/A") self._alt_u.set("") else: if units in (UI, UIK): self._alt.set(round(m2ft(float(alt)), 1)) self._alt_u.set("ft") else: self._alt.set(round(alt, 1)) self._alt_u.set("m") def _update_track(self, units, **kwargs): """ Update track and ground speed :param str units: distance units as string (UMM, UMK, UI, UIK) :param kwargs: optional speed and/or track key/value pairs """ if "speed" in kwargs: speed = kwargs["speed"] if speed in (None, ""): self._speed.set("N/A") self._speed_u.set("") else: if units == UI: self._speed.set(round(ms2mph(float(speed)), 1)) self._speed_u.set("mph") elif units == UIK: self._speed.set(round(ms2knots(float(speed)), 1)) self._speed_u.set("knots") elif units == UMK: self._speed.set(round(ms2kmph(float(speed)), 1)) self._speed_u.set("kmph") else: self._speed.set(round(speed, 1)) self._speed_u.set("m/s") if "track" in kwargs: track = kwargs["track"] if track in (None, ""): self._track.set("N/A") else: self._track.set(str(round(track, 1))) def _update_fix(self, **kwargs): """ Update fix type :param kwargs: optional fix key/value pair """ if "fix" in kwargs: fix = kwargs["fix"] if fix in ("3D", "3D + DR"): self._lbl_fix.config(fg="green2") elif fix in ("2D", "DR"): self._lbl_fix.config(fg="orange") else: self._lbl_fix.config(fg="red") self._fix.set(fix) def _update_siv(self, **kwargs): """ Update siv and sip :param kwargs: optional key value pairs """ if "siv" in kwargs: siv = kwargs["siv"] self._siv.set(str(siv).zfill(2)) if "sip" in kwargs: sip = kwargs["sip"] self._sip.set(str(sip).zfill(2)) def _update_dop(self, units, **kwargs): """ Update precision and accuracy :param str units: distance units as string (UMM, UMK, UI, UIK) :param kwargs: optional key value pairs """ if "dop" in kwargs: dop = kwargs["dop"] self._dop.set(str(dop) + " " + dop2str(dop)) if "hdop" in kwargs and "vdop" in kwargs: self._hvdop.set( "hdop " + str(kwargs["hdop"]) + "\nvdop " + str(kwargs["vdop"]) ) if "hacc" in kwargs and "vacc" in kwargs: if units in (UI, UIK): hacc = round(m2ft(kwargs["hacc"]), 1) vacc = round(m2ft(kwargs["vacc"]), 1) else: hacc = round(kwargs["hacc"], 1) vacc = round(kwargs["vacc"], 1) self._hvacc.set("hacc " + str(hacc) + "\nvacc " + str(vacc)) def _set_fontsize(self): """ Adjust font sizes according to frame size """ w = self.width # Cater for slightly different font behaviour on Linux if system() in ("W32", "Darwin"): val = 55 lbl = 75 sup = 85 else: val = 70 lbl = 85 sup = 95 sz = min(int(w / val), 18) self._lbl_status_preset.config(font=font.Font(size=sz)) self._lbl_time.config(font=font.Font(size=sz)) self._lbl_lat.config(font=font.Font(size=sz)) self._lbl_lon.config(font=font.Font(size=sz)) self._lbl_alt.config(font=font.Font(size=sz)) self._lbl_spd.config(font=font.Font(size=sz)) self._lbl_trk.config(font=font.Font(size=sz)) self._lbl_pdop.config(font=font.Font(size=sz)) self._lbl_fix.config(font=font.Font(size=sz)) self._lbl_sip.config(font=font.Font(size=sz)) self._lbl_siv.config(font=font.Font(size=sz)) sz = min(int(w / lbl), 14) self._lbl_ltime.config(font=font.Font(size=sz)) self._lbl_llat.config(font=font.Font(size=sz)) self._lbl_llon.config(font=font.Font(size=sz)) self._lbl_lalt.config(font=font.Font(size=sz)) self._lbl_lspd.config(font=font.Font(size=sz)) self._lbl_ltrk.config(font=font.Font(size=sz)) self._lbl_lpdop.config(font=font.Font(size=sz)) self._lbl_lfix.config(font=font.Font(size=sz)) self._lbl_lsip.config(font=font.Font(size=sz)) self._lbl_lsiv.config(font=font.Font(size=sz)) self._lbl_lacc.config(font=font.Font(size=sz)) sz = min(int(w / sup), 12) self._lbl_lalt_u.config(font=font.Font(size=sz)) self._lbl_lspd_u.config(font=font.Font(size=sz)) self._lbl_hvdop.config(font=font.Font(size=sz)) self._lbl_hvacc.config(font=font.Font(size=sz)) def _on_resize(self, event): # pylint: disable=unused-argument """ Resize frame :param event event: resize event """ self.width, self.height = self.get_size() self._set_fontsize() def get_size(self): """ Get current frame size. :return: window size (width, height) :rtype: tuple """ self.update_idletasks() # Make sure we know about any resizing width = self.winfo_width() height = self.winfo_height() return (width, height)
class MazeGUI: def __init__(self): self.maze = Maze(4, 4) self.root = Tk() self.gamescreen = Frame(self.root) self.startmenu = Frame(self.root) self.db = None self.display = None self.drawer = None self.start_time = None self.root.resizable(False, False) self.root.title("TriviaMaze") self.start_menu_init() self.startmenu.grid(row=0, column=0) self.gamescreen.grid_forget() pygame.init() pygame.mixer.init() self.root.mainloop() pygame.init() pygame.mixer.init() """Start menu""" def start_menu_init(self): """Builds the start menu for the game. Has a button to start a new game, continue game, display instructions and exit the program. Under the new game button there are options for different game difficulties, with easy as the default selection.""" self.startmenu.grid(row=0, column=0) menu_spacer = Frame(self.startmenu, height=80, width=600) menu_spacer.grid(row=0, column=0, columnspan=3) menu_spacer2 = Frame(self.startmenu, height=420, width=100) menu_spacer2.grid(row=2, column=1) menu_spacer3 = Frame(menu_spacer2) menu_spacer3.grid(row=4, column=1) title = Label(self.startmenu, text="504 TriviaMaze", font="Times 40", pady=50) title.grid(row=1, column=0, columnspan=4) new_game_button = Button(menu_spacer2, text="New Game", font="Times 20", command=lambda: self.display_new_game_menu()) new_game_button.grid(row=3, column=1, sticky=W) continue_game_button = Button(menu_spacer2, text="Continue Game", font="Times 20", command=self.display_load_menu) continue_game_button.grid(row=6, column=1, columnspan=2, sticky=W) instructions_button = Button(menu_spacer2, text="Instructions", font="Times 20", command=self.display_instructions) instructions_button.grid(row=7, column=1, columnspan=2, sticky=W) exit_button = Button(menu_spacer2, text="Exit", font="Times 20", command=self.root.destroy) exit_button.grid(row=8, column=1, columnspan=2, sticky=W) def display_instructions(self): """Displays basic instructions for the game. Hides the start menu and replaces it with a screen containing text from a separate text file. Creates a button that will return the user to the start menu.""" self.startmenu.grid_forget() instruction_file = open("triviamaze_instructions.txt", 'r') instruction_text = instruction_file.read() instruct_frame = Frame(self.root, height=600, width=600) instruct_frame.grid(row=0, column=0) t = Text(instruct_frame, wrap="word", font="Times 16") t.grid(row=0, column=0) t.insert("1.0", instruction_text) instruction_file.close() back_button = Button( instruct_frame, text="Back", font="Times 20", command=lambda: self.screen_switch(instruct_frame, self.startmenu)) back_button.grid(row=1, column=0) def display_new_game_menu(self): """Creates and displays the new game menu, allowing the player to choose question difficulty, maze size, and trivia category. The default options are easy, 4x4 and no specific category.""" def set_difficulty(difficulty): buttons = { "Easy": easy_button, "Medium": medium_button, "Hard": hard_button } for button in buttons.values(): button['relief'] = 'raised' buttons[difficulty]['relief'] = 'sunken' maze.set_difficulty(difficulty.lower()) def set_category(chosen_category, possible_categories): """Ensures a valid category is chosen""" if chosen_category in possible_categories: maze.set_category(chosen_category) else: invalid_selection = Label( new_game_menu, text="The selected category is invalid, please choose a " "different category.", font='Times 16', pady=5) invalid_selection.grid(row=5, column=0, columnspan=4) new_game_menu = Toplevel(self.root) maze = self.maze instruction_text = "Please select a category from the provided list.\nChoosing a specific category will reduce " \ "the number of\navailable questions and increase the change of repeat questions.\n Selecting" \ " no category will pull from all possible categories." selection_instruction = Label(new_game_menu, text=instruction_text, font="Times 14", pady=10) selection_instruction.grid(row=0, column=0, columnspan=3) difficulty_frame = Frame(new_game_menu) difficulty_frame.grid(row=1, column=0, columnspan=3) difficulty_label = Label(difficulty_frame, text="Question difficulty: ", font="Times 16", pady=15) difficulty_label.grid(row=1, column=0) hard_button = Button(difficulty_frame, text="Hard", padx=5, font="Times 12", command=lambda: set_difficulty("Hard")) hard_button.grid(row=1, column=4) medium_button = Button(difficulty_frame, text="Medium", padx=5, font="Times 12", command=lambda: set_difficulty("Medium")) medium_button.grid(row=1, column=3) easy_button = Button(difficulty_frame, text="Easy", padx=5, font="Times 12", command=lambda: set_difficulty("Easy")) easy_button.grid(row=1, column=2) set_difficulty("Easy") dimension_frame = Frame(new_game_menu) dimension_frame.grid(row=2, column=0, columnspan=3) dimension_choices = range(3, 11) row_label = Label(dimension_frame, text="Row: ", font="Times 16", pady=15) row_label.grid(row=2, column=0, sticky=W) row_choice = StringVar() row_choice.set(4) row_select = OptionMenu(dimension_frame, row_choice, *dimension_choices) row_select.grid(row=2, column=1) col_label = Label(dimension_frame, text="Col: ", font="Times 16") col_label.grid(row=2, column=2, sticky=W) col_choice = StringVar() col_choice.set(4) col_select = OptionMenu(dimension_frame, col_choice, *dimension_choices) col_select.grid(row=2, column=3) db = SQLDatabase() category_list = db.request_category_list() category_frame = Frame(new_game_menu) category_frame.grid(row=3, column=0, columnspan=3) category_label = Label(category_frame, text="Category: ", font="Times 16", pady=15).grid(row=3, column=0) c = StringVar() category_box = ttk.Combobox(category_frame, justify='left', textvariable=c, font='Times 16') categories = [] for key in category_list.keys(): categories.append(key) category_box['values'] = categories category_box.grid(row=3, column=1) button_frame = Frame(new_game_menu) button_frame.grid(row=4, column=1) submit = Button(button_frame, text='Start', font='Times 20', command=lambda: [ set_category(c.get(), categories), self.maze.resize_maze(int(row_choice.get()), int(col_choice.get())), self.start_game(new_game=True), new_game_menu.destroy() ]) submit.grid(row=4, column=0) back_button = Button(button_frame, text='Back', font='Times 20', command=lambda: new_game_menu.destroy()) back_button.grid(row=4, column=1) def prompt(self, savefile, type): """Creates a text prompt in the text display of the game screen asking the player to confirm their save/load. Prompt message depend on whether the player wishes to save or load. Upon confirming their action the save or load is initiated with the indicated save file. savefile: name of the save file as a string type: type of request, either 'save' or 'load' """ self.clear_text_display() if type == "save": confirm_text = "Any existing data in this save file will be written over." \ "\nAre you sure you wish to continue?" ok_button = Button(self.text_display, text="Yes", font='Times 20', command=lambda: self.save_game(savefile)) else: confirm_text = "Any unsaved progress will be lost when loading a save file.\n " \ "Are you sure you wish to continue?" ok_button = Button(self.text_display, text="Yes", font='Times 20', command=lambda: self.load_game(savefile)) ok_button.grid(row=1, column=2) warning_text = Label(self.text_display, font="Times 18", padx=10, pady=10, text=confirm_text) warning_text.grid(row=0, column=1, columnspan=4) back_button = Button(self.text_display, text="No", font='Times 20', command=lambda: self.clear_text_display()) back_button.grid(row=1, column=3) def load_game(self, savefile, event=None, load_menu=None): """Attempts to open the indicated save file. If it is not found and the load request came from the load menu, nothing happens, if the load request came from in game, displays an error message in the text display before returning. If the file is found, the maze is set equal to the save file data, the existing display is switched, the game restarts with the new maze. savefile: name of the save file as a string load_menu: load menu frame, used to indicate if the load request came from the load menu or in game, default is None """ print(f'loading {savefile}') try: loadhandle = open(savefile + '.pkl', 'rb') except FileNotFoundError: if load_menu: return else: self.clear_text_display() no_file_found_text = "No save file could be found for this save slot." no_file = Label(self.text_display, text=no_file_found_text, font='Times 20', padx=30, pady=40) no_file.grid(row=0, column=0) continue_button = Button(self.text_display, text='Continue', font='Times 20', command=self.clear_text_display) continue_button.grid(row=1, column=0) return load_tone = pygame.mixer.Sound('sfx/load_tone.wav') pygame.mixer.Sound.play(load_tone) mazedata = pickle.load(loadhandle) loadhandle.close() self.maze = mazedata if not load_menu: self.display.destroy() else: load_menu.destroy() self.screen_switch(self.startmenu, self.gamescreen) self.start_game() self.check_end_game() def save_game(self, savefile): """ Sets the time elapsed field for the maze and saves the current maze to the indicated save file. Displays a message in the text display to tell the player that the save was completed. savefile: name of the save file as a string """ self.maze.set_time_elapsed(self.start_time, int(time.time())) self.start_time = int(time.time()) savehandle = open(savefile + '.pkl', 'wb') pickle.dump(self.maze, savehandle) savehandle.close() self.clear_text_display() confirmation = Label( self.text_display, font="Times 18", pady=10, padx=120, text="Successfully saved", ) confirmation.grid(row=0, column=0) back_button = Button(self.text_display, text="Continue", font='Times 18', command=self.clear_text_display) back_button.grid(row=1, column=0) save_tone = pygame.mixer.Sound('sfx/save_tone.wav') pygame.mixer.Sound.play(save_tone) def display_load_menu(self): """ Builds a load menu that displays the three save slots. Loads the save information if the save file exists and uses different maze methods/fields to obtain information about the save such as the maze size, player location, trivia category, trivia difficulty, and time spent in game and displays this info. """ saves = Frame(self.root, height=650, width=650, bg='SystemButtonFace') saves.grid(row=0, column=0) save = [] load_instruct = "Loading will take a few seconds, and can be inconsistent.\n" \ "Wait a moment before clicking a save file again or exit the load menu and try again." instruct = Label(saves, text=load_instruct, font='Times 12', pady=10) instruct.grid(row=0, column=0) for i in range(1, 4): savelabel = LabelFrame(saves, height=175, width=550, text=f'Save {i}', cursor='hand1', font='Times 16') savelabel.grid(row=i, column=0, sticky=E) savelabel.grid_propagate(0) try: loadhandle = open(f'save_file_{i}.pkl', 'rb') maze = pickle.load(loadhandle) info = [ f'Rows: {maze.get_size()[0]}', f'Columns: {maze.get_size()[1]}', f'Difficulty: {maze.difficulty}', f'Category: {maze.category}', f'Position: {maze.player_location}', f'Time: {maze.get_time()}' ] for j in range(len(info)): label = Label(savelabel, text=info[j], font='Times 14', anchor=W, padx=5, pady=10) label.grid(row=j % 2, column=j // 2, sticky=W) loadhandle.close() save_file = "save_file_" + str(i) savelabel.bind( '<Button-1>', partial(self.load_game, save_file, load_menu=saves)) except FileNotFoundError: continue save.append(savelabel) back_button = Button( saves, text="Back", font='Times 20', anchor=N, command=lambda: self.screen_switch(saves, self.startmenu)) back_button.grid(row=4, column=0) def start_game(self, new_game=False): """Builds game screen and database of questions, switches to game screen, saves the current time for use in tracking the play time. new_game: boolean indicating if the game is being loaded from a save file or if it is a new game """ if new_game: self.maze.construct() self.screen_switch(self.startmenu, self.gamescreen) for item in self.gamescreen.winfo_children(): item.destroy() self._menu_init() self._movement_interface_init() size = self.maze.get_size() self.display = Canvas(self.gamescreen, height=size[0] * 100, width=size[1] * 100, bg="gray") self.drawer = Drawer(self.maze, self.display) self.drawer.draw() self.display.grid(row=0, column=0, columnspan=4) self.db = SQLDatabase(self.maze.category, self.maze.difficulty, self.maze.get_total_doors()) self.db.build_database() self.start_time = int(time.time()) def screen_switch(self, curr_frame, new_frame): """Switches the main display from the current frame to the desired frame. curr_frame: current frame that is being displayed new_frame: the desired frame """ curr_frame.grid_forget() new_frame.grid(row=0, column=0) """Game Screen""" def _menu_init(self): """Creates the menubar consisting of options for loading a game, saving the current game, getting instructions, or exiting the game.""" def confirm_exit(root): """Creates a popup that makes sure the user wishes to exit the program.""" def close(): root.destroy() def back(): warning.destroy() warning = Toplevel() warning_text = Label(warning, font="Times 20", pady=10, text="Are you sure you wish to exit? \n" "Any unsaved progress will not be kept.") warning_text.grid(row=0, column=0, columnspan=4) ok_button = Button(warning, text="Ok", font='Times 16', command=close).grid(row=1, column=1) back_button = Button(warning, text="Back", font='Times 16', command=back).grid(row=1, column=2) def display_help(): """Prints out the instruction text from the in the text display.""" instruction_file = open("triviamaze_instructions.txt", 'r') instruction_text = instruction_file.read() instruction_file.close() help_window = Toplevel() help_label = Label(help_window, text=instruction_text, font='Times 14') help_label.grid(row=0, column=0) menubar = Menu(self.root) menubar.add_command(label="Help", command=display_help) savemenu = Menu(menubar, tearoff=0) savemenu.add_command( label="Save 1", command=lambda: self.prompt("save_file_1", "save")) savemenu.add_command( label="Save 2", command=lambda: self.prompt("save_file_2", "save")) savemenu.add_command( label="Save 3", command=lambda: self.prompt("save_file_3", "save")) menubar.add_cascade(label="Save", menu=savemenu) loadmenu = Menu(menubar, tearoff=0) loadmenu.add_command( label="Load 1", command=lambda: self.prompt("save_file_1", "load")) loadmenu.add_command( label="Load 2", command=lambda: self.prompt("save_file_2", "load")) loadmenu.add_command( label="Load 3", command=lambda: self.prompt("save_file_3", "load")) menubar.add_cascade(label="Load", menu=loadmenu) menubar.add_command(label="Exit", command=lambda: confirm_exit(self.root)) self.root.config(menu=menubar) def _movement_interface_init(self): """Creates the interface allowing player movement, binds arrow keys to different movements.""" self.text_display = Frame(self.gamescreen, height=200, width=600, borderwidth=1) self.text_display.grid_propagate(0) self.text_display.grid(row=1, column=0) movementframe = Frame(self.gamescreen) self.north = Button(movementframe, text="North", command=lambda: self.display_question("north"), pady=5) self.north.grid(row=1, column=2, columnspan=2) self.south = Button(movementframe, text="South", command=lambda: self.display_question("south"), pady=5) self.south.grid(row=3, column=2, columnspan=2) self.east = Button(movementframe, text="East", command=lambda: self.display_question("east"), pady=5) self.east.grid(row=2, column=4) self.west = Button(movementframe, text="West", command=lambda: self.display_question("west"), pady=5) self.west.grid(row=2, column=1) movementframe.grid(row=1, column=1) self.gamescreen.bind('<Left>', partial(self.arrowKey, "west")) self.gamescreen.bind('<Right>', partial(self.arrowKey, "east")) self.gamescreen.bind('<Up>', partial(self.arrowKey, "north")) self.gamescreen.bind('<Down>', partial(self.arrowKey, "south")) self.gamescreen.focus_set() def arrowKey(self, direction, event=None): if self.maze.check_direction(self.maze.player_location[0], self.maze.player_location[1], direction): self.display_question(direction) else: pass def _set_move_button_state(self): """Sets the state of the movement buttons depending on if the adjacent rooms can be reached from the current room or not.""" row, col = self.maze.player_location[0], self.maze.player_location[1] directions = ["north", "south", "east", "west"] buttons = [self.north, self.south, self.east, self.west] for i in range(4): if self.maze.check_direction(row, col, directions[i]): buttons[i]['state'] = "normal" else: buttons[i]['state'] = "disabled" def _move_player(self, direction, event=None, correct=True): """Moves the player if correct. If incorrect, then the corresponding door is locked. In both cases the game display is redrawn, the movement buttons are reset and any text that is in the text display is deleted. direction: string representing the direction the player is moving correct: boolean indicating if the player correctly answered the trivia question""" pygame.mixer.init() if correct: self.maze.move_player(direction) walk_sound = pygame.mixer.Sound('sfx/walk.wav') pygame.mixer.Sound.play(walk_sound) else: self.maze.lock_door(direction) door_lock_sound = pygame.mixer.Sound('sfx/door_lock.wav') pygame.mixer.Sound.play(door_lock_sound) self.drawer.draw() self._set_move_button_state() self.clear_text_display() self.check_end_game() def check_end_game(self): """Checks if either player wins or maze is no longer completable. If either condition is met, the corresponding end game screen is displayed and options for exiting and replaying are offered.""" def close(window): window.destroy() if self.maze.player_wins(): text = Label(self.text_display, text=f'Congrats, you have won the game!', font="Times 26", padx=20, pady=10) game_win_sound = pygame.mixer.Sound('sfx/game_win.wav') pygame.mixer.Sound.play(game_win_sound) elif not self.maze.is_completable(): text = Label(self.text_display, text=f'Game Over\nYou can no longer reach the exit.', font="Times 26", padx=20) game_lose_sound = pygame.mixer.Sound('sfx/game_lose.wav') pygame.mixer.Sound.play(game_lose_sound) else: return text.grid(row=0, column=0, columnspan=4) replay_button = Button( self.text_display, text="Replay", font="Times 20", command=lambda: [ self.start_menu_init(), self.screen_switch(self.gamescreen, self.startmenu) ]) replay_button.grid(row=1, column=1) exit_button = Button(self.text_display, text="Exit", font="Times 20", command=lambda: close(self.root)) exit_button.grid(row=1, column=2) def display_question(self, direction): """If a question is currently being displayed, pass. If the room that the player is moving too has already been visited, then move the player. Otherwise, pull a question from the database, and display it in the text display. direction: string representing the direction that the player is attempting to move in """ def highlight_selection(i, event=None): answer_list[i]['bg'] = 'gray' def unhighlight_selection(i, event=None): answer_list[i]['bg'] = 'SystemButtonFace' if self.text_display.winfo_children(): return destination = self.maze.find_destination(self.maze.player_location[0], self.maze.player_location[1], direction) if destination in self.maze.visited_rooms: self.maze.move_player(direction) self.drawer.draw() self._set_move_button_state() walk_short_sound = pygame.mixer.Sound('sfx/walk_short.wav') pygame.mixer.Sound.play(walk_short_sound) else: question = self.db.get_random_question() question_text = Label(self.text_display, text=f'{question[1]}', font="Times 16", justify="left", wraplength=600, anchor=W, width=600) question_text.grid(row=0, column=0) answer_list = [] answer_count = len(question) positions = [*range(1, answer_count + 1)] random.shuffle(positions) for i in range(2, answer_count): if not question[i]: return answer = Label(self.text_display, text=f'\t{question[i]}', font="Times 14", anchor=W) answer.grid(row=positions.pop() + 1, column=0, sticky=E + W) answer.bind('<Enter>', partial(highlight_selection, i - 2)) answer.bind('<Leave>', partial(unhighlight_selection, i - 2)) answer.bind( '<Button-1>', partial(self._move_player, direction, correct=(i == 2))) answer_list.append(answer) def clear_text_display(self): """Clears items in the text display.""" for item in self.text_display.winfo_children(): item.destroy()
class wd_Entry(Frame): def __init__(self, framePai, **kwargs): super().__init__(framePai) self.grid() self.tit_Entry_text = kwargs.get('tit_Entry', 'Título') self.set_Entry_default = kwargs.get('set_Entry_default', 'Opções') self.state_Entry = kwargs.get('state_Entry', 'enabled') self.width_Entry = kwargs.get('width', 20) self.frameLocal = Frame(framePai) self.tit_Entry = Label(self.frameLocal, text=self.tit_Entry_text) self.var_Entry = StringVar() self.Entry = ttk.Entry(self.frameLocal, textvariable=self.var_Entry, width=self.width_Entry, state=self.state_Entry) def config_Entry(self, **kwargs): self.Entry.config(kwargs) def get(self): return self.var_Entry.get() def retorna_entr(self): return self.var_Entry.get() def insert(self, txt): self.Entry.insert_Entry(txt) def insert_Entry(self, txt): if self.Entry['state'] != 'enabled': state = self.Entry['state'] self.Entry.config(state='enabled') self.Entry.delete(0, "end") self.Entry.insert('end', txt) self.Entry.config(state=state) else: self.Entry.delete(0, "end") self.Entry.insert('end', txt) def grid_frame(self, **kwargs): row = kwargs.get('row', 0) column = kwargs.get('column', 0) sticky = kwargs.get('sticky', W) columnspan = kwargs.get('columnspan', 1) rowspan = kwargs.get('rowspan', 1) pady = kwargs.get('pady', 2) padx = kwargs.get('padx', 2) self.tit_Entry.grid(row=0, column=0, sticky=W, columnspan=columnspan) self.Entry.grid(row=1, column=0, sticky=sticky, columnspan=columnspan) self.frameLocal.grid(row=row, column=column, columnspan=columnspan, rowspan=rowspan, pady=pady, padx=padx, sticky=sticky) def ungrid_frame(self): self.frameLocal.grid_forget() def delete(self): self.Entry.delete(0, "end") def limpa_entr(self): self.Entry.delete(0, "end")
class Display(Frame): def __init__(self): Frame.__init__(self) self.color = IntVar() self.color.set(0) self.bg = GAME_COLOR[self.color.get()] self.grid() self.master.title('2048') self.master.bind("<Key>", self.key_press) self.commands = { UP_KEY: game_functions.move_up, DOWN_KEY: game_functions.move_down, LEFT_KEY: game_functions.move_left, RIGHT_KEY: game_functions.move_right, } self.gravitational = False self.cont = False self.new_game = False self.score = 0 self.timer = 0 self.ingame = False self.grid_cells = [] self.status_cells = [] self.game_type_code = IntVar() self.game_size = IntVar() self.sound = BooleanVar() self.player = StringVar() self.result_showed = BooleanVar() self.game_size.set(4) self.sound.set(False) self.back_from_partial = BooleanVar() self.back_from_partial.set(False) self.game_types = [("classic", 0), ("grav", 1)] self.nav_bar = Frame(self, bg='pink', width=EDGE_LENGTH * 4, height=EDGE_LENGTH) self.game_frame = Frame(self) self.game_para_cell = Frame() self.nav_bar.grid(row=0) self.menu_frame = Frame(self, bg='green', width=EDGE_LENGTH * 4, height=EDGE_LENGTH) self.menu_frame.grid(row=1) self.partial_result_frame = Frame() self.menu() self.mainloop() def bring_back_result(self, event): self.result_frame.grid_forget() self.partial_result_frame.grid_forget() self.show_result() def show_sum_score(self, event): self.result_showed.set(False) self.full_result_frame.grid_forget() self.partial_result_frame = Frame(self.result_frame, bg=GAME_COLOR[self.color.get()], width=EDGE_LENGTH * 2, height=EDGE_LENGTH) self.partial_result_frame.grid(padx=CELL_PAD, pady=CELL_PAD) quit_button = Button(master=self.partial_result_frame, text="Return", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=5, height=2) quit_button.grid(row=0, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=5) self.back_from_partial.set(True) quit_button.bind('<Button-1>', self.bring_back_result) result_dict = {} with open('result.json') as outfile: results = json.load(outfile) temp = results['result'] for i in temp: if i['name'] not in result_dict.keys(): result_dict[i['name']] = i else: result_dict[i['name']]['score'] += i['score'] temp_sorted = sorted(list(result_dict.values()), key=lambda k: k['score'], reverse=True) name_table_label = Label(master=self.partial_result_frame, text='SUM SCORE', bg=GAME_COLOR[self.color.get()], width=20, height=2) name_table_label.grid(row=1, column=0, columnspan=3) name_label = Label(master=self.partial_result_frame, text='NAME', bg=EMPTY_COLOR[self.color.get()], width=10, height=2) name_label.grid(row=2, column=0, columnspan=2) score_label = Label(master=self.partial_result_frame, text='SCORE', bg=EMPTY_COLOR[self.color.get()], width=7, height=2) score_label.grid(row=2, column=2) for i in range(3, len(temp_sorted) + 3): #Rows print(i) name_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 3]['name']), bg=EMPTY_COLOR[self.color.get()], width=10, height=2) name_label_val.grid(row=i, column=0, columnspan=2) score_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 3]['score']), bg=EMPTY_COLOR[self.color.get()], width=7, height=2) score_label_val.grid(row=i, column=2) def show_all_games(self, event): self.result_showed.set(False) self.full_result_frame.grid_forget() self.partial_result_frame = Frame(self.result_frame, bg=GAME_COLOR[self.color.get()], width=EDGE_LENGTH * 2, height=EDGE_LENGTH) self.partial_result_frame.grid(padx=CELL_PAD, pady=CELL_PAD) quit_button = Button(master=self.partial_result_frame, text="Return", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=5, height=2) quit_button.grid(row=0, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=5) self.back_from_partial.set(True) quit_button.bind('<Button-1>', self.bring_back_result) result_dict = {} with open('result.json') as outfile: results = json.load(outfile) temp = results['result'] for i in temp: if i['name'] not in result_dict.keys(): result_dict[i['name']] = i else: if result_dict[i['name']]['score'] < i['score']: result_dict[i['name']] = i temp_sorted = list(result_dict.values()) name_table_label = Label(master=self.partial_result_frame, text='INDIVIDUAL BEST', bg=GAME_COLOR[self.color.get()], width=20, height=2) name_table_label.grid(row=1, column=0, columnspan=5) name_label = Label(master=self.partial_result_frame, text='NAME', bg=EMPTY_COLOR[self.color.get()], width=10, height=2) name_label.grid(row=2, column=0, columnspan=2) size_label = Label(master=self.partial_result_frame, text='SIZE', bg=EMPTY_COLOR[self.color.get()], width=5, height=2) size_label.grid(row=2, column=2) time_label = Label(master=self.partial_result_frame, text='TIME', bg=EMPTY_COLOR[self.color.get()], width=5, height=2) time_label.grid(row=2, column=3) score_label = Label(master=self.partial_result_frame, text='SCORE', bg=EMPTY_COLOR[self.color.get()], width=7, height=2) score_label.grid(row=2, column=4) for i in range(3, len(temp_sorted) + 3): #Rows print(i) name_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 3]['name']), bg=EMPTY_COLOR[self.color.get()], width=10, height=2) name_label_val.grid(row=i, column=0, columnspan=2) size_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 3]['size']), bg=EMPTY_COLOR[self.color.get()], width=5, height=2) size_label_val.grid(row=i, column=2) time_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 3]['time']), bg=EMPTY_COLOR[self.color.get()], width=5, height=2) time_label_val.grid(row=i, column=3) score_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 3]['score']), bg=EMPTY_COLOR[self.color.get()], width=7, height=2) score_label_val.grid(row=i, column=4) def show_score_by_name(self, event): current_name = event.widget['text'] self.result_showed.set(False) self.full_result_frame.grid_forget() self.partial_result_frame = Frame(self.result_frame, bg=GAME_COLOR[self.color.get()], width=EDGE_LENGTH * 2, height=EDGE_LENGTH) self.partial_result_frame.grid(padx=CELL_PAD, pady=CELL_PAD) quit_button = Button(master=self.partial_result_frame, text="Return", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=5, height=2) quit_button.grid(row=0, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=5) self.back_from_partial.set(True) quit_button.bind('<Button-1>', self.bring_back_result) with open('result.json') as outfile: results = json.load(outfile) temp = results['result'] temp_with_name = [] for i in temp: if i["name"] == current_name: temp_with_name.append(i) #labels temp_sorted = sorted(temp_with_name, key=lambda k: k['score'], reverse=True) name_label = Label(master=self.partial_result_frame, text='NAME', bg=EMPTY_COLOR[self.color.get()], width=10, height=2) name_label.grid(row=1, column=0, columnspan=2) size_label = Label(master=self.partial_result_frame, text='SIZE', bg=EMPTY_COLOR[self.color.get()], width=5, height=2) size_label.grid(row=1, column=2) time_label = Label(master=self.partial_result_frame, text='TIME', bg=EMPTY_COLOR[self.color.get()], width=5, height=2) time_label.grid(row=1, column=3) score_label = Label(master=self.partial_result_frame, text='SCORE', bg=EMPTY_COLOR[self.color.get()], width=7, height=2) score_label.grid(row=1, column=4) for i in range(2, len(temp_sorted) + 2): #Rows print(i) name_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 2]['name']), bg=EMPTY_COLOR[self.color.get()], width=10, height=2) name_label_val.grid(row=i, column=0, columnspan=2) size_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 2]['size']), bg=EMPTY_COLOR[self.color.get()], width=5, height=2) size_label_val.grid(row=i, column=2) time_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 2]['time']), bg=EMPTY_COLOR[self.color.get()], width=5, height=2) time_label_val.grid(row=i, column=3) score_label_val = Label(master=self.partial_result_frame, text=str(temp_sorted[i - 2]['score']), bg=EMPTY_COLOR[self.color.get()], width=7, height=2) score_label_val.grid(row=i, column=4) def show_result(self, event=None): if self.result_showed.get() == False: self.partial_result_frame.grid_forget() self.result_showed.set(True) if not self.back_from_partial.get(): self.menu_frame.grid_forget() self.back_from_partial.set(False) self.result_frame = Frame(self, bg=GAME_COLOR[self.color.get()], width=EDGE_LENGTH * 2, height=EDGE_LENGTH) self.result_frame.grid(padx=CELL_PAD, pady=CELL_PAD) height = 12 width = 5 self.full_result_frame = Frame(self.result_frame, bg=GAME_COLOR[self.color.get()], width=EDGE_LENGTH * 2, height=EDGE_LENGTH) self.full_result_frame.grid(padx=CELL_PAD, pady=CELL_PAD) quit_button = Button(master=self.full_result_frame, text="Return", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=5, height=2) quit_button.grid(row=0, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=5) quit_button.bind('<Button-1>', self.close_result) with open('result.json') as outfile: results = json.load(outfile) temp = results['result'] #labels temp_sorted = sorted(temp, key=lambda k: k['score'], reverse=True) name_label = Button(master=self.full_result_frame, text='NAME', bg=EMPTY_COLOR[self.color.get()], width=10, height=2) name_label.grid(row=1, column=0, columnspan=2) name_label.bind('<Button-1>', self.show_all_games) size_label = Label(master=self.full_result_frame, text='SIZE', bg=EMPTY_COLOR[self.color.get()], width=5, height=2) size_label.grid(row=1, column=2) time_label = Label(master=self.full_result_frame, text='TIME', bg=EMPTY_COLOR[self.color.get()], width=5, height=2) time_label.grid(row=1, column=3) score_label = Button(master=self.full_result_frame, text='SCORE', bg=EMPTY_COLOR[self.color.get()], width=7, height=2) score_label.grid(row=1, column=4) score_label.bind('<Button-1>', self.show_sum_score) for i in range(2, height): #Rows print(i) name_label_val = Button(master=self.full_result_frame, text=str(temp_sorted[i - 2]['name']), bg=EMPTY_COLOR[self.color.get()], width=10, height=2) name_label_val.grid(row=i, column=0, columnspan=2) name_label_val.bind('<Button-1>', self.show_score_by_name) size_label_val = Label(master=self.full_result_frame, text=str(temp_sorted[i - 2]['size']), bg=EMPTY_COLOR[self.color.get()], width=5, height=2) size_label_val.grid(row=i, column=2) time_label_val = Label(master=self.full_result_frame, text=str(temp_sorted[i - 2]['time']), bg=EMPTY_COLOR[self.color.get()], width=5, height=2) time_label_val.grid(row=i, column=3) score_label_val = Label(master=self.full_result_frame, text=str(temp_sorted[i - 2]['score']), bg=EMPTY_COLOR[self.color.get()], width=7, height=2) score_label_val.grid(row=i, column=4) def close_result(self, event=None): self.result_showed.set(False) self.result_frame.grid_forget() self.menu_frame.grid() def start_game(self, event): self.gravitational = False self.score = 0 self.timer = 0 self.grid_cells = [] self.status_cells = [] self.new_game = False self.ingame = True current_game_type = self.game_type_code.get() if current_game_type == 1: self.gravitational = True else: self.gravitational = False game_functions.N = self.game_size.get() self.menu_frame.grid_forget() self.game_frame.grid() self.build_grid() self.init_matrix() self.draw_grid_cells() def continue_game(self, event): file_data = open('time.txt', 'r') self.game_size.set(int(file_data.readline().strip())) game_functions.N = self.game_size.get() game_functions.init_var() self.gravitational = (file_data.readline().strip() == 'True') self.matrix = np.genfromtxt('matrix.csv', delimiter=',', dtype=np.int16) self.score = int(np.sum(self.matrix)) self.timer = int(file_data.readline().strip()) self.grid_cells = [] self.status_cells = [] self.new_game = False self.ingame = True self.menu_frame.grid_forget() self.game_frame.grid() self.build_grid() self.draw_grid_cells() def sound_play(self): if self.sound.get() == True: pygame.mixer.music.play(loops=-1) else: pygame.mixer.music.stop() def change_color(self): self.configure(bg=GAME_COLOR[self.color.get()]) for child in self.winfo_children(): if type(child).__name__ in ['Button', 'Label', 'Radiobutton']: child.configure(bg=EMPTY_COLOR[self.color.get()]) else: child.configure(bg=GAME_COLOR[self.color.get()]) for child2 in child.winfo_children(): if type(child2).__name__ in ['Button', 'Label', 'Radiobutton']: child2.configure(bg=EMPTY_COLOR[self.color.get()]) else: child2.configure(bg=GAME_COLOR[self.color.get()]) for child3 in child2.winfo_children(): if type(child3).__name__ in [ 'Button', 'Label', 'Radiobutton' ]: child3.configure(bg=EMPTY_COLOR[self.color.get()]) else: child3.configure(bg=GAME_COLOR[self.color.get()]) for child4 in child3.winfo_children(): if type(child4).__name__ in [ 'Button', 'Label', 'Radiobutton' ]: child4.configure(bg=EMPTY_COLOR[self.color.get()]) else: child4.configure(bg=GAME_COLOR[self.color.get()]) for child5 in child4.winfo_children(): if type(child5).__name__ in [ 'Button', 'Label', 'Radiobutton' ]: child5.configure( bg=EMPTY_COLOR[self.color.get()]) else: child5.configure( bg=GAME_COLOR[self.color.get()]) self.game_para_cell.configure(bg=EMPTY_COLOR[self.color.get()]) for child in self.game_para_cell.winfo_children(): child.configure(bg=EMPTY_COLOR[self.color.get()]) def menu(self): self.configure(bg=GAME_COLOR[self.color.get()]) mute_icon = ImageTk.PhotoImage(Image.open("mute.png")) pygame.mixer.init() pygame.mixer.music.load("game_sound.mp3") self.sound_play() nav_bar = Frame(self.nav_bar, bg=GAME_COLOR[self.color.get()], width=self.nav_bar.winfo_width(), height=EDGE_LENGTH) nav_bar.grid(columnspan=2) soundframe = Frame(nav_bar, bg=EMPTY_COLOR[self.color.get()], width=np.floor(EDGE_LENGTH / self.game_size.get()) * 2, height=np.floor(EDGE_LENGTH / self.game_size.get())) soundframe.grid(row=0, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=2) sound_on_checkbutton = Radiobutton(soundframe, text="Sound on", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, value=True, variable=self.sound, padx=15, pady=10, command=self.sound_play) sound_on_checkbutton.grid(row=0, column=0, sticky=tk.W) sound_off_checkbutton = Radiobutton(soundframe, text="Sound off", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, value=False, variable=self.sound, padx=15, pady=10, command=self.sound_play) sound_off_checkbutton.grid(row=0, column=1, sticky=tk.W) colorframe = Frame(nav_bar, bg=EMPTY_COLOR[self.color.get()], width=np.floor(EDGE_LENGTH / self.game_size.get()) * 2, height=np.floor(EDGE_LENGTH / self.game_size.get())) colorframe.grid(row=1, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=2) light_mode_checkbutton = Radiobutton(colorframe, text="Light", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, value=0, variable=self.color, padx=15, pady=10, command=self.change_color) light_mode_checkbutton.grid(row=0, column=0, sticky=tk.W) dark_mode_checkbutton = Radiobutton(colorframe, text="Dark", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, value=1, variable=self.color, padx=15, pady=10, command=self.change_color) dark_mode_checkbutton.grid(row=0, column=1, sticky=tk.W) background = Frame(self.menu_frame, bg=GAME_COLOR[self.color.get()], width=self.menu_frame.winfo_width(), height=EDGE_LENGTH) background.grid() start_cell = Frame(background, bg=GAME_COLOR[self.color.get()], width=np.floor(EDGE_LENGTH / self.game_size.get()) * 2, height=np.floor(EDGE_LENGTH / self.game_size.get())) start_cell.grid(row=0, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=2) start_button = Button(master=start_cell, text="Start", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=10, height=2) start_button.grid(row=0, column=0, padx=CELL_PAD, pady=CELL_PAD) continue_button = Button(master=start_cell, text="Continue", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=10, height=2) continue_button.grid(row=0, column=1, padx=CELL_PAD, pady=CELL_PAD) self.game_para_cell = Frame(background, bg=EMPTY_COLOR[self.color.get()]) self.game_para_cell.grid(row=1, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=2) game_type_cell = Frame(self.game_para_cell, bg=EMPTY_COLOR[self.color.get()]) game_type_cell.grid(padx=CELL_PAD, pady=CELL_PAD, row=1, column=0) start_button.bind('<Button-1>', self.start_game) continue_button.bind('<Button-1>', self.continue_game) classic_checkbutton = Radiobutton(game_type_cell, text="Classic", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=LABEL_FONT, value=0, variable=self.game_type_code, padx=15, pady=10) classic_checkbutton.grid(row=1, column=0, sticky=tk.W) grav_checkbutton = Radiobutton(game_type_cell, text="Gravita", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=LABEL_FONT, value=1, variable=self.game_type_code, padx=15, pady=10) grav_checkbutton.grid(row=2, column=0, sticky=tk.W) game_size_cell = Frame(self.game_para_cell, bg=EMPTY_COLOR[self.color.get()]) game_size_cell.grid(padx=CELL_PAD, pady=CELL_PAD, row=1, column=1) size_4_checkbutton = Radiobutton(game_size_cell, text="4", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=LABEL_FONT, value=4, variable=self.game_size, padx=15, pady=10) size_4_checkbutton.grid(row=1, column=1, sticky=tk.W) size_5_checkbutton = Radiobutton(game_size_cell, text="5", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=LABEL_FONT, value=5, variable=self.game_size, padx=15, pady=10) size_5_checkbutton.grid(row=2, column=1, sticky=tk.W) result_button = Button(master=background, text="Top score", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=10, height=2) result_button.grid(row=3, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=2) result_button.bind('<Button-1>', self.show_result) def save_game(self, event): np.savetxt('matrix.csv', self.matrix, delimiter=',') with open('time.txt', 'w') as outfile: outfile.write('{}\n{}\n{}\n'.format(str(self.game_size.get()), str(self.gravitational), str(self.timer))) outfile.close() def build_grid(self): background = Frame(self.game_frame, bg=GAME_COLOR[self.color.get()], width=EDGE_LENGTH, height=EDGE_LENGTH) background.grid() info_cell = Frame(background, bg=GAME_COLOR[self.color.get()], width=EDGE_LENGTH, height=EDGE_LENGTH) score_cell = Frame(info_cell, bg=EMPTY_COLOR[self.color.get()], width=np.floor(EDGE_LENGTH / self.game_size.get()) * 2, height=np.floor(EDGE_LENGTH / self.game_size.get())) score_cell.grid(row=0, column=0, padx=CELL_PAD, pady=CELL_PAD, columnspan=2) score = Label(master=score_cell, text="score: " + str(self.score), bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=LABEL_FONT, width=10, height=2) score.grid() self.status_cells.append(score) timer_cell = Frame(info_cell, bg=EMPTY_COLOR[self.color.get()], width=np.floor(EDGE_LENGTH / self.game_size.get()) * 2, height=np.floor(EDGE_LENGTH / self.game_size.get())) timer_cell.grid(row=0, column=2, padx=CELL_PAD, pady=CELL_PAD, columnspan=2) timer = Label(master=timer_cell, text="timer: " + str(self.timer), bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=LABEL_FONT, width=10, height=2) timer.grid() save_cell = Frame(info_cell, bg=EMPTY_COLOR[self.color.get()], width=np.floor(EDGE_LENGTH / self.game_size.get()) * 2, height=np.floor(EDGE_LENGTH / self.game_size.get())) save_cell.grid(row=1, padx=CELL_PAD, pady=CELL_PAD, columnspan=4) save_button = Button(master=save_cell, text="Save", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=10, height=2) save_button.grid() info_cell.grid(columnspan=self.game_size.get()) save_button.bind('<Button-1>', self.save_game) self.status_cells.append(timer) self.timer_count() for row in range(1, self.game_size.get() + 1): grid_row = [] for col in range(self.game_size.get()): cell = Frame( background, bg=EMPTY_COLOR[self.color.get()], width=np.floor(EDGE_LENGTH / self.game_size.get()), height=np.floor(EDGE_LENGTH / self.game_size.get())) cell.grid(row=row, column=col, padx=CELL_PAD, pady=CELL_PAD) t = Label(master=cell, text="", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=LABEL_FONT, width=5, height=2) t.grid() grid_row.append(t) self.grid_cells.append(grid_row) def init_matrix(self): self.matrix = game_functions.initialize_game() def draw_grid_cells(self): for row in range(self.game_size.get()): for col in range(self.game_size.get()): tile_value = self.matrix[row][col] if not tile_value: self.grid_cells[row][col].configure( text="", bg=EMPTY_COLOR[self.color.get()]) else: self.grid_cells[row][col].configure( text=str(tile_value), bg=TILE_COLORS[self.color.get()][tile_value], fg=LABEL_COLORS[self.color.get()][tile_value]) self.status_cells[0].configure(text="score: " + str(self.score)) self.update_idletasks() def input_name(self, message="You Lose"): self.game_frame.grid_forget() background = Frame(self, bg=GAME_COLOR[self.color.get()], width=EDGE_LENGTH, height=EDGE_LENGTH) background.grid() message = Label(background, bg=GAME_COLOR[self.color.get()], font=LABEL_FONT, text=message + " " + str(self.score)).grid( row=0, column=0, columnspan=2) input_name_label = Label(background, text="Your name:", bg=GAME_COLOR[self.color.get()], justify=CENTER, font=LABEL_FONT, width=10, height=2).grid(row=1, column=0) input_name_entry = Entry(background, textvariable=self.player).grid(row=1, column=1, padx=CELL_PAD, pady=CELL_PAD) input_button = Button(background, text="Summit", bg=EMPTY_COLOR[self.color.get()], justify=CENTER, font=SMALL_FONT, width=10, height=2) input_button.grid(columnspan=2, padx=CELL_PAD, pady=CELL_PAD) def summit(event): if os.stat('result.json').st_size == 0: results = {} results['result'] = [{ 'name': 'admin', 'size': 4, 'time': 0, 'score': 0 }, { 'name': str(self.player.get()), 'size': int(self.game_size.get()), 'time': int(self.timer), 'score': int(self.score) }] with open('result.json', 'w') as outfile: json.dump(results, outfile, indent=4) else: with open('result.json') as outfile: results = json.load(outfile) temp = results['result'] y = { 'name': str(self.player.get()), 'size': int(self.game_size.get()), 'time': int(self.timer), 'score': int(self.score) } temp.append(y) with open('result.json', 'w') as outfile: json.dump(results, outfile, indent=4) background.grid_forget() self.new_game = True self.menu_frame.grid() self.game_frame.destroy() self.game_frame = Frame(self) input_button.bind('<Button-1>', summit) def key_press(self, event): if self.ingame: valid_game = True key = repr(event.char) if key in self.commands: self.matrix, move_made, _ = self.commands[repr(event.char)]( self.matrix) if move_made: self.matrix = game_functions.add_new_tile(self.matrix) self.score = np.sum(self.matrix) self.draw_grid_cells() move_made = False if game_functions.check_for_win(self.matrix) == True: self.input_name("You Win") _, movable = game_functions.fixed_move(self.matrix) if movable == False: self.input_name("You Lost") def grav_mov(self): self.matrix, move_made, _ = self.commands[DOWN_KEY](self.matrix) if move_made: self.matrix = game_functions.add_new_tile(self.matrix) self.draw_grid_cells() move_made = False def timer_count(self): if not self.new_game: self.status_cells[1].configure(text="time: " + str(self.timer)) self.timer += 1 if (self.gravitational) & (self.timer % 5 == 3): self.grav_mov() self.after(1000, self.timer_count)
class SerialConfigFrame( Frame ): # pylint: disable=too-many-ancestors, too-many-instance-attributes """ Serial port configuration frame class. """ def __init__(self, container, *args, **kwargs): """ Constructor. :param tkinter.Frame container: reference to container frame :param args: optional args to pass to Frame parent class :param kwargs: optional kwargs for value ranges, or to pass to Frame parent class """ self._bpsrate_rng = kwargs.pop("bpsrates", BPSRATE_RNG) self._databits_rng = kwargs.pop("databits", DATABITS_RNG) self._stopbits_rng = kwargs.pop("stopbits", STOPBITS_RNG) self._parity_rng = kwargs.pop("parities", PARITY_RNG) self._timeout_rng = kwargs.pop("timeouts", TIMEOUT_RNG) self._preselect = kwargs.pop("preselect", ()) self._readonlybg = kwargs.pop("readonlybackground", BGCOL) Frame.__init__(self, container, *args, **kwargs) self._show_advanced = False self._noports = True self._ports = () self._port = StringVar() self._port_desc = StringVar() self._bpsrate = IntVar() self._databits = IntVar() self._stopbits = DoubleVar() self._parity = StringVar() self._rtscts = IntVar() self._xonxoff = IntVar() self._timeout = StringVar() self._body() self._do_layout() self._get_ports() self._attach_events() self.reset() def _body(self): """ Set up widgets. """ self._frm_basic = Frame(self) self._lbl_port = Label(self._frm_basic, text="Port") self._lbx_port = Listbox( self._frm_basic, border=2, relief="sunken", bg=self._readonlybg, width=28, height=5, justify=LEFT, exportselection=False, ) self._scr_portv = Scrollbar(self._frm_basic, orient=VERTICAL) self._scr_porth = Scrollbar(self._frm_basic, orient=HORIZONTAL) self._lbx_port.config(yscrollcommand=self._scr_portv.set) self._lbx_port.config(xscrollcommand=self._scr_porth.set) self._scr_portv.config(command=self._lbx_port.yview) self._scr_porth.config(command=self._lbx_port.xview) self._lbl_bpsrate = Label(self._frm_basic, text="Rate bps") self._spn_bpsrate = Spinbox( self._frm_basic, values=self._bpsrate_rng, width=8, state=READONLY, readonlybackground=self._readonlybg, wrap=True, textvariable=self._bpsrate, ) self._btn_toggle = Button( self._frm_basic, text=ADVOFF, width=3, command=self._on_toggle_advanced ) self._frm_advanced = Frame(self) self._lbl_databits = Label(self._frm_advanced, text="Data Bits") self._spn_databits = Spinbox( self._frm_advanced, values=self._databits_rng, width=3, state=READONLY, readonlybackground=self._readonlybg, wrap=True, textvariable=self._databits, ) self._lbl_stopbits = Label(self._frm_advanced, text="Stop Bits") self._spn_stopbits = Spinbox( self._frm_advanced, values=self._stopbits_rng, width=3, state=READONLY, readonlybackground=self._readonlybg, wrap=True, textvariable=self._stopbits, ) self._lbl_parity = Label(self._frm_advanced, text="Parity") self._spn_parity = Spinbox( self._frm_advanced, values=self._parity_rng, width=6, state=READONLY, readonlybackground=self._readonlybg, wrap=True, textvariable=self._parity, ) self._chk_rts = Checkbutton( self._frm_advanced, text="RTS/CTS", variable=self._rtscts ) self._chk_xon = Checkbutton( self._frm_advanced, text="Xon/Xoff", variable=self._xonxoff ) self._lbl_timeout = Label(self._frm_advanced, text="Timeout (s)") self._spn_timeout = Spinbox( self._frm_advanced, values=self._timeout_rng, width=4, state=READONLY, readonlybackground=self._readonlybg, wrap=True, textvariable=self._timeout, ) def _do_layout(self): """ Layout widgets. """ self._frm_basic.grid(column=0, row=0, columnspan=4, sticky=(W, E)) self._lbl_port.grid(column=0, row=0, sticky=(W)) self._lbx_port.grid(column=1, row=0, sticky=(W, E), padx=3, pady=3) self._scr_portv.grid(column=2, row=0, sticky=(N, S)) self._scr_porth.grid(column=1, row=1, sticky=(E, W)) self._lbl_bpsrate.grid(column=0, row=2, sticky=(W)) self._spn_bpsrate.grid(column=1, row=2, sticky=(W), padx=3, pady=3) self._btn_toggle.grid(column=2, row=2, sticky=(E)) self._frm_advanced.grid_forget() self._lbl_databits.grid(column=0, row=0, sticky=(W)) self._spn_databits.grid(column=1, row=0, sticky=(W), padx=3, pady=3) self._lbl_stopbits.grid(column=2, row=0, sticky=(W)) self._spn_stopbits.grid(column=3, row=0, sticky=(W), padx=3, pady=3) self._lbl_parity.grid(column=0, row=1, sticky=(W)) self._spn_parity.grid(column=1, row=1, sticky=(W), padx=3, pady=3) self._chk_rts.grid(column=2, row=1, sticky=(W)) self._chk_xon.grid(column=3, row=1, sticky=(W), padx=3, pady=3) self._lbl_timeout.grid(column=0, row=2, sticky=(W)) self._spn_timeout.grid(column=1, row=2, sticky=(W), padx=3, pady=3) def _attach_events(self): """ Bind events to widgets. """ self._lbx_port.bind("<<ListboxSelect>>", self._on_select_port) def _get_ports(self): """ Populate list of available serial ports using pyserial comports tool. Attempt to automatically select a serial device matching a list of 'preselect' devices (only works on platforms which parse UART device desc or HWID e.g. Posix). """ self._ports = sorted(comports()) init_idx = 0 port = "" desc = "" if len(self._ports) > 0: for idx, (port, desc, _) in enumerate(self._ports, 1): self._lbx_port.insert(idx, port + ": " + desc) for dev in self._preselect: if dev in desc: init_idx = idx break self._noports = False else: self._noports = True self.enable_controls(True) self._lbx_port.activate(init_idx) self._port.set(port) self._port_desc.set(desc) def _on_select_port(self, *args, **kwargs): # pylint: disable=unused-argument """ Get selected port from listbox and set global variable. """ idx = self._lbx_port.curselection() if idx == "": idx = 0 port_orig = self._lbx_port.get(idx) port = port_orig[0: port_orig.find(":")] desc = port_orig[port_orig.find(":") + 1:] if desc == "": desc = "device" self._port.set(port) self._port_desc.set(desc) def _on_toggle_advanced(self): """ Toggle advanced serial port settings panel on or off. """ self._show_advanced = not self._show_advanced if self._show_advanced: self._frm_advanced.grid(column=0, row=1, columnspan=3, sticky=(W, E)) self._btn_toggle.config(text=ADVON) else: self._frm_advanced.grid_forget() self._btn_toggle.config(text=ADVOFF) def enable_controls(self, disabled: bool=False): """ Enable or disable controls (e.g. to prevent changes when serial device is connected). :param bool disabled: disable controls flag """ for widget in ( self._lbl_port, self._lbl_bpsrate, self._lbl_databits, self._lbl_stopbits, self._lbl_parity, self._lbl_timeout, self._chk_rts, self._chk_xon, self._lbx_port, ): widget.configure(state=(DISABLED if disabled else NORMAL)) for widget in ( self._spn_bpsrate, self._spn_databits, self._spn_stopbits, self._spn_parity, self._spn_timeout, ): widget.configure(state=(DISABLED if disabled else READONLY)) def reset(self): """ Reset settings to defaults (first value in range). """ self._bpsrate.set(self._bpsrate_rng[0]) self._databits.set(self._databits_rng[0]) self._stopbits.set(self._stopbits_rng[0]) self._parity.set(self._parity_rng[0]) self._rtscts.set(False) self._xonxoff.set(False) self._timeout.set(self._timeout_rng[0]) @property def noports(self) -> bool: """ Getter for noports flag, which indicates if there are no serial ports available. :return: noports flag (True/False) :rtype: bool """ return self._noports @property def port(self) -> str: """ Getter for port. :return: selected port :rtype: str """ return self._port.get() @property def port_desc(self) -> str: """ Getter for port description. :return: selected port description :rtype: str """ return self._port_desc.get() @property def bpsrate(self) -> int: """ Getter for bps rate (commonly but incorrectly referred to as baud rate). :return: selected baudrate :rtype: int """ return self._bpsrate.get() @property def databits(self) -> int: """ Getter for databits. :return: selected databits :rtype: int """ return self._databits.get() @property def stopbits(self) -> float: """ Getter for stopbits. :return: selected stopbits :rtype: float """ return self._stopbits.get() @property def parity(self) -> str: """ Getter for parity. :return: selected parity :rtype: str """ return PARITIES[self._parity.get()] @property def rtscts(self) -> bool: """ Getter for rts/cts. :return: selected rts/cts :rtype: bool """ return self._rtscts.get() @property def xonxoff(self) -> bool: """ Getter for xon/xoff. :return: selected xon/xoff :rtype: bool """ return self._xonxoff.get() @property def timeout(self) -> float: """ Getter for timeout. :return: selected timeout :rtype: float (or None) """ if self._timeout.get() == "None": return None return float(self._timeout.get())
class AdventureGUI: def __init__(self): self.dungeon = Dungeon(4, 4) self.dungeon.generate() self.adventurer = Adventurer("") self.root = Tk() self.root.resizable(False, False) self.root.title("Dungeon Adventure") self.start_menu_init() def start(self): """Creates the tkinter window containing the game. Used to delay startup so that changes can be made to the dungeon and adventurer for testing specific cases.""" self.root.mainloop() def start_menu_init(self): """Builds the start menu for the game. Has a button to start a new game, display instructions and exit the program.""" self.startmenu = Frame(self.root) self.startmenu.grid(row=0, column=0) menu_spacer = Frame(self.startmenu, height=100, width=600).grid(row=0, column=0) title = Label(self.startmenu, text="502 Dungeon Adventure", font="Times 40", pady=50).grid(row=1, column=0) new_game_button = Button(self.startmenu, text="New Game", font="Times 20", command=self.game_init).grid(row=2, column=0) instructions_button = Button(self.startmenu, text="Instructions", font="Times 20", command=self.display_instructions).grid( row=3, column=0) exit_button = Button(self.startmenu, text="Exit", font="Times 20", command=self.root.destroy).grid(row=4, column=0) menu_spacer2 = Frame(self.startmenu, height=100, width=600).grid(row=5, column=0) def display_instructions(self): """Displays basic instructions for the game. Hides the start menu and replaces it with a screen containing text from a separate text file. Creates a button that will return the user to the start menu.""" self.startmenu.grid_forget() instruction_file = open("dungeon_instruct.txt", 'r') instruction_text = instruction_file.read() instruct_frame = Frame(self.root, height=600, width=600) instruct_frame.grid(row=0, column=0) t = Text(instruct_frame, wrap="word", font="Times 16") t.grid(row=0, column=0) t.insert("1.0", instruction_text) instruction_file.close() back_button = Button( instruct_frame, text="Back", font="Times 20", command=lambda: self.return_to_start(instruct_frame)).grid( row=1, column=0) def return_to_start(self, current): """Hides the tkinter object that is passed in and displays the start menu object.""" current.grid_forget() self.startmenu.grid(row=0, column=0) def game_init(self): """Creates a menu for choosing game settings. Provides an entry for setting an adventurer name and buttons for selecting the game difficulty. The default difficulty is easy and buttons are toggled.""" def set_difficulty(difficulty): if difficulty == "Hard": dungeon.resize_dungeon(10, 10) easy_button["relief"] = "raised" medium_button["relief"] = "raised" hard_button["relief"] = "sunken" elif difficulty == "Medium": dungeon.resize_dungeon(7, 7) easy_button["relief"] = "raised" medium_button["relief"] = "sunken" hard_button["relief"] = "raised" elif difficulty == "Easy": dungeon.resize_dungeon(4, 4) easy_button["relief"] = "sunken" medium_button["relief"] = "raised" hard_button["relief"] = "raised" else: pass dungeon = self.dungeon adventurer = self.adventurer self.startmenu.grid_forget() creation_menu = Frame(self.root) creation_menu.grid(row=0, column=0) new_name = Label(creation_menu, text="Adventurer Name: ", font="Times 14") new_name.grid(row=0, column=0, columnspan=2) name_entry = Entry(creation_menu, width=40) name_entry.grid(row=0, column=2) difficulty = Label(creation_menu, text="Choose difficulty:", font="Times 14") difficulty.grid(row=1, column=0, columnspan=2) hard_button = Button(creation_menu, text="Hard", command=lambda: set_difficulty("Hard")) hard_button.grid(row=2, column=2) medium_button = Button(creation_menu, text="Medium", command=lambda: set_difficulty("Medium")) medium_button.grid(row=3, column=2) easy_button = Button(creation_menu, text="Easy", relief="sunken", command=lambda: set_difficulty("Easy")) easy_button.grid(row=4, column=2) confirm_button = Button( creation_menu, text="Confirm", font="Times 16", command=lambda: self.start_game(name_entry.get(), creation_menu)) confirm_button.grid(row=6, column=0) back_button = Button( creation_menu, text="Back", font="Times 16", command=lambda: self.return_to_start(creation_menu)) back_button.grid(row=6, column=1) def start_game(self, name, current_canvas): """Checks if an adventurer name was given, if not, creates a popup prompting for a name. If a name is given, the creation menu is hidden, the dungeon is generated, and the adventurer is placed at the entrance. The main game logic is started by the Main_Game class. Adds the start menu to the window behind the main game to allow the game to restart if the main game ends.""" if name.strip() == "": error_window = Toplevel() error_window.title("Error") message = Label(error_window, text="Please enter a name", font="Times 20").grid(row=0, column=0) else: current_canvas.grid_forget() self.adventurer = Adventurer("") self.adventurer.name = name self.dungeon.generate() self.dungeon.visited_rooms.clear() self.dungeon.visited_rooms.append(self.dungeon.unique_rooms[0]) entrance = self.dungeon.unique_rooms[0].position() entrance_row, entrance_col = entrance[0], entrance[1] self.adventurer.set_location(entrance_row, entrance_col) self.startmenu.grid(row=0, column=0) main_game = Main_Game(self.root, self.dungeon, self.adventurer) main_game.frame.grid(row=0, column=0)
class MyScrolledText(Frame): def __init__(self, tkobj, *args, **kwargs): super().__init__(tkobj, **kwargs) #Textfeld self.textfeld = ScrolledText(self, relief='sunken', width=80, height=20, background='white', undo=True) self.textfeld.insert(INSERT, 'Bitte geben Sie den Einleitungstext ein! ') self.textfeld.grid(column=0, row=0, pady=5, padx=5, sticky=NW) #Frame Checkbutton + Latex-Befehle self.boxframe = Frame(self) self.boxframe.grid(column=1, row=0, pady=10, padx=10, sticky=NW) #Hinzufügen eines Checkbuttons self.c = BooleanVar() self.c.set(False) self.latexctn = Checkbutton(self.boxframe, text='LaTeX-Befehl aktivieren', var=self.c, command=self.LaFrhide) self.latexctn.grid(column=0, row=0, pady=5, padx=5, sticky=NW) #Frame - LaTeX-Befehle aktivieren self.LaFr = Frame(self.boxframe) self.LaFr.grid(column=2, row=0, pady=10, padx=10, sticky=N) #Button für LaTeX-Befehle self.btnit = Button(self.LaFr, text='kursiv', font=('Arial', 10, 'italic'), command=self.LaTeXitalic) self.btnit.grid(column=0, row=0, pady=5, sticky=(NW)) self.btnbd = Button(self.LaFr, text='fett', font=('Arial', 10, 'bold'), command=self.LaTeXbold) self.btnbd.grid(column=0, row=1, pady=5, sticky=(NW)) self.btnun = Button(self.LaFr, text='unterstrichen', font=('Arial', 10, 'underline'), command=self.LaTeXundl) self.btnun.grid(column=0, row=2, pady=5, sticky=(NW)) self.btntl = Button(self.LaFr, text='~', font=('Arial', 10, 'bold'), command=self.LaTeXTilde) self.btntl.grid(column=0, row=3, pady=5, sticky=(NW)) self.btntg = Button(self.LaFr, text='<', font=('Arial', 10, 'bold'), command=self.LaTeXless) self.btntg.grid(column=1, row=3, pady=5, sticky=(NW)) self.btntd = Button(self.LaFr, text='>', font=('Arial', 10, 'bold'), command=self.LaTeXgreater) self.btntd.grid(column=2, row=3, pady=5, sticky=(NW)) self.btnLi = Button(self.LaFr, text='Aufzählung', font=('Arial', 10), command=self.LaTeXBullet) self.btnLi.grid(column=0, row=4, pady=5, sticky=(NW)) self.btnim = Button(self.LaFr, text='Item', font=('Arial', 10), command=self.LaTeXItem) self.btnim.grid(column=1, row=4, pady=5, sticky=(NW)) self.btnNum = Button(self.LaFr, text='Nummerierung', font=('Arial', 10), command=self.LaTeXNum) self.btnNum.grid(column=0, row=5, pady=5, sticky=(NW)) #self.btnGr = Button(self.LaFr, text='Graphic', font=('Arial', 10), command=self.LaTeXGrafic) #self.btnGr.grid(column=0, row=6, pady=5, sticky=(NW)) self.LaFr.grid_forget() def get(self): return self.textfeld.get(1.0, END) def insert(self, *args): self.textfeld.insert(*args) def delete(self, *args): self.textfeld.delete(*args) def getflag(self): return self.c.get() def setflag(self, flag): self.c.set(flag) self.LaFrhide() def LaFrhide(self): if self.c.get() == False: self.LaFr.grid_forget() else: self.LaFr.grid(column=0, row=1, pady=10, padx=10, sticky=(N)) #------------------------------------ def LaTeXitalic(self): try: self.focus_get().insert(INSERT, '\\textit{}') except: pass #------------------------------------ def LaTeXbold(self): try: self.focus_get().insert(INSERT, '\\textbf{}') except: pass #------------------------------------ def LaTeXundl(self): try: self.focus_get().insert(INSERT, '\\underline{}') except: pass #------------------------------------ def LaTeXTilde(self): try: self.focus_get().insert(INSERT, r'$\sim$') except: pass #------------------------------------ def LaTeXless(self): try: self.focus_get().insert(INSERT, '\\textless{}') except: pass #------------------------------------ def LaTeXgreater(self): try: self.focus_get().insert(INSERT, '\\textgreater{}') except: pass #------------------------------------ def LaTeXBullet(self): try: self.focus_get().insert( INSERT, '\\begin{itemize}\n\\item lorem ipsum\n\\end{itemize}') except: pass #------------------------------------ def LaTeXNum(self): try: self.focus_get().insert( INSERT, '\\begin{enumerate}\n\\item lorem ipsum\n\\end{enumerate}') except: pass #------------------------------------ #def LaTeXGrafic(self): #try: #self.focus_get().insert(INSERT, '\\begin{figure}[h]\n\\centering\n\\includegraphics[width=4cm]{Dateiname}\n\\caption{Bildunterschrift}\n\\end{figure}') #except: #pass #------------------------------------ def LaTeXItem(self): try: self.focus_get().insert(INSERT, '\\item ') except: pass
class FormParentQuiz: def __init__(self, root): container = Frame(root) canvas = tk.Canvas(container) scrollbar = Scrollbar(container, orient="vertical", command=canvas.yview) self.frm_parent = Frame(canvas) self.frm_parent.bind( "<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all"))) canvas.create_window((0, 0), window=self.frm_parent, anchor="nw") canvas.configure(yscrollcommand=scrollbar.set) # for i in range(50): # Label(scrollable_frame, text="Sample scrolling label").pack() self.initialize_components() self.frm_child = FormChildQuiz(self.frm_parent) container.pack() canvas.pack(side="left", fill="both", expand=True) scrollbar.pack(side="right", fill="y") # self.frm_parent = Frame(root) # frm_parent1 = ScrolledFrame(window) # self.frm_parent = self.frm_parent1.display_widget(self.frm_parent5) # self.frm_parent.pack(side="top", expand=15, fill=None) # self.frm_parent = Frame(window) # vsb_frm_parent = Scrollbar(self.frm_parent, orient="vertical", command=self.frm_parent) # vsb_frm_parent.grid(row=2, column=10, pady=10, sticky=E) # self.frm_parent.configure(yscrollcommand=vsb_frm_parent.set) # vsb_txt_desc = Scrollbar(self.frm_aux1, orient="vertical", command=self.txt_description.yview) # vsb_txt_desc.grid(row=2, column=3, pady=10, sticky=NS) # self.frm_parent.configure(yscrollcommand=vsb_frm_parent.set) # self.initialize_components() # self.frm_child = FormChildQuiz(self.frm_parent) def initialize_components(self): # scrollbar = Scrollbar(self) # scrollbar.pack(side=RIGHT, fill=Y) # # area = Text(self, yscrollcommand=scrollbar.set) # area.pack(expand=True, fill='both') # scrollbar.config(command=area.yview) lbl_experimenter_title = Label(self.frm_parent, text='Quiz') lbl_experimenter_title.config(fg=TEXT_COLOR, font=TITLE_FONT) lbl_experimenter_title.grid(row=0, column=0, pady=20) def show_frm(self): self.frm_parent.grid(row=0, column=0) self.frm_child.show_frm() def hide_frm(self): self.frm_parent.grid_forget()