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 __init__(self, root, title): self.root = root self.root.title(title) # Variable that stores file handle (may be unnecessary) self.file_handle = "" master_frame = Frame(root) master_frame.pack(expand="yes", fill="both") # Create left button frame and buttons button_frame = Frame(master_frame) self.open_button = Button(button_frame, text="Choose File", command=self.load_file) self.open_button.pack(expand="yes", fill="both") self.apply_button = Button(button_frame, text="Apply", command=self.apply_consistent, state="disabled") self.apply_button.pack(expand="yes", fill="both") self.save_button = Button(button_frame, text="Save File", command=self.save_file, state="disabled") self.save_button.pack(expand="yes", fill="both") # Create text frame and initialize text widget text_frame = Frame(master_frame) self.text_box = Text(text_frame, height=10, width=50, state="disabled") self.text_box.pack(side="top", expand="yes", fill="both") # Configure weights for grid elements master_frame.columnconfigure(0, weight=1) master_frame.columnconfigure(1, weight=5) for i in range(3): master_frame.rowconfigure(i, weight=1) # Position button and text frames button_frame.grid(row=0, column=0, rowspan=3, sticky="nsew") text_frame.grid(row=0, column=1, rowspan=3, sticky="nsew") self.root.minsize(500, 200)
def _build_cell(self, row: int, col: int) -> Frame: cell = Frame(self._content, borderwidth=5, relief=const.SUNKEN, height=50, width=50) cell._canvas = Canvas(master=cell, height=50, width=50) cell.row = row cell.col = col cell.bound = False cell.grid(row=row, column=col, sticky="nsew") cell.columnconfigure(0, weight=1) cell.rowconfigure(0, weight=1) cell._canvas.grid(row=0, column=0, sticky="nsew") return cell
def __init__(self, runner): self.runner = runner self.messages = {} Screen.destroy() Screen.reinit() super().__init__() Screen.title("NaOH: PocketMine-MP Console") # GUI initialization fstframe = Frame(Screen.root) fstframe.grid(row=0, rowspan=1, columnspan=8) sndframe = Frame(Screen.root) sndframe.grid(row=0, rowspan=1, column=8, columnspan=2) self.scrollbar = Scrollbar(fstframe) self.listbox = Listbox(fstframe, yscrollcommand=self.scrollbar.set, width=120, height=25) self.listbox.grid(row=0, column=0, rowspan=1, columnspan=7, sticky='nswe') self.scrollbar.config(command=self.listbox.yview) self.scrollbar.grid(row=0, column=7, rowspan=1, sticky='nse') self.scrolllock = False Button(fstframe, text='나가기 (주의: 강제 종료됩니다)', command=self.runner.killAll).grid(row=1, column=0, sticky='nwse') self.slbutton = Button(fstframe, text='ScrollLock Off', command=self.togglesl) self.slbutton.grid(row=1, column=1, sticky='new') Label(fstframe, text='명령어: /', justify='right').grid(row=1, column=2) self.cmdentry = Entry(fstframe) self.cmdentry.bind('<Return>', self.put_cmd) self.cmdentry.grid(row=1, column=3, columnspan=5, sticky='nwe') fstframe.rowconfigure(1, weight=1) fstframe.columnconfigure(3, weight=1) fstframe.columnconfigure(4, weight=20) sndframe.rowconfigure(0, weight=1) Button(sndframe, text='서버 상태', command=lambda: statusScreen(self)).grid(row=0, sticky='n') Button(sndframe, text='설정 편집', command=lambda: propertiesScreen(self.runner.workdir + sep + 'server.properties')).grid(row=1, sticky='n') Button(sndframe, text='덤프 삭제', command=self.removeDumps).grid(row=2, sticky='n') self.cmdentry.focus() Screen.root.focus_force() # GUI initialization done self.thread = threading.Thread(target=lambda: asyncStream(self)).start() Screen.root.protocol("WM_DELETE_WINDOW", self.runner.killAll) Screen.root.mainloop() try: Screen.root.destroy() except: self.runner.killAll()
def showPlotTools(self): f2= Frame(self.selectPlotFrame, relief=FLAT,bg='#FADC46') f2.grid(row=1,column=0,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) b1.config(state=EguanaModel().machine.plot3DKButtonState) b2.config(state=EguanaModel().machine.plot3DDstButtonState) b3.config(state=EguanaModel().machine.plot3DDpButtonState) b4.config(state=EguanaModel().machine.plot2DKButtonState) b5.config(state=EguanaModel().machine.plot2DDstButtonState) b6.config(state=EguanaModel().machine.plot2DDpButtonState) 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)
class AffichageCalendrier(AbstractDisplayedCalendar): """ Affichage de calendrier classique. Si deux objets sont en même temps, ils sont affichés dans des colonnes séparées. """ def __init__(self, master=None, **kwargs): """ Affichage par défaut du calendrier et de ses tâches. @param master: NoteBook du DonneeCalendrier, master du tkinter.Frame() que cet objet est. @param **kwargs: Options de configuration du tkinter.Frame() que cet objet est. """ super().__init__(master) # Note : self.master est référence vers Notebook. self.__listeLabelHeure = [] # \ self.__listeLabelJour = [ ] # )-> Tout est dans le nom de ces trois listes. self.__listeSeparateurJour = [] # / # Vaudrait-il mieux pas utiliser la liste héritée self.listeTaskAffichees ? self.listeDisplayableItem = [ ] # Liste de la variante affichée de ces tâches. self.__frame = Frame( self, bg=self.getPalette() ["background"]) # Frame dans lequel tout s'affiche. self.__frame.pack(expand=YES, fill=BOTH) # Mise à jour de l'affichage. self.updateAffichage() # Pour mémoriser les différentes parts pour savoir si elles sont le même jour qu'une autre. # Est-ce vraiment nécessaire au vu de l'attribut self.__partsParColonnes qui répartie les parts # selon leurs colonnes ET DONC leur jour ? self.__parts = [] # Nombre de colonne par jour. # En effet, pour que le grid fasse en sorte que toutes les colonnes des jours soient de même taille, # il faut que toutes les colonnes de jours aient le même nombre de jours de grille chacunes. # C'est pour cela qu'il s'agit que d'une seule valeur. Elle est recalculée lors de chaque mise à jour # d'affichage via la méthode #updateAffichage() self.__nbColonneParJour = 1 self.__partsParColonnes = [] ## Binding self.getApplication().bind_all("<<Affichage-Classique-deselect-all>>", self.deselectAll, add=1) # self.deselectEverything() self.getApplication().bind_all( "<<Affichage-Classique-delete-selected>>", self.deleteSelected, add=1) self.getApplication().bind_all("<<Affichage-Classique-select-all>>", self.selectAll, add=1) self._setBinding("Classique", self.getApplication()) #self.bind("<Delete>", lambda e = None : self.event_generate("<<delete-selected>>")) #self.bind("<Configure>", lambda e : self.updateAffichage()) "" # Marque pour que le repli de code fasse ce que je veux ############# # Getters : # ############# "" def __getNbColonnePourJour(self, jour): """ Permet d'obtenir le nombre de colonne qu'il y a dans un jour donné. Note : la méthode __computePartsParColonnesDuJour appelée avec le même jour doit avoir été appelée auparavant pour travailler sur les dernières données. @param jour: datetime.date() correspondant au jour dont cherche le nombre de colonne d'items superposés. @return le nombre de colonne qu'il y a dans le jour demandé. """ try: return max( 1, len(self.__partsParColonnes[(jour - self.getJourDebut()).days])) except: return 1 def __getNoColonnePourPart(self, part): """ Permet de savoir la colonne sur laquelle une DatetimeItemPart() doit être positionnée par rapport à la colonne de son jour. @param part: le DatetimeItemPart() dont on veut savoir la position. @return le numéro de la colonne par rapport à sa colonne de son jour. """ for jour in range(len(self.__partsParColonnes)): colonne = 0 colPerColumn = self.__nbColonneParJour / max( 1, len(self.__partsParColonnes[jour])) for st in self.__partsParColonnes[jour]: for p in st: if p == part: return colonne colonne += colPerColumn return 0 def getPartRectangle(self, part): """ Permet d'obtenir le rectangle qui contient les informations de placement du AbstractItemContent lié à la DatetimeItemPart. Les coordonnées du rectangle sont comptées en coordonnées des cases dans la grille, et non en pixels. Une unité correspond à une case, si l'objet doit se mettre sur plusieurs cases, la largeur ou la hauteur du rectangle sera changé sur plus de 1. Dans tout les cas, faites attention à caster les coordonnées en int pour éviter les soucis lors du grid, car c'est bel et bien un grid qu'il faut faire ici. @param part: Le DatetimeItemPart dont on doit calculer la zone. @return le rectangle contenant les informations de placement du AbstractItemContent lié à la DatetimeItemPart demandé. Les informations sont données en cases de grid comme indiqué ci-dessus. """ # Colonnes : colonnespan = self.__nbColonneParJour / self.__getNbColonnePourJour( part.getJour()) colonne = 1 + ((part.getJour() - self.getJourDebut()).days) * ( self.__nbColonneParJour + 1) + self.__getNoColonnePourPart(part) # Note : à chaque fois le 1 + au début du calcul sert pour les lignes autant # que pour les colonnes à ignorer la première ligne ou la première colonne d'entête. # Lignes : temps0 = 1 + self.getHeureDebut().hour * 60 + self.getHeureDebut( ).minute temps1 = 1 + part.getHeureDebut().hour * 60 + part.getHeureDebut( ).minute temps2 = 1 + part.getHeureFin().hour * 60 + part.getHeureFin().minute ligne1 = 1 + temps1 - temps0 ligne2 = 1 + temps2 - temps0 # Création et renvoi du rectangle. rect = Rectangle(x1=colonne, width=colonnespan, y1=ligne1, y2=ligne2) return rect def getPartsOfDay(self, day): """ Permet d'obtenir toutes les DatetimeItemPart actuellement enregistrées via la méthode __precalculer() (qui ne prend en compte que les parts qui sont visibles) qui sont dans le jour demandé. @param day: Jour sur lequel on demande les parts. @return un générateur avec toutes les DatetimeItemPart qui sont le jour demandé. """ return (part for part in self.__parts if part.getJour() == day) "" ###################### # Méthodes liées aux # # schedulables # ###################### "" def addSchedulable(self, schedulable): """ Permet d'ajouter un objet planifiable à l'affichage dans le calendrier. @param schedulable: l'objet à rajouter pour l'affichage. @param region : correspond au début de l'objet planifiable si celle-ci n'en a pas. @return la tâche qui à peut-être été changé pour des raisons d'affichage. """ self.listeDisplayableItem.append(ObjetClassique(self, schedulable)) #self.updateAffichage() def identify_region(self, x, y): """ Renvoie la région à la position X et Y. X et Y sont relatifs à ce widget. La région doit être quelque chose qui doit permettre de savoir où ajouter une tâche si celle-ci n'a pas de début/période prédéfinie. (voir #addTask(tache, REGION = ...)) Cela doit donc correspondre à un ensemble avec une date/heure de début, on utilisera pour cela la classe datetime.datetime(). @param x: Position X relative à ce widget, sera bien souvent la position de la souris. @param y: Position Y relative à ce widget, sera bien souvent la position de la souris. @return datetime.datetime() indiquant la région trouvé aux coordonnées indiquées. @override indentify_region in AbstractDisplayedCalendar """ # On regarde si c'est trop à gauche (sur les heures): colonne, ligne = self.__frame.grid_location(x, y) colonne = (colonne - 1) // 2 jour = self.getJourDebut() + datetime.timedelta(days=colonne) jour = datetime.datetime(jour.year, jour.month, jour.day) minute = self.getHeureDebut().hour * 60 + (ligne - 1) heure, minute = minute // 60, minute % 60 # TODO : A Changer : return jour + datetime.timedelta(hours=heure, minutes=minute) def removeSchedulable(self, obj): """ Retire un schedulable de la liste @param obj : <schedulable> celui qu'il faut retirer """ print("removing :", obj) for item in reversed(self.listeDisplayableItem): if isinstance(item, ObjetClassique): if item.getSchedulable() == obj: self.listeDisplayableItem.remove(item) print("removed") self.updateAffichage(True) def resetSchedulable(self): """ Permet de vider self.listeDisplayableItem """ self.listeDisplayableItem = [] "" ################################## # Méthodes liées à l'affichage : # ################################## "" def __adapteGrid(self): """ Permet d'étirer les cases du grid, sauf la ligne d'entête des jours et la colonne d'entête des heures. Cette méthode se doit d'être appelée une fois que tout est dessiné, sinon ce qui serais rajouté après n'aurait pas forcément eu cet étirage des cases. """ # à mettre À LA FIN ! ! ! (pour les expands) for column in range(self.getNbJour() * (self.__nbColonneParJour + 1)): if column % (self.__nbColonneParJour + 1) == 0: self.__frame.columnconfigure(column, weight=0) else: self.__frame.columnconfigure(column, weight=1) self.__frame.rowconfigure(ALL, weight=1) self.__frame.rowconfigure(0, weight=0) def __afficherLesHeures(self): """ Permet de mettre à jour les labels des heures. """ # On efface ceux déjà présent : self.__listeLabelHeure = [] # et on les recrées : for heure in range(self.getHeureDebut().hour, self.getHeureFin().hour + 1): # le +1 pour compter Début ET Fin. self.__listeLabelHeure.append( Label(self.__frame, text=heure, bd=1, relief=SOLID, bg=self.getPalette()["highlightedWidget"])) # Note : Un détail à la minute près va être fait, # donc on compte 60 lignes pour une heure. # La ligne 0 étant la ligne des labels des jours, # On compte à partir de 1, c'est-à-dire en ajoutant 1. self.__listeLabelHeure[-1].grid( row=(heure - self.getHeureDebut().hour) * 60 + 1, # le *60 pour faire un détail à la minute près column= 0, # Les labels des heures sont réservés à la colonne de gauche. rowspan=60, # Mais ils prennent 60 minutes et lignes. sticky="NSWE" ) # Permet de centrer le label et d'en remplir les bords par la couleur du fond. #self.__adapteGrid() def __afficherLesJours(self): """ Permet de mette à jour les labels des jours. """ self.__listeLabelJour = [] self.__listeSeparateurJour = [] # Variable qui parcours la liste, rangeDate n'est pas fonctionnelle car après il y un soucis de last entre période et 2/5/... jours jour = self.getJourDebut() for compteur in range(self.getNbJour()): # Est-ce que le jour est sélectionné ? jourSelectionne = self.getDonneeCalendrier().isJourSelected(jour) #self.__listeLabelJour.append(Label(self.__frame, text=JOUR[jour.weekday()]+"\nfisefoijsoifjsoiejfiosef\njofijesoifjosiejfoi", bg = "#91C9F7" if jourSelectionne else "light grey", font = ("TkFixedFont"))) self.__listeLabelJour.append( self._makeTextWidget(jour, master=self.__frame)) #self.__listeLabelJour.append(TextWidget(self.__frame, text=JOUR[jour.weekday()] + "", nbJour = self.getNbJour())) self.__listeLabelJour[-1].bind( "<Button-1>", lambda e, jour=jour: self.selectJour(jour)) self.__listeLabelJour[-1].bind( "<Control-Button-1>", lambda e, jour=jour: self.selectJour(jour, control=True)) self.__listeLabelJour[-1].grid( row=0, column=1 + ((jour - self.getJourDebut()).days) * (self.__nbColonneParJour + 1), columnspan=self.__nbColonneParJour, sticky="NSWE") if jour < self.getJourFin(): self.__listeSeparateurJour.append( Separator(self.__frame, orient=VERTICAL)) self.__listeSeparateurJour[-1].grid( row=0, column=(self.__nbColonneParJour + 1) * (1 + (jour - self.getJourDebut()).days), rowspan=60 * (self.getHeureFin().hour + 1 - self.getHeureDebut().hour) + 1, sticky="NS") jour += datetime.timedelta(days=1) # Cela permet de réadapter les lignes et colonnes qui sont en expand pour le grid. self.__adapteGrid() def __afficherLesTaches(self): """ Permet de mettre à jour l'affichage des tâches et autres objets planifiables. """ for displayable in self.listeDisplayableItem: displayable.redraw(self.__frame) def __computePartsParColonnesDuJour(self, jour): """ Permet de calculer les multi-colonne d'un jour donné. @param jour: datetime.date() correspondant au jour dont on calcule le multi-colonne des objets. @return une liste de set() correspondant chacuns à la répartition des DatetimeItemPart()s dans les différentes colonnes. Un set() est une colonne, et chaques éléments de ces set()s est un DatetimeItemPart """ partsParColonnes = [] for part in self.getPartsOfDay(jour): index = 0 intersecting = True while intersecting: intersecting = False if len(partsParColonnes) <= index: partsParColonnes.append(set()) for p in partsParColonnes[index]: if part.intersectWith(p): index += 1 intersecting = True break partsParColonnes[index].add(part) return partsParColonnes def __precalculer(self): """ Permet de précalculer les Parts non fusionnées des tâches affichées dans ce calendrier. Permet aussi de calculer les multi-colonnes quand deux objets sont censés s'afficher en même temps. """ for displayable in self.listeDisplayableItem: if isinstance(displayable, AbstractMultiFrameItem): self.__parts.extend(displayable.getRepartition()) parts = [] for i in range(len(self.__parts)): part = self.getVisiblePart(self.__parts[i]) if part is not None: parts.append(part) self.__parts = parts jour = self.getJourDebut() self.__nbColonneParJour = 1 self.__partsParColonnes = [] for compteur in range(self.getNbJour()): self.__partsParColonnes.append( self.__computePartsParColonnesDuJour(jour)) self.__nbColonneParJour = ppcm(self.__nbColonneParJour, self.__getNbColonnePourJour(jour)) jour += datetime.timedelta(days=1) def updateAffichage(self, force=False): """ Permet de mettre à jour l'affichage. @override #updateAffichage() in AbstractDisplayedCalendar """ # On détruit et recrée le Frame self.__frame.destroy() self.__parts = [] self.__frame = Frame(self, bg=self.getPalette()["background"]) self.__frame.pack(expand=YES, fill=BOTH) self.__frame.bind("<Button-1>", lambda e: self.__onClicSurFrame(), add=True) # On précalcule : self.__precalculer() # On affiche les trucs self.__afficherLesHeures() self.__afficherLesJours() self.__afficherLesTaches() def updateColor(self): """ Permet de mettre à jour la couleur de tout les IDisplayableItem()s. """ for displayable in self.listeDisplayableItem: displayable.updateColor(self.__frame) # Ci-dessous, une petite customisation, qui permet de faire que les labels des jours soient coloré quand le jour en question est sélectionné. # Variable qui parcours la liste, rangeDate n'est pas fonctionnelle car après il y un soucis de last entre période et 2/5/... jours jour = self.getJourDebut() for compteur in range(self.getNbJour()): # Est-ce que le jour est sélectionné ? jourSelectionne = "jour" if jour == datetime.date.today( ) else "highlightedWidget" jourSelectionne = "selected" if self.getDonneeCalendrier( ).isJourSelected(jour) else jourSelectionne self.__listeLabelJour[compteur].setColor(mode=jourSelectionne) # On incrémente le jour, car on a pas rangeDate, comme indiqué plus haut. jour += datetime.timedelta(days=1) "" ########################### # Méthodes des bindings : # ########################### "" def deleteSelected(self, event): """ Supprime tout ce qui est actuellement sélectionné @param event : <event> set à chercher la provenance de l'event """ if self.hasParent(self, event.widget): super().deleteSelected() def deselectAll(self, event): """ Désélectionne tout ce qui est actuellement sélectionné @param event : <event> sert à chercher la provenance de l'event """ if self.hasParent(self, event.widget): self.deselectEverything() def selectAll(self, event): """ Sélectionne tous les schedulables mais pas les jours @param event : <event> sert à chercher la provenance de l'event """ if self.hasParent(self, event.widget): for item in self.listeDisplayableItem: item.getSchedulable().setSelected(True, andInside=True) self.getDonneeCalendrier().updateColor() "" ##################### # Autres méthodes : # ##################### "" def __onClicSurFrame(self): self.deselectEverything() def clicSurObjet(self, objClassique, schedulableDisp=None, control=False): """ Méthode exécutée lors d'un clic sur un objet. @param objClassique: l'objet sur lequel l'utilisateur à cliqué. @param schedulable: l'objet planifiable cliqué si il y en a un. @param control: True si la touche control (command sur mac) a été activé lors de ce clic, False sinon. @override clicSurObjet(objet) in AbstractDisplayedCalendar() """ if control is False: self.deselectEverything() schedulableDisp.onClic(control) self.getDonneeCalendrier().updateColor()
class PW_Widget(object): def grid(self, row=0, column=0): self.pw_frame.grid(row=row, column=column) def winfo_x(self): return self.pw_frame.winfo_x() def winfo_width(self): return self.pw_frame.winfo_width() def winfo_y(self): return self.pw_frame.winfo_y() def winfo_height(self): return self.pw_frame.winfo_height() def destroy(self): self.pw_frame.destroy() def destroy_children(self): for child in self.pw_frame.winfo_children(): child.destroy() def keys(self): """Only get native_widget.keys()""" return list( self.native_widget.keys()) # + self.cobj.user_tkOptionD.keys() def cget(self, name): return self.native_widget.cget(name) def __getitem__(self, attr_name): """expected attr_name values: relief, background, fg, font, etc.""" if attr_name in self.cobj.user_tkOptionD: return self.cobj.user_tkOptionD[attr_name] if attr_name in self.cobj.default_tkOptionD: return self.cobj.default_tkOptionD[attr_name] return None def __setitem__(self, key, value): #print("Entering __setitem__ with key=",key,' and value=',value) if value is None: value = '' if value: self.cobj.user_tkOptionD[key] = value elif key in self.cobj.user_tkOptionD: # i.e. no value input, but key is in user_tkOptionD so delete it. del self.cobj.user_tkOptionD[key] # do nothing if no value and key not already in user_tkOptionD #print('Setting Item Attr:',key,' = ',value) self.set_native_widget_attr() def __init__(self, disp_frame, cobj): """ disp_frame is PreviewWin.prevFrame for Main objects disp_frame is the native_widget of pw_widget's parent otherwise cobj is target_tk_app_def.Component (e.g. cobj.widget_type, cobj.widget_name, cobj.row, cobj.col, cobj.tab_label, cobj.tkvar, cobj.user_tkOptionD """ self.disp_frame = disp_frame self.cobj = cobj self.pw_frame = Frame(disp_frame) self.pw_frame_background = self.pw_frame['background'] self.pw_frame_borderwidth = self.pw_frame['borderwidth'] self.pw_frame_highlightbackground = self.pw_frame[ 'highlightbackground'] #print('disp_frame: ',disp_frame.winfo_class()) #for child in disp_frame.winfo_children(): # print('child: ',child.winfo_class()) # print('child.keys()',child.keys()) # just in case row_weight or col_weight is applied to native_widget self.pw_frame.rowconfigure(0, weight=1) self.pw_frame.columnconfigure(0, weight=1) self.put_native_widget_into_pw_frame() def native_widget_clicked(self, event): """When native_widget is clicked, try to change grid_notebook tab.""" if self.cobj.target_app.grid_notebook is None: #print('grid_notebook is None') return nb_obj = self.cobj.target_app.grid_notebook nb_obj.set_current_tab_by_label(self.cobj.tab_label) def tab_of_notebook_changed(self, event): """When PreviewWin Tab changes, try to change grid_notebook tab.""" if self.cobj.target_app.grid_notebook is None: #print('grid_notebook is None') return nb = self.native_widget text = nb.tab(nb.select(), "text") nb_obj = self.cobj.target_app.grid_notebook for itab, (row, col, tab_name, tab_label) in enumerate(self.cobj.tab_nameL): #print( (row, col, tab_name, tab_label) ) if text == tab_label: nb_obj.set_current_tab_by_label(tab_name) #nb_obj.pw_widget.native_widget.select( itab ) #print('preview_win_widgets.tab_of_notebook_changed: set PreviewWin Tab to:', itab) break def tab_of_notebook_clicked(self, event): if self.cobj.target_app.grid_notebook is None: #print('grid_notebook is None') return #print('x:', event.x) #print('y:', event.y) nb = self.native_widget clicked_tab = nb.tk.call(nb._w, "identify", "tab", event.x, event.y) #print('clicked tab:', clicked_tab) active_tab = nb.index(nb.select()) #print(' active tab:', active_tab) self.tab_of_notebook_changed(event) #if clicked_tab == active_tab: # print( 'clicked_tab == active_tab' ) def put_native_widget_into_pw_frame(self): cobj = self.cobj if cobj.widget_type == 'Notebook': self.native_widget = Notebook(self.pw_frame, width=400, height=300) #self.native_widget.bind("<<NotebookTabChanged>>", self.tab_of_notebook_changed) self.native_widget.bind("<ButtonRelease-1>", self.tab_of_notebook_clicked) tab_label_str = cobj.user_tkOptionD.get('tab_labels', 'Pine\nBirch\nCherry') tab_labelL = tab_label_str.split('\n') # First tab is just to identify Notebook_xxx #tab_frame = Frame( self.native_widget ) #self.native_widget.add(tab_frame, text=cobj.widget_name) self.tab_frameL = [ ] # list of Frame objects used as tabs for Notebook # add desired tabs after that for tab_str in tab_labelL: tab_frame = Frame(self.native_widget) self.native_widget.add(tab_frame, text=tab_str) # save Frame objects to put Tab widgets onto. self.tab_frameL.append(tab_frame) elif cobj.widget_type == 'Frame': self.native_widget = Frame(self.pw_frame, bd=2, relief=GROOVE) elif cobj.widget_type == 'Spinbox': self.native_widget = Spinbox(self.pw_frame, from_=0, to=100) elif cobj.widget_type == 'Treeview': self.native_widget = Treeview(self.pw_frame) tree = self.native_widget # Inserted at the root, program chooses id: tree.insert('', 'end', 'widgets', text='Widget Tour') # Same thing, but inserted as first child: tree.insert('', 0, 'gallery', text=cobj.widget_name) # Treeview chooses the id: id = tree.insert('', 'end', text='Tutorial') # Inserted underneath an existing node: for tree_widget in sorted(tkWidgetsD.keys()): tree.insert('widgets', 'end', text=tree_widget) tree.insert(id, 'end', text='Tree') elif cobj.widget_type in ['RadioGroup', 'LabelFrame']: self.native_widget = LabelFrame(self.pw_frame, text=cobj.widget_name) elif cobj.widget_type == "Canvas": self.native_widget = Canvas(self.pw_frame) w = int(cobj.user_tkOptionD['width']) h = int(cobj.user_tkOptionD['height']) #self.native_widget.create_rectangle((2, 2, w-1, h-1), outline="blue") self.native_widget.config(bg='#aaffaa') self.native_widget.create_text(w // 2, h // 2, text=cobj.widget_name, fill="black", width=w, anchor='center') elif cobj.tkvar is None: # has no tk variable, so don't worry about it self.native_widget = tkWidgetsD[cobj.widget_type](self.pw_frame) # ============ The following all have tk variable controllers. =============== else: # e.g. StringVar # 'Entry' 'OptionMenu' 'Combobox' 'Checkbutton' 'Radiobutton' 'Scale' if cobj.widget_type == 'Entry': self.native_widget = Entry(self.pw_frame, textvariable=cobj.tkvar) elif cobj.widget_type == 'OptionMenu': self.native_widget = OptionMenu(self.pw_frame, cobj.tkvar, "one", "two", "three", "four") cobj.tkvar.set("two") elif cobj.widget_type == 'Combobox': self.native_widget = Combobox(self.pw_frame, textvariable=cobj.tkvar) self.native_widget['values'] = ('X', 'Y', 'Z') self.native_widget.current(0) elif cobj.widget_type == 'Checkbutton': self.native_widget = Checkbutton(self.pw_frame, variable=cobj.tkvar, onvalue="yes", offvalue="no") cobj.tkvar.set("yes") elif cobj.widget_type == 'Menubutton': self.native_widget = Menubutton(self.pw_frame, text=cobj.widget_name, relief=GROOVE) self.native_widget.menu = Menu(self.native_widget, tearoff=0) self.native_widget["menu"] = self.native_widget.menu for i, tkvar in enumerate(cobj.tkvar_list): self.native_widget.menu.add_checkbutton(label="option %i" % (i + 1, ), variable=tkvar) elif cobj.widget_type == 'Radiobutton': if cobj.tab_label.startswith("RadioGroup"): tkvar = cobj.target_app.compObjD[cobj.tab_label].tkvar self.native_widget = Radiobutton(self.pw_frame, variable=tkvar, value=cobj.widget_name) #print(cobj.widget_name,' is part of ',cobj.tab_label) self.native_widget.select() else: self.native_widget = Radiobutton(self.pw_frame, variable=cobj.tkvar, value=cobj.widget_name) #print(cobj.widget_name,' is an isolated radio button') elif cobj.widget_type == 'Scale': self.native_widget = Scale(self.pw_frame, variable=cobj.tkvar, from_=0, to=100) else: print("WARNING... ignoring tk variable for ", cobj.widget_name) self.native_widget = tkWidgetsD[cobj.widget_type]( self.pw_frame) self.has_y_scroll = False # might get set in self.set_native_widget_attr() self.has_x_scroll = False # might get set in self.set_native_widget_attr() self.vbar = False # might get set in self.set_native_widget_attr() self.hbar = False # might get set in self.set_native_widget_attr() if cobj.widget_type in ('Treeview', ): self.tooltip = CreateToolTip( self.pw_frame, text=cobj.widget_name, background=CONTROL_COLOR_D[cobj.widget_type]) else: self.tooltip = CreateToolTip( self.native_widget, text=cobj.widget_name, background=CONTROL_COLOR_D[cobj.widget_type]) #self.native_widget.pack(side=LEFT,expand=True,fill=BOTH) self.native_widget.grid(row=0, column=0) cobj.default_tkOptionD = get_properties_dict(self.native_widget) #if 'from' in cobj.default_tkOptionD: # cobj.default_tkOptionD['from_'] = cobj.default_tkOptionD['from'] self.set_native_widget_attr() # bind to native_widget_clicked so the grid_notebook tab can be set if cobj.widget_type != 'Notebook': self.native_widget.bind("<ButtonRelease-1>", self.native_widget_clicked) def maybe_add_y_scroll(self): if self.has_y_scroll: return # already have a y scroll widget else: self.has_y_scroll = True if self.cobj.widget_type == 'Canvas': w = int(self.cobj.user_tkOptionD['width']) h = int(self.cobj.user_tkOptionD['height']) self.native_widget.config(scrollregion=(0, 0, w, h * 2)) vbar = Scrollbar(self.pw_frame, orient=VERTICAL) vbar.grid(row=0, column=1, sticky='ns') vbar.config(command=self.native_widget.yview) self.native_widget.config(yscrollcommand=vbar.set) self.vbar = vbar def maybe_add_x_scroll(self): if self.has_x_scroll: return # already have a y scroll widget else: self.has_x_scroll = True if self.cobj.widget_type == 'Canvas': w = int(self.cobj.user_tkOptionD['width']) h = int(self.cobj.user_tkOptionD['height']) if self.has_y_scroll: self.native_widget.config(scrollregion=(0, 0, w * 2, h * 2)) else: self.native_widget.config(scrollregion=(0, 0, w * 2, h)) elif self.cobj.widget_type == 'Text': self.native_widget.config(wrap=NONE) hbar = Scrollbar(self.pw_frame, orient=HORIZONTAL) hbar.grid(row=1, column=0, sticky='ew', columnspan=2) hbar.config(command=self.native_widget.xview) self.native_widget.config(xscrollcommand=hbar.set) self.hbar = hbar def pw_highlight_widget(self): if self['background']: self.native_widget["background"] = "#FF6666" else: self.pw_frame["background"] = "#FF6666" self.pw_frame["highlightbackground"] = "#FF6666" self.pw_frame["borderwidth"] = 5 #print('did the Highlighting of pw widget') def pw_unhighlight_widget(self): if self['background']: # taken from user_tkOptionD or default_tkOptionD self.native_widget["background"] = self['background'] else: self.pw_frame["background"] = self.pw_frame_background self.pw_frame[ "highlightbackground"] = self.pw_frame_highlightbackground self.pw_frame["borderwidth"] = self.pw_frame_borderwidth def handle_scroll_logic(self): must_rebuild = False if self.cobj.user_tkOptionD.get('scrolly', 'no') == 'yes': self.maybe_add_y_scroll() elif self.has_y_scroll: must_rebuild = True # request is "no", but already have y scroll if self.cobj.user_tkOptionD.get('scrollx', 'no') == 'yes': self.maybe_add_x_scroll() elif self.has_x_scroll: must_rebuild = True # request is "no", but already have x scroll if must_rebuild: self.destroy_children() self.put_native_widget_into_pw_frame() def set_native_widget_attr(self): # NEED TO WAIT UNTIL PLACED INTO PARENT GRID BEFORE CHANGING ATTR. # set any user options (at this point only width and height) #print('user_tkOptionD =',self.cobj.user_tkOptionD,' for ',self.cobj.widget_name) self.handle_scroll_logic() for key, val in list(self.cobj.user_tkOptionD.items()): if key == 'sticky': # for sticky, need to set both pw_frame and native_widget set_attribute_if_possible(self.pw_frame, key, val) set_attribute_if_possible(self.native_widget, key, val) elif key in PW_FRAME_ATTR: set_attribute_if_possible(self.pw_frame, key, val) else: set_attribute_if_possible(self.native_widget, key, val)
# print("new size pixels: ", wi,hi) # mplCanvas.config(width=wi, height=hi) ; printBboxes("A") # #mplCanvas.grid(sticky=Tkconstants.NSEW) # canvas.itemconfigure(cwid, width=wi, height=hi) ; printBboxes("B") # canvas.config(scrollregion=canvas.bbox(Tkconstants.ALL),width=200,height=200) # figure.canvas.draw() ; printBboxes("C") # print() if __name__ == "__main__": root = Tk() # root.rowconfigure(1, weight=1) # root.columnconfigure(1, weight=1) frame = Frame(root) frame.grid(column=1, row=1, sticky=Tkconstants.NSEW) frame.rowconfigure(1, weight=1) frame.columnconfigure(1, weight=1) figure = plt.figure(dpi=150, figsize=(4, 4)) plt.plot(range(10), [math.sin(x) for x in range(10)]) addScrollingFigure(figure, frame) # buttonFrame = Frame(root) # buttonFrame.grid(row=1, column=2, sticky=Tkconstants.NS) # biggerButton = Button(buttonFrame, text="larger", # command=lambda : changeSize(figure, 1.5)) # biggerButton.grid(column=1, row=1) # smallerButton = Button(buttonFrame, text="smaller", # command=lambda : changeSize(figure, .5)) # smallerButton.grid(column=1, row=2)
class SimpleScatter(Frame): def __init__(self, parent, master): super(SimpleScatter, self).__init__(parent) self.window = master #type:VisAnaWindow self.parent = parent self.param_y = None self.param_x = None self.ds = self.window.ds #type:DataSource self.columnconfigure(1, weight=1) self.rowconfigure(0, weight=1) self.sidebar = Notebook(self) self.sidebar.grid(column=0, row=0, sticky=(S, W, N, E)) if self.ds is None: self.settings = SSControls(self.sidebar, self, None) self.sidebar.add(self.settings, text="Settings") #self.settings.grid(column=1, row=0, sticky=(S,W,N,E)) else: self.settings = SSControls(self.sidebar, self, self.ds.base().get_attr_names()) self.sidebar.add(self.settings, text="Settings") #self.settings.grid(column=0, row=0, sticky=(S,W,N,E)) self.param_x = self.settings.getX() self.param_y = self.settings.getY() self.create_tooltip_frame(destroy=False) self.was_normalized_before = False self.create_plot() self.select_rect = None def create_plot(self): self.fig = Figure(figsize=(5, 5), dpi=100) #type:Figure self.ax = self.fig.add_subplot(111) #type:Axes #self.ax2 = self.fig.add_subplot(212) self.ax.grid(True) self.canvas = FigureCanvasTkAgg(self.fig, self) #type:FigureCanvasTkAgg self.canvas.mpl_connect('motion_notify_event', self.handle_hover) self.canvas.mpl_connect('button_press_event', self.handle_mouse_down) self.canvas.mpl_connect('button_release_event', self.handle_mouse_up) #self.canvas.mpl_connect('pick_event', self.draw_tooltip) self.canvas.get_tk_widget().grid(column=1, row=0, sticky=(N, E, W, S), rowspan=2) # self.canvas_tb = NavigationToolbar2TkAgg(self.canvas, self.canvas.get_tk_widget()) #self.ctbwidget=tk.Frame(self) #self.ctbwidget.grid(column=1, row=4, sticky=(tk.N, tk.E, tk.W, tk.S)) #self.canvas_tb = NavigationToolbar2TkAgg(self.canvas, self.ctbwidget) #self.ax.callbacks.connect('xlim_changed', self.handle_changed_axes) #self.ax.callbacks.connect('ylim_changed', self.handle_changed_axes) util.zoom_factory(self.ax) #### Handle Graph signals ################### # PLOT-EVENT HANDLER def handle_changed_axes(self, ev=None): self.clean_tooltip() xlim = self.ax.get_xlim() ylim = self.ax.get_ylim() self.xmin = xlim[0] self.xmax = xlim[1] self.ymin = ylim[0] self.ymax = ylim[1] text = "Focus changed to: x=[{:.1f};{:.1f}] and y=[{:.1f};{:.1f}]".format( xlim[0], xlim[1], ylim[0], ylim[1]) self.window.history.add(text) ## is called by the plot to confirm if the mouseevent was inside/on a plotted line or a marker def handle_pick(self, line, mouseevent): if mouseevent.button == 1: return self.handle_mouse_event(mouseevent) else: return False, dict() ## is called to to do something when the mouse hovers over the plot and has changed its position. ## if no mousebutton is pressed and no points were selected, a hover-tooltip is shown. ## if the left button is pressed, (re-)draw the selection indicator def handle_hover(self, mouseevent): if self.ds is None: return if not mouseevent.button in [1, 3] and self.select_rect is None: isover, props = self.handle_mouse_event(mouseevent) if isover: self.draw_tooltip(mouseevent, props["ind"]) elif mouseevent.button in [1, 3]: ## handle case if mouse is outside the canvas if mouseevent.xdata == None: xmin = self.mouse_pressed[0] xmax = self.mouse_pressed[0] ymin = self.mouse_pressed[1] ymax = self.mouse_pressed[1] else: xmin = min(mouseevent.xdata, self.mouse_pressed[0]) xmax = max(mouseevent.xdata, self.mouse_pressed[0]) ymin = min(mouseevent.ydata, self.mouse_pressed[1]) ymax = max(mouseevent.ydata, self.mouse_pressed[1]) bbox = (xmin, ymin, xmax, ymax) self.clean_tooltip(True, emit=False) bbox2 = self.ax.transData.transform(bbox) c_height = self.canvas.figure.bbox.height bbox3 = (bbox2[0], c_height - bbox2[1], bbox2[2], c_height - bbox2[3]) self.select_rect = self.canvas.get_tk_widget().create_rectangle( bbox3, dash=".", outline=self.fgcol) ## is called whenever a mousebutton is clicked while the mouse is over the plot. ## if the left button is pushed, we begin to draw a selection area def handle_mouse_down(self, mouseevent): if mouseevent.button in [1, 3]: self.clean_tooltip(True) self.mouse_pressed = (mouseevent.xdata, mouseevent.ydata) ## is called whenever a mouse button is released while hovering over the plot ## if the left button was pressed and there are points within the selection area, select those points and show a ## tooltip containing information about those selected points. If not, clean up. def handle_mouse_up(self, mouseevent): if mouseevent.button in [1, 3]: ## handle case if mouse is outside the canvas if mouseevent.xdata == None: xmin = self.mouse_pressed[0] xmax = self.mouse_pressed[0] ymin = self.mouse_pressed[1] ymax = self.mouse_pressed[1] else: xmin = min(mouseevent.xdata, self.mouse_pressed[0]) xmax = max(mouseevent.xdata, self.mouse_pressed[0]) ymin = min(mouseevent.ydata, self.mouse_pressed[1]) ymax = max(mouseevent.ydata, self.mouse_pressed[1]) if xmin == xmax and ymin == ymax: self.clean_tooltip(True) else: if mouseevent.button == 1: if self.param_x == self.ds.get_time_colname(): xmin = mdates.num2date(xmin) xmax = mdates.num2date(xmax) if self.param_y == self.ds.get_time_colname(): ymin = mdates.num2date(ymin) ymax = mdates.num2date(ymax) self.ds.select("ss_selected", self.param_x, xmin, xmax, "ss_show") self.ds.select("ss_selected", self.param_y, ymin, ymax, "ss_selected") ind = self.ds.df("ss_selected").index.values if len(ind) > 0: text = "Selected area from ({:.1f}; {:.1f})\n\t to ({:.1f}; {:.1f})"\ .format(xmin,ymin,xmax,ymax) self.draw_tooltip(mouseevent, ind, True) self.window.history.add(text) # MAYBE #self.trigger_update(level=self.TIMELINE_SELECTION) else: self.clean_tooltip(True) else: self.clean_tooltip(True, emit=False) self.ax.set_xlim((xmin, xmax), emit=False) self.ax.set_ylim((ymin, ymax)) self.canvas.draw() ## handle any mouse event where it has to be clarified whether there's a marker under the mouse or not. If so, ## return all index values of the concerning markers. def handle_mouse_event(self, mouseevent, radius=5): """ find the points within a certain radius from the mouse in data coords and attach the index numbers of the found elements which are the data points that were picked """ self.clean_tooltip() if self.ds is None: return False, dict() # print("PICKER") # print(mouseevent, vars(mouseevent)) if self.param_x == self.ds.get_time_colname( ) or self.param_y == self.ds.get_time_colname(): return False, dict() xydata = self.ax.transData.transform( self.ds.df("ss_show")[[self.param_x, self.param_y]]).transpose() try: mxy = self.ax.transData.transform( [mouseevent.xdata, mouseevent.ydata]) except ValueError: return False, dict() xdata = xydata[0] ydata = xydata[1] mousex = mxy[0] mousey = mxy[1] if mouseevent.xdata is None: return False, dict() d = pd.np.sqrt((xdata - mousex)**2. + (ydata - mousey)**2.) ind = self.ds.df("ss_show").index.values[pd.np.nonzero( pd.np.less_equal(d, radius))[0]] if len(ind) > 0: props = dict(ind=ind) return True, props else: return False, dict() ## draws a tooltip and generates the information it contains from an event with/and a list of index values def draw_tooltip(self, event, ind=None, selected=False): if ind is None: ind = event.ind #event = event.mouseevent # Generate the Tooltip-String selstr = "" if selected: selstr = "selected " if len(ind) is 1: text = selstr + "value:" self.ds.select_ids("ss_selected", ind, "ss_show") for col, cdata in self.ds.df("ss_selected").iteritems(): text += '\n{}: {}'.format(col, cdata[ind[0]]) else: text = selstr + "%s values:" % len(ind) if not selected: self.ds.select_ids("ss_selected", ind, "ss_show") self.ds.aggregate("ss_sel_aggremin", "MIN", in_table="ss_selected") self.ds.aggregate("ss_sel_aggremax", "MAX", in_table="ss_selected") for col, cdata in self.ds.df("ss_sel_aggremin").iteritems(): #text += '\n{}:\n min:\t{}\n max:\t{}'.format(col, cdata[0], self.ds.df("ss_sel_aggremax")[col][0]) text += '\n{}: {} to {}'.format( col, cdata[0], self.ds.df("ss_sel_aggremax")[col][0]) # write the tooltip self.tooltip.set(text) # # Draw the box and write the string on it # # c_height = self.canvas.figure.bbox.height # c_width = self.canvas.figure.bbox.width # y = c_height - event.y # x = event.x # # # get bounding box of a possible tooltip # self.plot_tooltip = self.canvas.get_tk_widget().create_text(x + 2, y, anchor=tk.NW, text=text) # bbox = self.canvas.get_tk_widget().bbox(self.plot_tooltip) # self.canvas.get_tk_widget().delete(self.plot_tooltip) # # # print("bbox:", bbox) # # # make sure the tooltip is within bounds # if bbox[2] > c_width: # adj = -2 # if bbox[3] > c_height: # anchor = tk.SE # else: # anchor = tk.NE # else: # adj = 2 # if bbox[3] > c_height: # anchor = tk.SW # else: # anchor = tk.NW # # get the new bounding box # if anchor is not tk.NW: # =^= the anchor had to be modified # self.plot_tooltip = self.canvas.get_tk_widget().create_text(x + adj, y, anchor=anchor, text=text) # bbox = self.canvas.get_tk_widget().bbox(self.plot_tooltip) # self.canvas.get_tk_widget().delete(self.plot_tooltip) # # self.plot_tooltip_rect = self.canvas.get_tk_widget().create_rectangle(bbox, fill="yellow") # self.plot_tooltip = self.canvas.get_tk_widget().create_text(x + adj, y, anchor=anchor, text=text) ## remove the tooltip if shown def clean_tooltip(self, with_select_rect=False, emit=True): self.tooltip.set("") if with_select_rect and self.select_rect is not None: self.canvas.get_tk_widget().delete(self.select_rect) self.select_rect = None #if emit: #self.action_str = None #TODO #self.trigger_update(self.TIMELINE_SELECTION) #### Handle Signals from Outside #the selection changed, called by SSControls def params_changed(self, event=None): self.param_x = self.settings.getX() self.param_y = self.settings.getY() self.window.history.add("scatterplot: axes changed to ({},{})".format( self.param_x, self.param_y)) # Set Bounding Box for the plot #widen plot box by 2% on each side padding = 0.02 # 2% x_all = self.ds.get_data("ss_show").get_column(self.param_x) y_all = self.ds.get_data("ss_show").get_column(self.param_y) self.xmin = x_all.min() - padding * (x_all.max() - x_all.min()) self.xmax = x_all.max() + padding * (x_all.max() - x_all.min()) self.ymin = y_all.min() - padding * (y_all.max() - y_all.min()) self.ymax = y_all.max() + padding * (y_all.max() - y_all.min()) self.apply_settings() # a cluster recalculation was processed, called by VisAnaWindow.redo_plots def apply_settings(self, ev=None): if self.settings.do_white_on_black(): self.bgcol = "black" self.fgcol = "white" else: self.fgcol = "black" self.bgcol = "white" self.alpha = self.settings.get_alpha() self.s = self.settings.get_s() self.should_connect = self.settings.do_connect() self.redraw_plot() def redraw_plot(self): self.window.status.set("Redraw Plot...") self.draw_plot() self.window.status.set("") # the underlying data changed, called by VisAnaWindow.openFile def ds_changed(self): olds = self.ds self.ds = self.window.ds if olds is None: self.settings.destroy() newcols = self.window.calc.get_all_columns(with_custom=False) self.settings = SSControls(self.sidebar, self, newcols) self.sidebar.add(self.settings, text="Settings") self.create_tooltip_frame(destroy=True) #self.settings.grid(column=0, row=0, sticky=(S, W, N, E)) self.settings.set_new_cluster(0) #self.cluster_changed("base") def cluster_changed(self, in_table): #TODO what to do when graph not seen? #TODO multiple Graphs newcols = self.window.calc.get_all_columns(with_time=True, after_calc=True) self.ds.link("ss_show", in_table) self.settings.set_new_cols(newcols) #number of clusters if self.ds.get_data("ss_show").centroids is not None: k = len(self.ds.get_data("ss_show").centroids) self.settings.set_new_cluster(k) if self.param_x is None or self.param_x not in newcols or self.param_y not in newcols \ or not self.window.options.shouldNormalize() == self.was_normalized_before: self.params_changed() else: self.redraw_plot() self.was_normalized_before = self.window.options.shouldNormalize() #sync settings and redraw plot #self.create_plot() ## update view with specified data def draw_plot(self): #ax.plot(self.df[self.param_x], self.df[self.param_y], marker="o", linewidth=0, picker=self.line_picker) self.clean_tooltip(True) self.ax.clear() self.ax.grid(True) #if self.param_x == self.ds.get_time_colname() or self.param_y == self.ds.get_time_colname(): # #self.plot=self.ax.plot(x, y,picker=self.handle_pick)#, marker="o", linewidths=0,picker=self.handle_pick) # self.plot = self.ax.scatter(x=x, y=y, picker=self.handle_pick) #else: x_all = self.ds.get_data("ss_show").get_column(self.param_x) y_all = self.ds.get_data("ss_show").get_column(self.param_y) c = self.ds.get_data("ss_show").centroids if c is not None: for i in range(len(c)): if self.settings.clusel.draw_cluster(i): d = self.ds.df("ss_show") d2 = d.loc[d["_cluster"] == i] if self.param_x == self.ds.get_time_colname(): x = d2.index.values else: x = d2[self.param_x] if self.param_y == self.ds.get_time_colname(): y = d2.index.values else: y = d2[self.param_y] self.ax.scatter(x=x, y=y, marker="o", color=COLORS[i], s=self.s, alpha=self.alpha, linewidths=0, picker=self.handle_pick) #TOO SLOW # colors = self.ds.get_data("ss_show").get_column("_color") # self.ax.scatter(x=x_all, y=y_all, marker="o",color=colors, s=1, # alpha=0.4, linewidths=0, picker=self.handle_pick) else: self.ax.scatter(x=x_all, y=y_all, marker="o", color=self.fgcol, s=self.s, alpha=self.alpha, linewidths=0, picker=self.handle_pick) if self.should_connect: #print("HAI", type(x_all), type(y_all)) self.ax.plot( x=list(x_all), y=list(y_all), alpha=1, linewidth=5) #, color=self.fgcol, linewidth=5, ls="solid") util.set_backgroundcolor(self.ax, self.bgcol) self.ax.grid(color=self.fgcol) #util.set_foregroundcolor(self.ax,fgcol) self.ax.set_xlabel(self.param_x) self.ax.set_ylabel(self.param_y) self.ax.set_xlim(self.xmin, self.xmax, emit=False) self.ax.set_ylim(self.ymin, self.ymax, emit=False) self.ax.callbacks.connect('xlim_changed', self.handle_changed_axes) self.ax.callbacks.connect('ylim_changed', self.handle_changed_axes) self.fig.tight_layout(pad=0) if self.settings.doRegr() and not (self.param_y == self.ds.get_time_colname()): self.draw_regression() self.canvas.draw() def draw_regression(self): ## we need to remove rows with NaNs first completedf = self.ds.df("ss_show") completedf = completedf[pd.notnull(completedf[self.param_x])] completedf = completedf[pd.notnull(completedf[self.param_y])] if self.param_x == self.ds.get_time_colname(): completedf["delta_time"] = ( completedf[self.ds.get_time_colname()] - completedf[self.ds.get_time_colname()].min()) / np.timedelta64( 1, "m") X = completedf["delta_time"].to_frame() else: X = completedf[self.param_x].to_frame() y = completedf[self.param_y].to_frame() lr = LinearRegression() lr.fit(X, y) print(lr.coef_) if self.param_x == self.ds.get_time_colname(): self.ax.plot(completedf[self.ds.get_time_colname()], lr.predict(X), color="red") else: self.ax.plot(X, lr.predict(X), color="red") def has_selection(self) -> bool: return self.select_rect is not None def create_tooltip_frame(self, destroy): if destroy: self.tframe.destroy() self.tframe = Frame(self.sidebar) self.sidebar.add(self.tframe, text="Details") #self.tframe.grid(column=0, row=0, sticky=(S,W,N,E)) self.tframe.rowconfigure(0, weight=1) self.tframe.columnconfigure(0, weight=1) self.tooltip = StringVar(self.tframe) self.tlabel = Label(self.tframe, textvariable=self.tooltip, justify="left", anchor="nw", wraplength=200) font = Font(font=self.tlabel['font']) font["size"] = 7 self.tlabel["font"] = font self.tlabel.grid(column=0, row=0, sticky=(W, N))
class MLNQueryGUI(object): def __init__(self, master, gconf, directory=None): self.master = master self.initialized = False self.master.bind('<Return>', self.infer) self.master.bind('<Escape>', lambda a: self.master.quit()) self.master.protocol('WM_DELETE_WINDOW', self.quit) self.dir = os.path.abspath( ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) self.frame = Frame(master) self.frame.pack(fill=BOTH, expand=1) self.frame.columnconfigure(1, weight=1) row = 0 # pracmln project options Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0, sticky='ES') project_container = Frame(self.frame) project_container.grid(row=row, column=1, sticky="NEWS") # new proj file self.btn_newproj = Button(project_container, text='New Project...', command=self.new_project) self.btn_newproj.grid(row=0, column=1, sticky="WS") # open proj file self.btn_openproj = Button(project_container, text='Open Project...', command=self.ask_load_project) self.btn_openproj.grid(row=0, column=2, sticky="WS") # save proj file self.btn_updateproj = Button(project_container, text='Save Project...', command=self.noask_save_project) self.btn_updateproj.grid(row=0, column=3, sticky="WS") # save proj file as... self.btn_saveproj = Button(project_container, text='Save Project as...', command=self.ask_save_project) self.btn_saveproj.grid(row=0, column=4, sticky="WS") # grammar selection row += 1 Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E') grammars = ['StandardGrammar', 'PRACGrammar'] self.selected_grammar = StringVar() self.selected_grammar.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_grammar) + tuple(grammars)) l.grid(row=row, column=1, sticky='NWE') # logic selection row += 1 Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E') logics = ['FirstOrderLogic', 'FuzzyLogic'] self.selected_logic = StringVar() self.selected_logic.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics)) l.grid(row=row, column=1, sticky='NWE') # mln section row += 1 Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE') self.mln_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.mln', 'ftypes': [('MLN files', '.mln')] }, defaultname='*unknown{}', importhook=self.import_mln, deletehook=self.delete_mln, projecthook=self.save_proj, filecontenthook=self.mlnfilecontent, fileslisthook=self.mlnfiles, updatehook=self.update_mln, onchangehook=self.project_setdirty) self.mln_container.editor.bind("<FocusIn>", self._got_focus) self.mln_container.grid(row=row, column=1, sticky="NEWS") self.mln_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) row += 1 self.use_emln = IntVar() self.use_emln.set(0) self.cb_use_emln = Checkbutton(self.frame, text="use model extension", variable=self.use_emln, command=self.onchange_use_emln) self.cb_use_emln.grid(row=row, column=1, sticky="W") # mln extension section row += 1 self.emlncontainerrow = row self.emln_label = Label(self.frame, text="EMLN: ") self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE') self.emln_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.emln', 'ftypes': [('MLN extension files', '.emln') ] }, defaultname='*unknown{}', importhook=self.import_emln, deletehook=self.delete_emln, projecthook=self.save_proj, filecontenthook=self.emlnfilecontent, fileslisthook=self.emlnfiles, updatehook=self.update_emln, onchangehook=self.project_setdirty) self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NEWS") self.emln_container.editor.bind("<FocusIn>", self._got_focus) self.emln_container.columnconfigure(1, weight=2) self.onchange_use_emln(dirty=False) self.frame.rowconfigure(row, weight=1) # db section row += 1 Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE') self.db_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.db', 'ftypes': [('Database files', '.db')] }, defaultname='*unknown{}', importhook=self.import_db, deletehook=self.delete_db, projecthook=self.save_proj, filecontenthook=self.dbfilecontent, fileslisthook=self.dbfiles, updatehook=self.update_db, onchangehook=self.project_setdirty) self.db_container.grid(row=row, column=1, sticky="NEWS") self.db_container.editor.bind("<FocusIn>", self._got_focus) self.db_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) # inference method selection row += 1 self.list_methods_row = row Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E) self.selected_method = StringVar() self.selected_method.trace('w', self.select_method) methodnames = sorted(InferenceMethods.names()) self.list_methods = OptionMenu(*(self.frame, self.selected_method) + tuple(methodnames)) self.list_methods.grid(row=self.list_methods_row, column=1, sticky="NWE") # options row += 1 option_container = Frame(self.frame) option_container.grid(row=row, column=1, sticky="NEWS") # Multiprocessing self.multicore = IntVar() self.cb_multicore = Checkbutton(option_container, text="Use all CPUs", variable=self.multicore, command=self.settings_setdirty) self.cb_multicore.grid(row=0, column=2, sticky=W) # profiling self.profile = IntVar() self.cb_profile = Checkbutton(option_container, text='Use Profiler', variable=self.profile, command=self.settings_setdirty) self.cb_profile.grid(row=0, column=3, sticky=W) # verbose self.verbose = IntVar() self.cb_verbose = Checkbutton(option_container, text='verbose', variable=self.verbose, command=self.settings_setdirty) self.cb_verbose.grid(row=0, column=4, sticky=W) # options self.ignore_unknown_preds = IntVar() self.cb_ignore_unknown_preds = Checkbutton( option_container, text='ignore unkown predicates', variable=self.ignore_unknown_preds, command=self.settings_setdirty) self.cb_ignore_unknown_preds.grid(row=0, column=5, sticky="W") # queries row += 1 Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E) self.query = StringVar() self.query.trace('w', self.settings_setdirty) Entry(self.frame, textvariable=self.query).grid(row=row, column=1, sticky="NEW") # additional parameters row += 1 Label(self.frame, text="Add. params: ").grid(row=row, column=0, sticky="NE") self.params = StringVar() self.params.trace('w', self.settings_setdirty) self.entry_params = Entry(self.frame, textvariable=self.params) self.entry_params.grid(row=row, column=1, sticky="NEW") # closed-world predicates row += 1 Label(self.frame, text="CW preds: ").grid(row=row, column=0, sticky="E") cw_container = Frame(self.frame) cw_container.grid(row=row, column=1, sticky='NEWS') cw_container.columnconfigure(0, weight=1) self.cwPreds = StringVar() self.cwPreds.trace('w', self.settings_setdirty) self.entry_cw = Entry(cw_container, textvariable=self.cwPreds) self.entry_cw.grid(row=0, column=0, sticky="NEWS") self.closed_world = IntVar() self.cb_closed_world = Checkbutton(cw_container, text="CW Assumption", variable=self.closed_world, command=self.onchange_cw) self.cb_closed_world.grid(row=0, column=1, sticky='W') # output filename row += 1 output_cont = Frame(self.frame) output_cont.grid(row=row, column=1, sticky='NEWS') output_cont.columnconfigure(0, weight=1) # - filename Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="NE") self.output_filename = StringVar() self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename) self.entry_output_filename.grid(row=0, column=0, sticky="NEW") # - save option self.save = IntVar() self.cb_save = Checkbutton(output_cont, text="save", variable=self.save) self.cb_save.grid(row=0, column=1, sticky=W) # start button row += 1 start_button = Button(self.frame, text=">> Start Inference <<", command=self.infer) start_button.grid(row=row, column=1, sticky="NEW") self.settings_dirty = IntVar() self.project_dirty = IntVar() self.gconf = gconf self.project = None self.project_dir = os.path.abspath( ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) if gconf['prev_query_project':self.project_dir] is not None: self.load_project( os.path.join(self.project_dir, gconf['prev_query_project':self.project_dir])) else: self.new_project() self.config = self.project.queryconf self.project.addlistener(self.project_setdirty) self.mln_container.dirty = False self.emln_container.dirty = False self.db_container.dirty = False self.project_setdirty(dirty=False) self.master.geometry(gconf['window_loc_query']) self.initialized = True def _got_focus(self, *_): if self.master.focus_get() == self.mln_container.editor: if not self.project.mlns and not self.mln_container.file_buffer: self.mln_container.new_file() elif self.master.focus_get() == self.db_container.editor: if not self.project.dbs and not self.db_container.file_buffer: self.db_container.new_file() elif self.master.focus_get() == self.emln_container.editor: if not self.project.emlns and not self.emln_container.file_buffer: self.emln_container.new_file() def quit(self): if self.settings_dirty.get() or self.project_dirty.get(): savechanges = messagebox.askyesnocancel( "Save changes", "You have unsaved project changes. Do you want to save them before quitting?" ) if savechanges is None: return elif savechanges: self.noask_save_project() self.master.destroy() else: # write gui settings and destroy self.write_gconfig() self.master.destroy() ####################### PROJECT FUNCTIONS ################################# def new_project(self): self.project = MLNProject() self.project.addlistener(self.project_setdirty) self.project.name = DEFAULTNAME.format('.pracmln') self.reset_gui() self.set_config(self.project.queryconf) self.mln_container.update_file_choices() self.emln_container.update_file_choices() self.db_container.update_file_choices() self.project_setdirty(dirty=True) def project_setdirty(self, dirty=False, *args): self.project_dirty.set(dirty or self.mln_container.dirty or self.db_container.dirty or self.emln_container.dirty) self.changewindowtitle() def settings_setdirty(self, *args): self.settings_dirty.set(1) self.changewindowtitle() def changewindowtitle(self): title = (WINDOWTITLEEDITED if (self.settings_dirty.get() or self.project_dirty.get()) else WINDOWTITLE).format(self.project_dir, self.project.name) self.master.title(title) def ask_load_project(self): filename = askopenfilename(initialdir=self.dir, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln") if filename and os.path.exists(filename): self.load_project(filename) else: logger.info('No file selected.') return def load_project(self, filename): if filename and os.path.exists(filename): projdir, _ = ntpath.split(filename) self.dir = os.path.abspath(projdir) self.project_dir = os.path.abspath(projdir) self.project = MLNProject.open(filename) self.project.addlistener(self.project_setdirty) self.reset_gui() self.set_config(self.project.queryconf.config) self.mln_container.update_file_choices() self.db_container.update_file_choices() if len(self.project.mlns) > 0: self.mln_container.selected_file.set( self.project.queryconf['mln'] or list(self.project.mlns.keys())[0]) self.mln_container.dirty = False if len(self.project.emlns) > 0: self.emln_container.selected_file.set( self.project.queryconf['emln'] or list(self.project.emlns.keys())[0]) self.emln_container.dirty = False if len(self.project.dbs) > 0: self.db_container.selected_file.set( self.project.queryconf['db'] or list(self.project.dbs.keys())[0]) self.db_container.dirty = False self.write_gconfig(savegeometry=False) self.settings_dirty.set(0) self.project_setdirty(dirty=False) self.changewindowtitle() else: logger.error( 'File {} does not exist. Creating new project...'.format( filename)) self.new_project() def noask_save_project(self): if self.project.name and not self.project.name == DEFAULTNAME.format( '.pracmln'): self.save_project(os.path.join(self.project_dir, self.project.name)) else: self.ask_save_project() def ask_save_project(self): fullfilename = asksaveasfilename(initialdir=self.project_dir, confirmoverwrite=True, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln") self.save_project(fullfilename) def save_project(self, fullfilename): if fullfilename: fpath, fname = ntpath.split(fullfilename) fname = fname.split('.')[0] self.project.name = fname self.dir = os.path.abspath(fpath) self.project_dir = os.path.abspath(fpath) self.mln_container.save_all_files() self.emln_container.save_all_files() self.db_container.save_all_files() self.update_config() self.project.save(dirpath=self.project_dir) self.write_gconfig() self.load_project(fullfilename) self.settings_dirty.set(0) def save_proj(self): self.project.save(dirpath=self.project_dir) self.write_gconfig() self.project_setdirty(dirty=False) ####################### MLN FUNCTIONS ##################################### def import_mln(self, name, content): self.project.add_mln(name, content) def delete_mln(self, fname): if fname in self.project.mlns: self.project.rm_mln(fname) fnamestr = fname.strip('*') if fnamestr in self.project.mlns: self.project.rm_mln(fnamestr) def update_mln(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.mln_container.selected_file.get() if new is None: new = self.mln_container.selected_file.get().strip('*') if content is None: content = self.mln_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.mlns[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.mlns[old] = content else: if new in self.project.mlns: if askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.mlns[new] = content else: logger.error('no name specified!') return -1 else: self.project.mlns[new] = content return 1 def mlnfiles(self): return list(self.project.mlns.keys()) def mlnfilecontent(self, filename): return self.project.mlns.get(filename, '').strip() # /MLN FUNCTIONS ##################################### ####################### EMLN FUNCTIONS ##################################### def import_emln(self, name, content): self.project.add_emln(name, content) def delete_emln(self, fname): if fname in self.project.emlns: self.project.rm_emln(fname) fnamestr = fname.strip('*') if fnamestr in self.project.emlns: self.project.rm_emln(fnamestr) def update_emln(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.emln_container.selected_file.get() if new is None: new = self.emln_container.selected_file.get().strip('*') if content is None: content = self.emln_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.emlns[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.emlns[old] = content else: if new in self.project.emlns: if askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.emlns[new] = content else: logger.error('no name specified!') return -1 else: self.project.emlns[new] = content return 1 def emlnfiles(self): return list(self.project.emlns.keys()) def emlnfilecontent(self, filename): return self.project.emlns.get(filename, '').strip() # /EMLN FUNCTIONS ##################################### # DB FUNCTIONS ##################################### def import_db(self, name, content): self.project.add_db(name, content) def delete_db(self, fname): if fname in self.project.dbs: self.project.rm_db(fname) fnamestr = fname.strip('*') if fnamestr in self.project.dbs: self.project.rm_db(fnamestr) def update_db(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.db_container.selected_file.get() if new is None: new = self.db_container.selected_file.get().strip('*') if content is None: content = self.db_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.dbs[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.dbs[old] = content else: if new in self.project.dbs: if askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.dbs[new] = content else: logger.error('no name specified!') return -1 else: self.project.dbs[new] = content return 1 def dbfiles(self): return list(self.project.dbs.keys()) def dbfilecontent(self, filename): return self.project.dbs.get(filename, '').strip() # /DB FUNCTIONS ##################################### # GENERAL FUNCTIONS ################################# def select_method(self, *args): self.set_outputfilename() self.settings_setdirty() def onchange_use_emln(self, dirty=True, *args): if not self.use_emln.get(): self.emln_label.grid_forget() self.emln_container.grid_forget() else: self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky="NE") self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NWES") if dirty: self.settings_setdirty() def onchange_cw(self, *args): if self.closed_world.get(): self.entry_cw.configure(state=DISABLED) else: self.entry_cw.configure(state=NORMAL) self.settings_setdirty() def reset_gui(self): self.set_config({}) self.db_container.clear() self.emln_container.clear() self.mln_container.clear() def set_config(self, newconf): self.config = newconf self.selected_grammar.set(ifnone(newconf.get('grammar'), 'PRACGrammar')) self.selected_logic.set(ifnone(newconf.get('logic'), 'FirstOrderLogic')) self.mln_container.selected_file.set(ifnone(newconf.get('mln'), '')) if self.use_emln.get(): self.emln_container.selected_file.set( ifnone(newconf.get('mln'), '')) self.db_container.selected_file.set(ifnone(newconf.get('db'), "")) self.selected_method.set( ifnone(newconf.get("method"), InferenceMethods.name('MCSAT'), transform=InferenceMethods.name)) self.multicore.set(ifnone(newconf.get('multicore'), 0)) self.profile.set(ifnone(newconf.get('profile'), 0)) self.params.set(ifnone(newconf.get('params'), '')) self.use_emln.set(ifnone(newconf.get('use_emln'), 0)) self.verbose.set(ifnone(newconf.get('verbose'), 1)) self.ignore_unknown_preds.set( ifnone(newconf.get('ignore_unknown_preds'), 0)) self.output_filename.set(ifnone(newconf.get('output_filename'), '')) self.cwPreds.set(ifnone(newconf.get('cw_preds'), '')) self.closed_world.set(ifnone(newconf.get('cw'), 0)) self.save.set(ifnone(newconf.get('save'), 0)) self.query.set(ifnone(newconf.get('queries'), '')) self.onchange_cw() def set_outputfilename(self): if not hasattr(self, "output_filename") or not hasattr( self, "db_filename") or not hasattr(self, "mln_filename"): return mln = self.mln_container.selected_file.get() db = self.db_container.selected_file.get() if "" in (mln, db): return if self.selected_method.get(): method = InferenceMethods.clazz(self.selected_method.get()) methodid = InferenceMethods.id(method) filename = config.query_output_filename(mln, methodid, db) self.output_filename.set(filename) def update_config(self): self.config = PRACMLNConfig() self.config["use_emln"] = self.use_emln.get() self.config['mln'] = self.mln_container.selected_file.get().strip( ).lstrip('*') self.config['emln'] = self.emln_container.selected_file.get().strip( ).lstrip('*') self.config["db"] = self.db_container.selected_file.get().strip( ).lstrip('*') self.config["method"] = InferenceMethods.id( self.selected_method.get().strip()) self.config["params"] = self.params.get().strip() self.config["queries"] = self.query.get() self.config["output_filename"] = self.output_filename.get().strip() self.config["cw"] = self.closed_world.get() self.config["cw_preds"] = self.cwPreds.get() self.config['profile'] = self.profile.get() self.config['logic'] = self.selected_logic.get() self.config['grammar'] = self.selected_grammar.get() self.config['multicore'] = self.multicore.get() self.config['save'] = self.save.get() self.config['ignore_unknown_preds'] = self.ignore_unknown_preds.get() self.config['verbose'] = self.verbose.get() self.config['window_loc'] = self.master.winfo_geometry() self.config['dir'] = self.dir self.project.queryconf = PRACMLNConfig() self.project.queryconf.update(self.config.config.copy()) def write_gconfig(self, savegeometry=True): self.gconf['prev_query_path'] = self.dir self.gconf['prev_query_project':self.dir] = self.project.name # save geometry if savegeometry: self.gconf['window_loc_query'] = self.master.geometry() self.gconf.dump() def infer(self, savegeometry=True, options={}, *args): mln_content = self.mln_container.editor.get("1.0", END).strip() db_content = self.db_container.editor.get("1.0", END).strip() # create conf from current gui settings self.update_config() # write gui settings self.write_gconfig(savegeometry=savegeometry) # hide gui self.master.withdraw() try: print((headline('PRACMLN QUERY TOOL'))) print() if options.get('mlnarg') is not None: mlnobj = MLN(mlnfile=os.path.abspath(options.get('mlnarg')), logic=self.config.get('logic', 'FirstOrderLogic'), grammar=self.config.get('grammar', 'PRACGrammar')) else: mlnobj = parse_mln( mln_content, searchpaths=[self.dir], projectpath=os.path.join(self.dir, self.project.name), logic=self.config.get('logic', 'FirstOrderLogic'), grammar=self.config.get('grammar', 'PRACGrammar')) if options.get('emlnarg') is not None: emln_content = mlnpath(options.get('emlnarg')).content else: emln_content = self.emln_container.editor.get("1.0", END).strip() if options.get('dbarg') is not None: dbobj = Database.load(mlnobj, dbfiles=[options.get('dbarg')], ignore_unknown_preds=self.config.get( 'ignore_unknown_preds', True)) else: out(self.config.get('ignore_unknown_preds', True)) dbobj = parse_db(mlnobj, db_content, ignore_unknown_preds=self.config.get( 'ignore_unknown_preds', True)) if options.get('queryarg') is not None: self.config["queries"] = options.get('queryarg') infer = MLNQuery(config=self.config, mln=mlnobj, db=dbobj, emln=emln_content) result = infer.run() # write to file if run from commandline, otherwise save result to project results if options.get('outputfile') is not None: output = io.StringIO() result.write(output) with open(os.path.abspath(options.get('outputfile')), 'w') as f: f.write(output.getvalue()) logger.info('saved result to {}'.format( os.path.abspath(options.get('outputfile')))) elif self.save.get(): output = io.StringIO() result.write(output) fname = self.output_filename.get() self.project.add_result(fname, output.getvalue()) self.project.save(dirpath=self.dir) logger.info( 'saved result to file results/{} in project {}'.format( fname, self.project.name)) else: logger.debug( 'No output file given - results have not been saved.') except: traceback.print_exc() # restore main window sys.stdout.flush() self.master.deiconify()
def MakeWidgets(self): self.wwUi.title(TITLE) self.wwUi.rowconfigure(2, weight=3) # needed to fill out column self.wwUi.columnconfigure(0, weight=1) cwPicker = self.MakePicker() cwRecent = self.MakeRecent() # can't remember why self.GetPicker().update_idletasks() fwOptions = self.MakeButtonPanel() # next level of widgets fwPicker = Frame(cwPicker, borderwidth=0, relief='sunken', name='fwPicker') cwPicker.create_window((0, 0), window=fwPicker, anchor="nw") fwPicker.rowconfigure(0, weight=1) fwPicker.columnconfigure(0, weight=1) swPicker = Scrollbar(cwPicker, orient="vertical", command=cwPicker.yview) swPicker.grid(row=0, column=1, sticky="ns") cwPicker.configure(yscrollcommand=swPicker.set) swPicker.columnconfigure(0, weight=1) fwPicker.bind('<Configure>', self.ConstrainPickerScroll) fwRecent = Frame(cwRecent, borderwidth=1, relief='sunken', name='fwRecent') cwRecent.create_window((0, 0), window=fwRecent, anchor="nw") fwRecent.rowconfigure(0, weight=1) fwRecent.columnconfigure(0, weight=1) swRecent = Scrollbar(cwRecent, orient="horizontal", command=cwRecent.yview) swRecent.grid(row=1, column=0, sticky="ew") cwRecent.configure(yscrollcommand=swRecent.set) swRecent.columnconfigure(0, weight=1) fwRecent.bind('<Configure>', self.ConstrainRecentScroll) rwModeScale = Radiobutton(fwOptions, text='Scale', variable=self.rvMode, value=MODE_SCALE, height=1) rwModeFill = Radiobutton(fwOptions, text='Fill', variable=self.rvMode, value=MODE_FILL) rwModeMax = Radiobutton(fwOptions, text='Max', variable=self.rvMode, value=MODE_MAX) rwModeCentre = Radiobutton(fwOptions, text='Centre', variable=self.rvMode, value=MODE_CENTRE) rwModeTile = Radiobutton(fwOptions, text='Tile', variable=self.rvMode, value=MODE_TILE) rwModeScale.grid(row=0, column=0, sticky="news") rwModeFill.grid(row=0, column=1, sticky="news") rwModeMax.grid(row=0, column=2, sticky="news") rwModeCentre.grid(row=0, column=3, sticky="news") rwModeTile.grid(row=0, column=4, sticky="news") bwDoIt = Button(fwOptions, text="Set Background", command=self.SetBg) bwDoIt.grid(row=1, column=1) bwQuit = Button(fwOptions, text="Close", command=self.Close) bwQuit.grid(row=1, column=2) bwI3Config = Button(fwOptions, text="Add to i3", command=WriteI3) bwI3Config.grid(row=1, column=3) self.UpdatePicker() self.UpdateRecent() # TO DO: expand the scrollwheel binding to all widgets # not just the scrollbars. self.wwUi.bind_all('<MouseWheel>', self.ScrollVertically) self.wwUi.bind_all('<Shift-MouseWheel>', self.ScrollHorizontally) # TO DO: make resize-redraw work without crashing #self.wwUi.bind('<Configure>', ResizeWindow) self.wwUi.mainloop()
class MLNQueryGUI(object): def __init__(self, master, gconf, directory=None): self.master = master self.initialized = False self.master.bind('<Return>', self.infer) self.master.bind('<Escape>', lambda a: self.master.quit()) self.master.protocol('WM_DELETE_WINDOW', self.quit) self.dir = os.path.abspath(ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) self.frame = Frame(master) self.frame.pack(fill=BOTH, expand=1) self.frame.columnconfigure(1, weight=1) row = 0 # pracmln project options Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0, sticky='ES') project_container = Frame(self.frame) project_container.grid(row=row, column=1, sticky="NEWS") # new proj file self.btn_newproj = Button(project_container, text='New Project...', command=self.new_project) self.btn_newproj.grid(row=0, column=1, sticky="WS") # open proj file self.btn_openproj = Button(project_container, text='Open Project...', command=self.ask_load_project) self.btn_openproj.grid(row=0, column=2, sticky="WS") # save proj file self.btn_updateproj = Button(project_container, text='Save Project...', command=self.noask_save_project) self.btn_updateproj.grid(row=0, column=3, sticky="WS") # save proj file as... self.btn_saveproj = Button(project_container, text='Save Project as...', command=self.ask_save_project) self.btn_saveproj.grid(row=0, column=4, sticky="WS") # grammar selection row += 1 Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E') grammars = ['StandardGrammar', 'PRACGrammar'] self.selected_grammar = StringVar() self.selected_grammar.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_grammar) + tuple(grammars)) l.grid(row=row, column=1, sticky='NWE') # logic selection row += 1 Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E') logics = ['FirstOrderLogic', 'FuzzyLogic'] self.selected_logic = StringVar() self.selected_logic.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics)) l.grid(row=row, column=1, sticky='NWE') # mln section row += 1 Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE') self.mln_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.mln', 'ftypes': [('MLN files', '.mln')]}, defaultname='*unknown{}', importhook=self.import_mln, deletehook=self.delete_mln, projecthook=self.save_proj, filecontenthook=self.mlnfilecontent, fileslisthook=self.mlnfiles, updatehook=self.update_mln, onchangehook=self.project_setdirty) self.mln_container.editor.bind("<FocusIn>", self._got_focus) self.mln_container.grid(row=row, column=1, sticky="NEWS") self.mln_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) row += 1 self.use_emln = IntVar() self.use_emln.set(0) self.cb_use_emln = Checkbutton(self.frame, text="use model extension", variable=self.use_emln, command=self.onchange_use_emln) self.cb_use_emln.grid(row=row, column=1, sticky="W") # mln extension section row += 1 self.emlncontainerrow = row self.emln_label = Label(self.frame, text="EMLN: ") self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE') self.emln_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.emln', 'ftypes': [('MLN extension files','.emln')]}, defaultname='*unknown{}', importhook=self.import_emln, deletehook=self.delete_emln, projecthook=self.save_proj, filecontenthook=self.emlnfilecontent, fileslisthook=self.emlnfiles, updatehook=self.update_emln, onchangehook=self.project_setdirty) self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NEWS") self.emln_container.editor.bind("<FocusIn>", self._got_focus) self.emln_container.columnconfigure(1, weight=2) self.onchange_use_emln(dirty=False) self.frame.rowconfigure(row, weight=1) # db section row += 1 Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE') self.db_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.db', 'ftypes': [('Database files', '.db')]}, defaultname='*unknown{}', importhook=self.import_db, deletehook=self.delete_db, projecthook=self.save_proj, filecontenthook=self.dbfilecontent, fileslisthook=self.dbfiles, updatehook=self.update_db, onchangehook=self.project_setdirty) self.db_container.grid(row=row, column=1, sticky="NEWS") self.db_container.editor.bind("<FocusIn>", self._got_focus) self.db_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) # inference method selection row += 1 self.list_methods_row = row Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E) self.selected_method = StringVar() self.selected_method.trace('w', self.select_method) methodnames = sorted(InferenceMethods.names()) self.list_methods = OptionMenu(*(self.frame, self.selected_method) + tuple(methodnames)) self.list_methods.grid(row=self.list_methods_row, column=1, sticky="NWE") # options row += 1 option_container = Frame(self.frame) option_container.grid(row=row, column=1, sticky="NEWS") # Multiprocessing self.multicore = IntVar() self.cb_multicore = Checkbutton(option_container, text="Use all CPUs", variable=self.multicore, command=self.settings_setdirty) self.cb_multicore.grid(row=0, column=2, sticky=W) # profiling self.profile = IntVar() self.cb_profile = Checkbutton(option_container, text='Use Profiler', variable=self.profile, command=self.settings_setdirty) self.cb_profile.grid(row=0, column=3, sticky=W) # verbose self.verbose = IntVar() self.cb_verbose = Checkbutton(option_container, text='verbose', variable=self.verbose, command=self.settings_setdirty) self.cb_verbose.grid(row=0, column=4, sticky=W) # options self.ignore_unknown_preds = IntVar() self.cb_ignore_unknown_preds = Checkbutton(option_container, text='ignore unkown predicates', variable=self.ignore_unknown_preds, command=self.settings_setdirty) self.cb_ignore_unknown_preds.grid(row=0, column=5, sticky="W") # queries row += 1 Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E) self.query = StringVar() self.query.trace('w', self.settings_setdirty) Entry(self.frame, textvariable=self.query).grid(row=row, column=1, sticky="NEW") # additional parameters row += 1 Label(self.frame, text="Add. params: ").grid(row=row, column=0, sticky="NE") self.params = StringVar() self.params.trace('w', self.settings_setdirty) self.entry_params = Entry(self.frame, textvariable=self.params) self.entry_params.grid(row=row, column=1, sticky="NEW") # closed-world predicates row += 1 Label(self.frame, text="CW preds: ").grid(row=row, column=0, sticky="E") cw_container = Frame(self.frame) cw_container.grid(row=row, column=1, sticky='NEWS') cw_container.columnconfigure(0, weight=1) self.cwPreds = StringVar() self.cwPreds.trace('w', self.settings_setdirty) self.entry_cw = Entry(cw_container, textvariable=self.cwPreds) self.entry_cw.grid(row=0, column=0, sticky="NEWS") self.closed_world = IntVar() self.cb_closed_world = Checkbutton(cw_container, text="CW Assumption", variable=self.closed_world, command=self.onchange_cw) self.cb_closed_world.grid(row=0, column=1, sticky='W') # output filename row += 1 output_cont = Frame(self.frame) output_cont.grid(row=row, column=1, sticky='NEWS') output_cont.columnconfigure(0, weight=1) # - filename Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="NE") self.output_filename = StringVar() self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename) self.entry_output_filename.grid(row=0, column=0, sticky="NEW") # - save option self.save = IntVar() self.cb_save = Checkbutton(output_cont, text="save", variable=self.save) self.cb_save.grid(row=0, column=1, sticky=W) # start button row += 1 start_button = Button(self.frame, text=">> Start Inference <<", command=self.infer) start_button.grid(row=row, column=1, sticky="NEW") self.settings_dirty = IntVar() self.project_dirty = IntVar() self.gconf = gconf self.project = None self.project_dir = os.path.abspath(ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) if gconf['prev_query_project': self.project_dir] is not None: self.load_project(os.path.join(self.project_dir, gconf['prev_query_project':self.project_dir])) else: self.new_project() self.config = self.project.queryconf self.project.addlistener(self.project_setdirty) self.mln_container.dirty = False self.emln_container.dirty = False self.db_container.dirty = False self.project_setdirty(dirty=False) self.master.geometry(gconf['window_loc_query']) self.initialized = True def _got_focus(self, *_): if self.master.focus_get() == self.mln_container.editor: if not self.project.mlns and not self.mln_container.file_buffer: self.mln_container.new_file() elif self.master.focus_get() == self.db_container.editor: if not self.project.dbs and not self.db_container.file_buffer: self.db_container.new_file() elif self.master.focus_get() == self.emln_container.editor: if not self.project.emlns and not self.emln_container.file_buffer: self.emln_container.new_file() def quit(self): if self.settings_dirty.get() or self.project_dirty.get(): savechanges = messagebox.askyesnocancel("Save changes", "You have unsaved project changes. Do you want to save them before quitting?") if savechanges is None: return elif savechanges: self.noask_save_project() self.master.destroy() else: # write gui settings and destroy self.write_gconfig() self.master.destroy() ####################### PROJECT FUNCTIONS ################################# def new_project(self): self.project = MLNProject() self.project.addlistener(self.project_setdirty) self.project.name = DEFAULTNAME.format('.pracmln') self.reset_gui() self.set_config(self.project.queryconf) self.mln_container.update_file_choices() self.emln_container.update_file_choices() self.db_container.update_file_choices() self.project_setdirty(dirty=True) def project_setdirty(self, dirty=False, *args): self.project_dirty.set(dirty or self.mln_container.dirty or self.db_container.dirty or self.emln_container.dirty) self.changewindowtitle() def settings_setdirty(self, *args): self.settings_dirty.set(1) self.changewindowtitle() def changewindowtitle(self): title = (WINDOWTITLEEDITED if (self.settings_dirty.get() or self.project_dirty.get()) else WINDOWTITLE).format(self.project_dir, self.project.name) self.master.title(title) def ask_load_project(self): filename = askopenfilename(initialdir=self.dir, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln") if filename and os.path.exists(filename): self.load_project(filename) else: logger.info('No file selected.') return def load_project(self, filename): if filename and os.path.exists(filename): projdir, _ = ntpath.split(filename) self.dir = os.path.abspath(projdir) self.project_dir = os.path.abspath(projdir) self.project = MLNProject.open(filename) self.project.addlistener(self.project_setdirty) self.reset_gui() self.set_config(self.project.queryconf.config) self.mln_container.update_file_choices() self.db_container.update_file_choices() if len(self.project.mlns) > 0: self.mln_container.selected_file.set(self.project.queryconf['mln'] or list(self.project.mlns.keys())[0]) self.mln_container.dirty = False if len(self.project.emlns) > 0: self.emln_container.selected_file.set(self.project.queryconf['emln'] or list(self.project.emlns.keys())[0]) self.emln_container.dirty = False if len(self.project.dbs) > 0: self.db_container.selected_file.set(self.project.queryconf['db'] or list(self.project.dbs.keys())[0]) self.db_container.dirty = False self.write_gconfig(savegeometry=False) self.settings_dirty.set(0) self.project_setdirty(dirty=False) self.changewindowtitle() else: logger.error('File {} does not exist. Creating new project...'.format(filename)) self.new_project() def noask_save_project(self): if self.project.name and not self.project.name == DEFAULTNAME.format('.pracmln'): self.save_project(os.path.join(self.project_dir, self.project.name)) else: self.ask_save_project() def ask_save_project(self): fullfilename = asksaveasfilename(initialdir=self.project_dir, confirmoverwrite=True, filetypes=[('PRACMLN project files','.pracmln')], defaultextension=".pracmln") self.save_project(fullfilename) def save_project(self, fullfilename): if fullfilename: fpath, fname = ntpath.split(fullfilename) fname = fname.split('.')[0] self.project.name = fname self.dir = os.path.abspath(fpath) self.project_dir = os.path.abspath(fpath) self.mln_container.save_all_files() self.emln_container.save_all_files() self.db_container.save_all_files() self.update_config() self.project.save(dirpath=self.project_dir) self.write_gconfig() self.load_project(fullfilename) self.settings_dirty.set(0) def save_proj(self): self.project.save(dirpath=self.project_dir) self.write_gconfig() self.project_setdirty(dirty=False) ####################### MLN FUNCTIONS ##################################### def import_mln(self, name, content): self.project.add_mln(name, content) def delete_mln(self, fname): if fname in self.project.mlns: self.project.rm_mln(fname) fnamestr = fname.strip('*') if fnamestr in self.project.mlns: self.project.rm_mln(fnamestr) def update_mln(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.mln_container.selected_file.get() if new is None: new = self.mln_container.selected_file.get().strip('*') if content is None: content = self.mln_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.mlns[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.mlns[old] = content else: if new in self.project.mlns: if askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.mlns[new] = content else: logger.error('no name specified!') return -1 else: self.project.mlns[new] = content return 1 def mlnfiles(self): return list(self.project.mlns.keys()) def mlnfilecontent(self, filename): return self.project.mlns.get(filename, '').strip() # /MLN FUNCTIONS ##################################### ####################### EMLN FUNCTIONS ##################################### def import_emln(self, name, content): self.project.add_emln(name, content) def delete_emln(self, fname): if fname in self.project.emlns: self.project.rm_emln(fname) fnamestr = fname.strip('*') if fnamestr in self.project.emlns: self.project.rm_emln(fnamestr) def update_emln(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.emln_container.selected_file.get() if new is None: new = self.emln_container.selected_file.get().strip('*') if content is None: content = self.emln_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.emlns[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.emlns[old] = content else: if new in self.project.emlns: if askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.emlns[new] = content else: logger.error('no name specified!') return -1 else: self.project.emlns[new] = content return 1 def emlnfiles(self): return list(self.project.emlns.keys()) def emlnfilecontent(self, filename): return self.project.emlns.get(filename, '').strip() # /EMLN FUNCTIONS ##################################### # DB FUNCTIONS ##################################### def import_db(self, name, content): self.project.add_db(name, content) def delete_db(self, fname): if fname in self.project.dbs: self.project.rm_db(fname) fnamestr = fname.strip('*') if fnamestr in self.project.dbs: self.project.rm_db(fnamestr) def update_db(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.db_container.selected_file.get() if new is None: new = self.db_container.selected_file.get().strip('*') if content is None: content = self.db_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.dbs[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.dbs[old] = content else: if new in self.project.dbs: if askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.dbs[new] = content else: logger.error('no name specified!') return -1 else: self.project.dbs[new] = content return 1 def dbfiles(self): return list(self.project.dbs.keys()) def dbfilecontent(self, filename): return self.project.dbs.get(filename, '').strip() # /DB FUNCTIONS ##################################### # GENERAL FUNCTIONS ################################# def select_method(self, *args): self.set_outputfilename() self.settings_setdirty() def onchange_use_emln(self, dirty=True, *args): if not self.use_emln.get(): self.emln_label.grid_forget() self.emln_container.grid_forget() else: self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky="NE") self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NWES") if dirty: self.settings_setdirty() def onchange_cw(self, *args): if self.closed_world.get(): self.entry_cw.configure(state=DISABLED) else: self.entry_cw.configure(state=NORMAL) self.settings_setdirty() def reset_gui(self): self.set_config({}) self.db_container.clear() self.emln_container.clear() self.mln_container.clear() def set_config(self, newconf): self.config = newconf self.selected_grammar.set(ifnone(newconf.get('grammar'), 'PRACGrammar')) self.selected_logic.set(ifnone(newconf.get('logic'), 'FirstOrderLogic')) self.mln_container.selected_file.set(ifnone(newconf.get('mln'), '')) if self.use_emln.get(): self.emln_container.selected_file.set(ifnone(newconf.get('mln'), '')) self.db_container.selected_file.set(ifnone(newconf.get('db'), "")) self.selected_method.set(ifnone(newconf.get("method"), InferenceMethods.name('MCSAT'), transform=InferenceMethods.name)) self.multicore.set(ifnone(newconf.get('multicore'), 0)) self.profile.set(ifnone(newconf.get('profile'), 0)) self.params.set(ifnone(newconf.get('params'), '')) self.use_emln.set(ifnone(newconf.get('use_emln'), 0)) self.verbose.set(ifnone(newconf.get('verbose'), 1)) self.ignore_unknown_preds.set(ifnone(newconf.get('ignore_unknown_preds'), 0)) self.output_filename.set(ifnone(newconf.get('output_filename'), '')) self.cwPreds.set(ifnone(newconf.get('cw_preds'), '')) self.closed_world.set(ifnone(newconf.get('cw'), 0)) self.save.set(ifnone(newconf.get('save'), 0)) self.query.set(ifnone(newconf.get('queries'), '')) self.onchange_cw() def set_outputfilename(self): if not hasattr(self, "output_filename") or not hasattr(self, "db_filename") or not hasattr(self, "mln_filename"): return mln = self.mln_container.selected_file.get() db = self.db_container.selected_file.get() if "" in (mln, db): return if self.selected_method.get(): method = InferenceMethods.clazz(self.selected_method.get()) methodid = InferenceMethods.id(method) filename = config.query_output_filename(mln, methodid, db) self.output_filename.set(filename) def update_config(self): self.config = PRACMLNConfig() self.config["use_emln"] = self.use_emln.get() self.config['mln'] = self.mln_container.selected_file.get().strip().lstrip('*') self.config['emln'] = self.emln_container.selected_file.get().strip().lstrip('*') self.config["db"] = self.db_container.selected_file.get().strip().lstrip('*') self.config["method"] = InferenceMethods.id(self.selected_method.get().strip()) self.config["params"] = self.params.get().strip() self.config["queries"] = self.query.get() self.config["output_filename"] = self.output_filename.get().strip() self.config["cw"] = self.closed_world.get() self.config["cw_preds"] = self.cwPreds.get() self.config['profile'] = self.profile.get() self.config['logic'] = self.selected_logic.get() self.config['grammar'] = self.selected_grammar.get() self.config['multicore'] = self.multicore.get() self.config['save'] = self.save.get() self.config['ignore_unknown_preds'] = self.ignore_unknown_preds.get() self.config['verbose'] = self.verbose.get() self.config['window_loc'] = self.master.winfo_geometry() self.config['dir'] = self.dir self.project.queryconf = PRACMLNConfig() self.project.queryconf.update(self.config.config.copy()) def write_gconfig(self, savegeometry=True): self.gconf['prev_query_path'] = self.dir self.gconf['prev_query_project': self.dir] = self.project.name # save geometry if savegeometry: self.gconf['window_loc_query'] = self.master.geometry() self.gconf.dump() def infer(self, savegeometry=True, options={}, *args): mln_content = self.mln_container.editor.get("1.0", END).strip() db_content = self.db_container.editor.get("1.0", END).strip() # create conf from current gui settings self.update_config() # write gui settings self.write_gconfig(savegeometry=savegeometry) # hide gui self.master.withdraw() try: print((headline('PRACMLN QUERY TOOL'))) print() if options.get('mlnarg') is not None: mlnobj = MLN(mlnfile=os.path.abspath(options.get('mlnarg')), logic=self.config.get('logic', 'FirstOrderLogic'), grammar=self.config.get('grammar', 'PRACGrammar')) else: mlnobj = parse_mln(mln_content, searchpaths=[self.dir], projectpath=os.path.join(self.dir, self.project.name), logic=self.config.get('logic', 'FirstOrderLogic'), grammar=self.config.get('grammar', 'PRACGrammar')) if options.get('emlnarg') is not None: emln_content = mlnpath(options.get('emlnarg')).content else: emln_content = self.emln_container.editor.get("1.0", END).strip() if options.get('dbarg') is not None: dbobj = Database.load(mlnobj, dbfiles=[options.get('dbarg')], ignore_unknown_preds=self.config.get('ignore_unknown_preds', True)) else: out(self.config.get('ignore_unknown_preds', True)) dbobj = parse_db(mlnobj, db_content, ignore_unknown_preds=self.config.get('ignore_unknown_preds', True)) if options.get('queryarg') is not None: self.config["queries"] = options.get('queryarg') infer = MLNQuery(config=self.config, mln=mlnobj, db=dbobj, emln=emln_content) result = infer.run() # write to file if run from commandline, otherwise save result to project results if options.get('outputfile') is not None: output = io.StringIO() result.write(output) with open(os.path.abspath(options.get('outputfile')), 'w') as f: f.write(output.getvalue()) logger.info('saved result to {}'.format(os.path.abspath(options.get('outputfile')))) elif self.save.get(): output = io.StringIO() result.write(output) fname = self.output_filename.get() self.project.add_result(fname, output.getvalue()) self.project.save(dirpath=self.dir) logger.info('saved result to file results/{} in project {}'.format(fname, self.project.name)) else: logger.debug('No output file given - results have not been saved.') except: traceback.print_exc() # restore main window sys.stdout.flush() self.master.deiconify()
def BuildMainFrame(self): from tkinter import Menu, IntVar, StringVar, Toplevel, Listbox, Frame, PanedWindow, Text, Scrollbar, Entry from tkinter import X, N, S, W, E, VERTICAL, TOP, END, DISABLED, RAISED menu = Menu(self.master, activeborderwidth=0, bd=0) self.master.config(menu=menu) filemenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="File", underline=0, menu=filemenu) filemenu.add_command(label="New", accelerator='Ctrl+N', command=self.NewCommand) filemenu.add_command(label="Open...", accelerator='Ctrl+O', command=self.OpenCommand) filemenu.add_command(label="Save as...", accelerator='Ctrl+S', command=self.SaveCommand) filemenu.add_separator() filemenu.add_command(label="Quit", accelerator='Ctrl+Q', command=self.QuitCommand) self.log_on = IntVar() self.log_on.set(1) self.output_to_file = StringVar() self.output_to_file.set('n') scriptmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) modulenames = ['vmtkscripts'] for modulename in modulenames: scriptsubmenu = self.BuildScriptMenu(menu, modulename) if scriptsubmenu: scriptmenu.add_cascade(label=modulename, menu=scriptsubmenu) editmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Edit", underline=0, menu=editmenu) editmenu.add_cascade(label="Insert script", menu=scriptmenu) editmenu.add_command(label="Insert file name", accelerator='Ctrl+F', command=self.InsertFileName) editmenu.add_separator() editmenu.add_command(label="Clear input", command=self.ClearInputCommand) editmenu.add_command(label="Clear output", command=self.ClearOutputCommand) editmenu.add_command(label="Clear all", command=self.ClearAllCommand) editmenu.add_separator() editmenu.add_checkbutton(label="Log", variable=self.log_on) editmenu.add_separator() editmenu.add_radiobutton(label="No output to file", variable=self.output_to_file, value='n') editmenu.add_radiobutton(label="Write output to file", variable=self.output_to_file, value='w') editmenu.add_radiobutton(label="Append output to file", variable=self.output_to_file, value='a') editmenu.add_command(label="Output file...", command=self.OutputFileCommand) runmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Run", underline=0, menu=runmenu) runmenu.add_command(label="Run all", command=self.RunAllCommand) runmenu.add_command(label="Run current line", command=self.RunLineCommand) runmenu.add_command(label="Run selection", command=self.RunSelectionCommand) helpmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Help", underline=0, menu=helpmenu) helpmenu.add_command(label="Help", underline=0, accelerator='F1', command=self.ShowHelpCommand) helpmenu.add_command(label="About", underline=0, command=self.AboutCommand) self.master.bind("<Control-KeyPress-q>", self.QuitHandler) self.master.bind("<Control-KeyPress-n>", self.NewHandler) self.master.bind("<Control-KeyPress-o>", self.OpenHandler) self.master.bind("<Control-KeyPress-s>", self.SaveHandler) self.master.bind("<Control-KeyPress-f>", self.InsertFileNameHandler) self.master.bind("<KeyPress-F1>", self.ShowHelpHandler) self.master.bind("<KeyPress>", self.KeyPressHandler) self.wordIndex = ['1.0', '1.0'] self.suggestionswindow = Toplevel(bg='#ffffff', bd=0, height=50, width=600, highlightthickness=0, takefocus=True) self.suggestionswindow.overrideredirect(1) self.suggestionslist = Listbox(self.suggestionswindow, bg='#ffffff', bd=1, fg='#336699', activestyle='none', highlightthickness=0, height=9) self.suggestionslist.insert(END, "foo") self.suggestionslist.pack(side=TOP, fill=X) self.suggestionswindow.bind("<KeyPress>", self.TopKeyPressHandler) self.suggestionswindow.withdraw() self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=1) content = Frame(self.master, bd=0, padx=2, pady=2) content.grid(row=0, column=0, sticky=N + S + W + E) content.rowconfigure(0, weight=1, minsize=50) content.rowconfigure(1, weight=0) content.columnconfigure(0, weight=1) panes = PanedWindow(content, orient=VERTICAL, bd=1, sashwidth=8, sashpad=0, sashrelief=RAISED, showhandle=True) panes.grid(row=0, column=0, sticky=N + S + W + E) frame1 = Frame(panes, bd=0) frame1.grid(row=0, column=0, sticky=N + S + W + E) frame1.columnconfigure(0, weight=1) frame1.columnconfigure(1, weight=0) frame1.rowconfigure(0, weight=1) panes.add(frame1, height=300, minsize=20) frame2 = Frame(panes, bd=0) frame2.grid(row=1, column=0, sticky=N + S + W + E) frame2.columnconfigure(0, weight=1) frame2.columnconfigure(1, weight=0) frame2.rowconfigure(0, weight=1) panes.add(frame2, minsize=20) self.text_input = Text(frame1, bg='#ffffff', bd=1, highlightthickness=0) self.text_input.bind("<KeyPress>", self.KeyPressHandler) self.text_input.bind("<Button-3>", self.PopupHandler) self.text_input.bind("<Control-Return>", self.RunKeyboardHandler) self.input_scrollbar = Scrollbar(frame1, orient=VERTICAL, command=self.text_input.yview) self.text_input["yscrollcommand"] = self.input_scrollbar.set self.text_output = Text(frame2, state=DISABLED, bd=1, bg='#ffffff', highlightthickness=0) self.output_scrollbar = Scrollbar(frame2, orient=VERTICAL, command=self.text_output.yview) self.text_output["yscrollcommand"] = self.output_scrollbar.set self.text_entry = Entry(content, bd=1, bg='#ffffff', state=DISABLED, highlightthickness=0) self.text_input.focus_set() self.text_input.grid(row=0, column=0, sticky=N + S + W + E) self.input_scrollbar.grid(row=0, column=1, sticky=N + S + W + E) self.text_output.grid(row=0, column=0, sticky=N + S + W + E) self.output_scrollbar.grid(row=0, column=1, sticky=N + S + W + E) self.text_entry.grid(row=1, column=0, sticky=N + S + W + E) self.popupmenu = Menu(self.text_input, tearoff=1, bd=0) self.popupmenu.add_command(label="Context help", command=self.ShowHelpCommand) self.popupmenu.add_cascade(label="Insert script", menu=scriptmenu) self.popupmenu.add_command(label="Insert file name...", command=self.InsertFileName) self.popupmenu.add_separator() self.popupmenu.add_command(label="Run all", command=self.RunAllCommand) self.popupmenu.add_command(label="Run current line", command=self.RunLineCommand) self.popupmenu.add_command(label="Run selection", command=self.RunSelectionCommand) self.output_stream = TkPadOutputStream(self.text_output) self.input_stream = TkPadInputStream(self.text_entry, self.output_stream)
class CadrePatrouilleur(Frame): def __init__(self, colonne, cadre_parent, poste, agent, couleur1, couleur2, grosseurs, heure_debut): largeur = grosseurs["Largeur cadre"] hauteur = grosseurs["Hauteur cadre"] police = grosseurs["Police"] #Création objets self.cadre = Frame(cadre_parent, height=hauteur, width=largeur, bd=3, relief='ridge', bg=couleur1) self.cadre_position = Frame(self.cadre, bd=3, relief="ridge", bg=couleur2, width=largeur - 10, height=0.12 * hauteur) self.cadre_logs = Frame(self.cadre, bd=1, relief='ridge', bg=couleur2, width=largeur - 10, height=grosseurs["Hauteur cadre logs"]) self.labels_logs_precedents = [] self.label_nom = Label(self.cadre, text=agent.afficher_avec_titre(), bg=couleur1, font=("Arial", police, "bold")) self.label_poste = Label(self.cadre, text=poste, bg=couleur1, font=("Arial", police + 6, "bold")) self.position_actuelle = Label(self.cadre_position) self.heure_position = Entry(self.cadre_position) #Configuration objets col = 0 while col < 5: self.cadre_position.columnconfigure(col, weight=1) col += 2 ligne = 0 while ligne < 3: self.cadre_position.rowconfigure(ligne, weight=1) ligne += 2 self.cadre_logs.columnconfigure(0, weight=1) self.cadre_logs.columnconfigure(2, weight=1) col = 0 while col < 7: self.cadre.columnconfigure(col, weight=1) col += 2 self.position_actuelle.config(text="Début de quart", bg=couleur2, font=("Arial", police - 2, "bold")) self.heure_position.config(bd=0, bg=couleur2, font=("Arial", police - 2, "bold"), width=6, justify=CENTER) self.heure_position.insert(END, heure_debut) #Grid objets self.cadre.grid(row=4, column=colonne, sticky=NSEW) self.label_poste.grid(row=0, column=0, padx=5, pady=5) self.label_nom.grid(row=1, column=0, padx=5, pady=5) self.cadre_logs.grid(row=4, column=0, padx=5) self.cadre_logs.grid_propagate(0) self.cadre_position.grid(row=3, column=0, padx=5) self.cadre_position.grid_propagate(0) self.position_actuelle.grid(row=1, column=1, padx=5, pady=5) self.heure_position.grid(row=1, column=3, padx=5, pady=5)
class CadreNouveauPatrouilleur(Frame): def __init__(self, colonne, cadre_parent, patrouilleur, commande, agents, couleur_defaut): #Création objets self.cadre = Frame(cadre_parent, bd=3, relief='ridge') self.couleurs_possibles = { "rouge": ["Indianred2", "IndianRed3"], "jaune": ["yellow2", "yellow3"], "bleu": ["DodgerBlue2", "DodgerBlue3"], "vert": ["chartreuse2", "chartreuse3"], "mauve": ["DarkOrchid2", "DarkOrchid"], "rose": ["maroon1", "maroon3"], "gris": ["light grey", "gray60"], "orange": ["DarkOrange2", "DarkOrange3"], "blanc": ["snow", "snow3"], "noir": ["gray37", "gray33"] } self.boutons_couleurs = { "rouge": None, "jaune": None, "bleu": None, "vert": None, "mauve": None, "rose": None, "gris": None, "orange": None, "blanc": None, "noir": None } self.cadre_pat = Frame(self.cadre) label_pat = Label(self.cadre_pat, text="Patrouilleur " + patrouilleur, font=("Arial", 13, "bold")) self.actif = IntVar() self.bouton = Checkbutton(self.cadre_pat, command=commande, variable=self.actif) self.entree_agent = Listbox(self.cadre, height=5, width=18, exportselection=0, yscrollcommand=1, font=("Arial", 13)) for item in sorted(agents, reverse=True): self.entree_agent.insert(0, item) self.cadre_couleurs = Frame(self.cadre) self.valeur_couleur = StringVar() self.valeur_couleur.set(couleur_defaut) for couleur in self.couleurs_possibles: self.boutons_couleurs[couleur] = Radiobutton( self.cadre_couleurs, bg=self.couleurs_possibles[couleur][0], selectcolor=self.couleurs_possibles[couleur][0], variable=self.valeur_couleur, value=couleur, bd=2, indicatoron=0, width=2) numero = 0 while numero < 19: self.cadre_couleurs.columnconfigure(0, weight=1) numero += 2 numero = 0 while numero < 5: self.cadre.columnconfigure(numero, weight=1) self.cadre.rowconfigure(numero, weight=1) numero += 2 self.cadre.rowconfigure(6, weight=1) self.cadre_pat.columnconfigure(0, weight=1) self.cadre_pat.columnconfigure(2, weight=1) self.cadre_pat.columnconfigure(4, weight=1) self.cadre_pat.rowconfigure(0, weight=1) self.cadre_pat.rowconfigure(2, weight=1) self.cadre.grid(row=1, column=colonne, sticky=W, padx=5, pady=5) self.cadre_couleurs.grid(columnspan=5, row=8, column=1) self.cadre_pat.grid(columnspan=5, row=0, column=1) label_pat.grid(row=1, column=1, sticky=W) self.bouton.grid(row=1, column=3, sticky=W, padx=5, pady=5) self.entree_agent.grid(row=5, column=3, padx=5, pady=5, sticky=W) colonne = 1 for couleur in self.boutons_couleurs: self.boutons_couleurs[couleur].grid(row=8, column=colonne, padx=2, pady=2) colonne += 2
class AppGUI: """ Creates the gui for the daylog """ def __init__(self): self.settings = Settings() self.bg = "#34495e" # Midnight Blue self.fg = "#FFFFFF" # White self.master = Tk() self.master.title("DayLog") self.master.configure(bg=self.bg) self.master.resizable(width=False, height=False) Label(self.master, text='Entry', bg=self.bg, fg=self.fg).grid(row=0) self.entry = Entry(self.master) self.entry.configure(bg=self.bg, fg=self.fg, highlightbackground=self.bg) self.entry.grid(row=0, column=1) self.entry.focus_set() self.entry.bind('<Return>', self.add) self.frame = Frame(self.master, bg=self.bg) self.frame.grid(row=1, column=0, columnspan=2, sticky='WE') self.frame.columnconfigure(0, weight=1) self.frame.columnconfigure(1, weight=1) self.frame.rowconfigure(0, weight=1) self.show_button = Button(self.frame, text="Show", command=self.show) self.show_button.configure(bg=self.bg, fg=self.bg, highlightbackground=self.bg, highlightcolor=self.bg) self.show_button.grid(row=0, column=0, sticky='WE') self.settings_button = Button(self.frame, text="Settings", command=None) self.settings_button.configure(bg=self.bg, fg=self.bg, highlightbackground=self.bg, highlightcolor=self.bg) self.settings_button.grid(row=0, column=1, sticky='WE') def get(self): """ Returns the text entry of the user """ return self.entry.get() def add(self, event): """ Adds user input to text file """ base = self.settings.getLocation() filename = strftime("%Y-%d-%m") + ".txt" filepath = path.join(base, filename) with open(filepath, 'a+') as fp: fp.write("[{}] {}\n".format(strftime("%H:%M:%S", localtime()), self.get())) self.update() def remove(self): """ Removes user input from text file """ pass def update(self): """ Updates window with a clean entry box """ self.entry.delete(0, 'end') def show(self): """ Prints the logs for the day """ x = self.master.winfo_x() y = self.master.winfo_y() w = self.master.winfo_width() h = self.master.winfo_height() root_h = self.master.winfo_height() frame_h = self.frame.winfo_height() toplevel = Toplevel() toplevel.title("Viewer") toplevel.configure(width=w, bg=self.bg) toplevel.resizable(width=False, height=False) base = self.settings.getLocation() filename = strftime("%Y-%d-%m") + ".txt" filepath = path.join(base, filename) # WIP --- if path.isfile(filepath): text = "" with open(filepath, 'r') as fp: for line in fp: text += line print(text) else: toplevel.geometry("%dx%d%+d%+d" % (w, h, x, y + root_h + frame_h + 2)) Label(toplevel, text="File does not exist.", bg=self.bg, fg=self.fg).grid() toplevel.focus_set() def start(self): """ Starts the GUI window """ self.master.mainloop()
def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self, parent) self.msg_top = 'Add task: ' self.msg_drop_down = 'priority: ' self.text = tk.Text(self, *args, **kwargs) self.text.configure(yscrollcommand=self.vsb.set) self.vsb.pack(side="right", fill="y") self.text.pack(side="left", fill="both", expand=True) self.tkvar = StringVar(self, parent).set('low') self.choices = {'low', 'medium', 'high'} self.opt_menu = OptionMenu(mainframe, self.tkvar, self.choices) self.opt_menu.grid(row=0, column=0) root = tk.Tk() mainframe = Frame(root) mainframe.grid(column=0,row=0, sticky='NWES') mainframe.columnconfigure(0, weight = 1) mainframe.rowconfigure(0, weight = 1) mainframe.pack(pady = 100, padx = 100) # tkvar = StringVar(root) # choices = {'low', 'medium', 'high'} # tkvar.set('low') # opt_menu = OptionMenu(mainframe, tkvar, *choices) opt_menu.grid(row=0, column=0) # Goal: reduce to AddBox(root) root.mainloop()
def show_items(self, items, upper=None): """ Creates a new page on the stack, automatically adds a back button when there are pages on the stack already :param items: list the items to display :param upper: list previous levels' ids :return: None """ if upper is None: upper = [] num = 0 # create a new frame wrap = Frame(self, bg="black") if len(self.framestack): # when there were previous frames, hide the top one and add a back button for the new one self.hide_top() back = FlatButton( wrap, text='back…', image=self.get_icon("arrow.left"), command=self.go_back, ) back.set_color("#00a300") # green back.grid(row=0, column=0, padx=1, pady=1, sticky=TkC.W + TkC.E + TkC.N + TkC.S) num += 1 # add the new frame to the stack and display it self.framestack.append(wrap) self.show_top() # calculate tile distribution allitems = len(items) + num rows = floor(sqrt(allitems)) cols = ceil(allitems / rows) # make cells autoscale for x in range(int(cols)): wrap.columnconfigure(x, weight=1) for y in range(int(rows)): wrap.rowconfigure(y, weight=1) # display all given buttons for item in items: act = upper + [item['name']] if 'icon' in item: image = self.get_icon(item['icon']) else: image = self.get_icon('scrabble.' + item['label'][0:1].lower()) btn = FlatButton( wrap, text=item['label'], # image=image ) if 'items' in item: # this is a deeper level btn.configure(command=lambda act=act, item=item: self.show_items(item['items'], act), text=item['label'] + '…') btn.set_color("#2b5797") # dark-blue else: # this is an action btn.configure(command=lambda act=act: self.go_action(act), ) if 'color' in item: btn.set_color(item['color']) # add buton to the grid btn.grid( row=int(floor(num / cols)), column=int(num % cols), padx=1, pady=1, sticky=TkC.W + TkC.E + TkC.N + TkC.S ) num += 1
class OthelloGUI: n = 1 def __init__(self): self._configure_game() self._init_game() self.refresh_board() def _configure_game(self) -> None: config = ConfigureGUI() config.start() self.game = config.getOthello() def _init_game(self) -> None: # Make some game constants more easily accessible self.rows = self.game.board.rows self.columns = self.game.board.cols # # Main window # self._root = Tk() self._root.title("Othello") self._root.columnconfigure(0, weight=1) self._root.rowconfigure(2, weight=1) self._root.minsize(50 * self.columns + 100, 50 * self.rows + 100) # # Score Label # score_frame = Frame(self._root) self._score_label = ttk.Label(score_frame, background="white", foreground="black", text="TEMPORARY LABEL") #TODO: compute label text score_frame.grid(row=0, column=0, sticky="ew") self._score_label.grid(row=0, column=0, sticky="ew", padx=5, pady=5) score_frame.columnconfigure(0, weight=1) # # Info Label # info_frame = Frame(self._root) self._info_label = ttk.Label(info_frame, text="", background="white", foreground="black") info_frame.grid(row=1, column=0, sticky="ew") self._info_label.grid(row=0, column=0, sticky="ew", padx=5, pady=5) info_frame.columnconfigure(0, weight=1) # # Game content (Othello board) # self._content = Frame(self._root) self._content.grid(row=2, column=0, sticky="nsew") self.cells = [] for row in range(self.rows): for col in range(self.columns): self.cells.append(self._build_cell(row, col)) self._content.columnconfigure(col, weight=1) self._content.rowconfigure(row, weight=1) def _build_cell(self, row: int, col: int) -> Frame: cell = Frame(self._content, borderwidth=5, relief=const.SUNKEN, height=50, width=50) cell._canvas = Canvas(master=cell, height=50, width=50) cell.row = row cell.col = col cell.bound = False cell.grid(row=row, column=col, sticky="nsew") cell.columnconfigure(0, weight=1) cell.rowconfigure(0, weight=1) cell._canvas.grid(row=0, column=0, sticky="nsew") return cell def refresh_board(self) -> None: self.draw_board() self._score_label["text"] = "I update when things happen. n = %d" % self.n self.n = self.n + 1 def draw_board(self) -> None: for cell in self.cells: p = Point(cell.col, cell.row) board_piece = self.game.board.piece_at(p) if(Piece.is_playable_piece(board_piece)): self.draw_piece(cell, board_piece) if cell.bound: cell._canvas.unbind("<ButtonPress-1>", None) else: cell._canvas.bind("<ButtonPress-1>", self.click_empty) cell.bound = True def draw_piece(self, cell: Frame, piece: Piece) -> None: cell._canvas.delete(const.ALL) if(piece == Piece.WHITE): cell._canvas.create_oval(10, 10, 50, 50, fill="light grey") elif(piece == Piece.BLACK): cell._canvas.create_oval(10, 10, 50, 50, fill="black") def click_empty(self, event) -> None: row = event.widget.master.row col = event.widget.master.col try: self.game.make_move(row + 1, col + 1) except InvalidMoveException as e: # TODO: # make this print the handled exception's message so we can get rid of # this hard coded string and make it so the error message only has to # be changed in one place self._info_label["foreground"] = ["red", "orange", "yellow", "green", "blue", "purple"][randint(0,5)] self._info_label["text"] = str(e) self.refresh_board() def start(self) -> None: self._root.mainloop()
class GameTab(Frame): def __init__(self, master): Frame.__init__(self, master) self._main_window = self.master.master self._land_land_roll = False self._heading = Frame(self) self._inventory_display = Frame(self) self._die_field = Frame(self) self._score_field = LabelFrame(self) self._turn_order = Frame(self) self.die = None if self._main_window.is_game_in_progress.get(): self._load_content() @property def _current_player(self): return self._main_window.engine.aktivjatekos def reset_content(self): self._heading.destroy() self._heading = Frame(self) self._inventory_display.destroy() self._inventory_display = Frame(self) self._die_field.destroy() self._die_field = Frame(self) self._score_field.destroy() self._score_field = LabelFrame(self) self._turn_order.destroy() self._turn_order = Frame(self) if self.die: self.die.destroy() self.die = None self._load_content() def _load_content(self): self.master.tab( 1, state=NORMAL) # TODO fix it when window is being resized. self._build_heading(0) self._build_inventory_display(1) self._build_score_field(2) self._build_state_display(3) self._horizontal_line(4) self._build_die_field(5) self._horizontal_line(6) self._build_turn_order(7) def _build_heading(self, position): flag = Gallery.get( f"flag_{self._current_player.empire.adjective.lower()}") Label(self._heading, text=self._current_player.name).grid(row=0, column=0) Label(self._heading, image=flag).grid(row=1, column=0) self._heading.grid(row=position, column=0, pady=5) def _build_inventory_display(self, position): gold_frame = LabelFrame(self._inventory_display, text=s.language.treasure) Label(gold_frame, image=Gallery.get("penz-d2")).grid(row=0, column=0) Label(gold_frame, textvariable=self._current_player.gold).grid(row=0, column=1) gold_frame.grid(row=0, column=0, sticky=N + E + W + S, padx=5) crew_frame = LabelFrame(self._inventory_display, text=s.language.crew) Label(crew_frame, image=Gallery.get("crew")).grid(row=0, column=0) Label(crew_frame, textvariable=self._current_player.crew).grid(row=0, column=1) crew_frame.grid(row=0, column=1, sticky=N + E + W + S, padx=5) self._inventory_display.grid(row=position, column=0) self._inventory_display.columnconfigure( ALL, minsize=(self.master.width - 20) / 2) def _horizontal_line(self, position): Separator(self, orient=HORIZONTAL).grid(row=position, column=0, sticky=E + W, padx=5, pady=5) def _build_score_field(self, position): self._score_field.config(text=s.language.scores) score_fields = {} target_empires = [empire.value for empire in Empires] target_empires.remove(self._current_player.empire) for index, empire in enumerate(target_empires): score_fields[empire.adjective] = Frame(self._score_field) flag = Gallery.get(f"flag_{empire.adjective.lower()}") Label(score_fields[empire.adjective], image=flag).grid(row=0, column=0) Label(score_fields[empire.adjective], text=':').grid(row=0, column=1) Label(score_fields[empire.adjective], textvariable=self._current_player.scores[ empire.adjective]).grid(row=0, column=2) score_fields[empire.adjective].grid(row=int((index / 2) % 2), column=index % 2, sticky=E + W) self._score_field.grid(row=position, column=0) self._score_field.columnconfigure(ALL, minsize=(self.master.width - 34) / 2) def _build_die_field(self, position): self._die_field.columnconfigure(0, weight=1) self._die_field.rowconfigure(0, weight=1) self._die_field.grid(row=position, column=0, ipady=5, ipadx=5) should_miss_turn = self._current_player.turns_to_miss.get() if should_miss_turn > 0: self._build_miss_turn_button(should_miss_turn) else: self._build_die() def _build_miss_turn_button(self, should_miss_turn): if should_miss_turn > 1: message = s.language.miss_turn % should_miss_turn else: message = s.language.miss_turn_last_time Button(self._die_field, text=message, command=self._main_window.engine.kimaradas).pack() if "leviathan" in self._current_player.states: command = self._main_window.engine.leviathan_kijatszasa Button(self._die_field, text=s.language.play_leviathan, command=command).pack() def _build_die(self): self._die_field.config(relief=RAISED, bd=2) self.die = Die(self._die_field, self.master.width / 4, self._current_player.color, self._current_player.secondary_color, self._current_player.last_roll) castaway_tiles = self._main_window.game_board.locations["castaways"] player_is_on_castaway_island = self._current_player.coordinates in castaway_tiles player_has_no_crew = not self._current_player.crew.get() if player_is_on_castaway_island and player_has_no_crew: self.die.bind('<Button-1>', self._main_window.engine.szamuzottek) else: self.die.bind('<Button-1>', self._roll_die) self.die.grid(row=0, column=0) def _build_turn_order(self, position): players = [] turn_order_label = Label(self._turn_order, text=s.language.turn_order) turn_order_label.grid(row=0, column=0, sticky=W) for index, player_name in enumerate(self._main_window.player_order): player = self._main_window.players[player_name] players.append( Label(self._turn_order, text=str(index + 1) + '. ' + player.name, bg=player.color, fg=player.secondary_color)) players[-1].grid(row=index + 1, column=0, sticky=W, padx=10) self._turn_order.grid(row=position, column=0, sticky=W, padx=5) def _build_state_display(self, position): state_field = LabelFrame(self, text=s.language.cards, relief=RAISED, width=self.master.width - 31) state_slots_per_row = int((self.master.width - 31) / 32) state_slot_height = 24 + ( (int(len(self._current_player.states) / state_slots_per_row) + 1) * 32) if self._current_player.states: for index, state in enumerate(self._current_player.states): if state not in self._main_window.engine.nemKartyaStatusz: if state in self._main_window.engine.eventszotar.keys(): origin = self._main_window.engine.eventszotar prefix = "event" else: origin = self._main_window.engine.kincsszotar prefix = "treasure" icon = f"{prefix}_{self._main_window.engine.eventszotar[state].kep}_i" icon = icon[(icon.find('_') + 1):] button = Button( state_field, image=Gallery.get(icon), command=lambda s=state: origin[s].megjelenik(1)) button.grid(row=int(index / state_slots_per_row), column=index % state_slots_per_row) state_field.config(height=state_slot_height) if state_field.winfo_children(): state_field.grid(row=position, column=0) state_field.grid_propagate(False) def _roll_die(self, event): if self._land_land_roll: self._main_window.game_board.turn_off_blinker() self._main_window.engine.dobasMegtortent.set(False) if not self._main_window.engine.dobasMegtortent.get(): dobas = self.die.roll() if "landland" in self._current_player.states: debug("New roll is possible because of Land, land! bonus.") self._main_window.status_bar.log(s.language.land_log) self._current_player.remove_state("landland") self._land_land_roll = True else: self._main_window.status_bar.log('') self._die_field.config(relief=SUNKEN) self._main_window.engine.set_dobasMegtortent() self._main_window.is_turn_in_progress.set(1) self._main_window.engine.aktivjatekos.last_roll = dobas self._main_window.engine.mozgas(dobas, 1) def disable_additional_roll(self): if self._land_land_roll is False: self._main_window.status_bar.log('') self._die_field.config(relief=SUNKEN) self._land_land_roll = False
class App(Frame): def __init__(self,parent): Frame.__init__(self,parent) self.parent = parent self.tileList = [] self.currentNumOfQueens = None self.initUI() # Hàm này có nhiệm vụ khởi tạo các widget chứa bên trong App def initUI(self): # Cấu hình layout cho cửa sổ này # Tham số side = "left" cho biết layout sẽ cố định bên trái, fill = "both" thì kích thước của layout # sẽ lắp đầy 2 bên, expand = True cho phép mở rộng self.pack(side = "left", fill = "both", expand = True) # Tạo một frame, frame này sẽ chứa MAP đặt n Queens # Tham số self cho biết widget sẽ chứa nó, width là chiều rộng, height là chiều cao self.map = Frame(self, width = 600, height = 600) self.map.pack(side = "left", fill ="both", expand = True) # Lấy ra thông tin chiều dài và rộng tính theo pixel của MAP, ta trừ đi kích thước 20 # để cách đều ra 2 bên self.map.update() self.x = int(self.map.winfo_width() - 20) self.y = int(self.map.winfo_width() - 20) # Tạo frame thứ 2, frame này sẽ chưa textbox cho ta nhập số n queens, số lần lặp của thuật toán self.frameWidget = Frame(self,width = 150) self.frameWidget.pack(side = "left", fill ="both", expand = True) self.lbNumOfQueens = Label(self.frameWidget, text = "Num of Queens") # Tham số pady = 25, để label cách đều về 2 phía theo trục y 25 px self.lbNumOfQueens.pack(pady = 25) # Tạo textbox để nhập số quân hậu cần đặt self.entryNumOfQueens = Entry(self.frameWidget) self.entryNumOfQueens.pack() self.lbNumOfInteractions = Label(self.frameWidget, text = "Num of Interactions") # Tham số pady = 25, để label cách đều về 2 phía theo trục y 25 px self.lbNumOfInteractions.pack(pady = 25) # Tạo textbox để nhập số lần lập của thuật toán self.entryNumOfInteractions= Entry(self.frameWidget) self.entryNumOfInteractions.pack() # Tạo button để chạy giải quyết thuậ toán # Tham số command = self.resolving để tạo sự kiện khi nhấn button này self.btnResolving = Button(self.frameWidget, text = "Simulated Annealing", command = self.resolving) self.btnResolving.pack(pady = 50) # Tạo label để hiển thị thời gian chạy của thuật toán self.lbTime= Label(self.frameWidget, text = "0.00s") # Tham số pady = 25, để label cách đều về 2 phía theo trục y 25 px self.lbTime.pack(pady = 25) # Hàm tạo bàn cờ numOfQueens x numOfQueens def createMap(self,numOfQueens): for widget in self.map.winfo_children(): widget.destroy() self.map.update() self.tileList.clear() # Ta lấy chiều dài và rộng của 1 ô theo pixel w = int(self.x/numOfQueens) h = int(self.y/numOfQueens) # Cấu hình cột hàng cho MAP for k in range(numOfQueens): self.map.columnconfigure(k, pad = 2) self.map.rowconfigure(k, pad = 2) # Tạo các label đại diện cho một ô trong MAP for i in range(numOfQueens): self.tileList.append([]) for j in range(numOfQueens): # Tạo một ảnh pixel, để khi ta set width và height cho Label thì nó sẽ lấy theo pixel # chứ không phải mm #Ta chỉnh các background xen kẽ nhau bg = "white" if (i+j) % 2 == 0: bg = "gray" pixelVirtual = PhotoImage(width = 1, height = 1) lb = Label(self.map, image = pixelVirtual, width = w, height = h, bg = bg,padx = 2, pady = 2) lb.grid(row = i, column = j) # Đặt nó vào hàng i, cột j của MAP self.tileList[i].append(lb) ''' Hàm tìm ra solution và đặt các con hậu lên MAP ''' def resolving(self): # Khi thuật toán bắt đầu tìm kiếm, ta tiến hành khóa button này lại, tránh trường hợp # click nhiều lần từ người dùng self.btnResolving["state"] = "disabled" numOfQueens = int(self.entryNumOfQueens.get()) # Ta kiểm tra xem số hậu được nhập từ người dùng là lần đầu tiên hay là số hậu mới, hay # là chỉ tìm kiếm cách đặt hậu mới # self.currentNumOfQueens = None thì ban đầu ta sẽ tạo ra một cái map mới hoặc # số hậu nhận từ người dùng ở lần tiếp theo khác với số hậu nhập từ người dùng ở lần trước đó # thì ta cũng tạo ra map mới. Ngược lại thì ta không cần tạo map mới mà chỉ cần đặt lại vị trí # hình ảnh quân hậu if self.currentNumOfQueens == None or self.currentNumOfQueens != numOfQueens: self.currentNumOfQueens = numOfQueens self.isNewMap = True else: self.isNewMap = False temperature = int(self.entryNumOfInteractions.get()) solution, ti = algr.getResults(numOfQueens,temperature) if self.isNewMap == True: self.createMap(numOfQueens) self.setTheQueens(numOfQueens,solution) self.lbTime.configure(text = str(ti)+"s") # Thuật toán chạy xong, các con hậu được đặt, ta mở khóa button cho người dùng tìm kiếm # các cách đặt khác self.btnResolving["state"] = "active" ''' Hàm đặt các quân hậu dựa vào solution tìm được ''' def setTheQueens(self,numOfQueens,solution): for i in range(numOfQueens): for j in range(numOfQueens): self.tileList[i][j].configure(image = None) self.tileList[i][j].image = None for column, row in solution.items(): image =ImageTk.PhotoImage(Image.open(os.getcwd()+"/queen.png")) self.tileList[row][column].configure(image = image) self.tileList[row][column].image = image
def __init__(self, primary): #super().__init__(primary) self.primary = primary primary.geometry("800x700") primary.title("VME Digital to Analog Converter Control GUI") global save_file save_file = 'mpv904_DAC_Voltage_Settings.json' #os.system('ls')#Reminder for how to run commands in terminal with Python. #Read in json file containing a list with all of the saved voltage channel settings. voltage_settings = get_voltage_settings(save_file) for ch in range(16): print('Output channel',ch,'is set to',voltage_settings[ch],'Volts.') #Create a frame to hold the exit button. exit_frame = Frame(primary, relief=RAISED, borderwidth=2) exit_frame.pack(side='bottom') exit_btn = Button(exit_frame, text='Close', width=2, height=1, font='Helvetica 8 bold', command=root.quit, bg = "red") exit_btn.pack(side="bottom") #Create a frame to hold directions and settings along with the save settings button. info_frame = Frame(primary, relief=RAISED, borderwidth=2) info_frame.pack(side='left', fill=BOTH, expand=True) save_btn = Button(info_frame, text='Save Settings', width=10, height=4, font='Helvetica 12 bold', command=self.save_settings, bg = "yellow") save_btn.pack(side="bottom") #canvas = Canvas(info_frame, width = 60,height = 60) #my_oval = canvas.create_oval(5, 5, 30, 30)#(x0,y0,x1,y1)=(top left corner of rectangle, bottom right corner) #canvas.itemconfig(my_oval, fill="red") #canvas.create_text(17,18,font='Helvetica 8 bold',text='OFF') #canvas.pack(side='top') #Create frame to set the individual channel voltage outputs. ch_settings_frame = Frame(primary, relief=RAISED, borderwidth=2) ch_settings_frame.pack(side='left', fill=BOTH, expand=True) self.nchs = 16 #Number of VME DAC output channels. nrows = self.nchs #Number of rows of channels settings. ncols = 6 #Number of columns per channel setting row. self.ch_labels = [] #Array to hold channel labels. self.readback_labels = [] #Array to hold current voltage setting readback labels. self.predicted_threshold_labels = [] #Array to hold predicted VME DAC threshold setting. self.voltage_setting_entries = [] #Array to hold entry widgets for entering the DAC voltage settings. self.power_buttons = [] #Array to hold the power on/off buttons for each output channel. self.indicator_lights = [] #Array to hold the indicator lights to see if a channel is energized. entry_names = [] for ch in range(self.nchs): #Create and store the channel labels. self.ch_label_text = StringVar() self.ch_label_text.set("Channel "+str(ch)) self.ch_label = Label(ch_settings_frame, width = 9,textvariable=self.ch_label_text) self.ch_labels.append(self.ch_label) #Create and store the channel voltage readback labels. self.readback_label_text = StringVar() self.readback_label_text.set(str(voltage_settings[ch])) self.readback_label = Label(ch_settings_frame, width = 9,textvariable=self.readback_label_text) self.readback_labels.append(self.readback_label) #Create and store the predicted discriminator threshold labels. self.thr_label_text = StringVar() self.thr_label_text.set("NA") self.thr_label = Label(ch_settings_frame, width = 9,textvariable=self.thr_label_text) self.predicted_threshold_labels.append(self.thr_label) #Create and store the entry widgets for setting the channel voltage outputs. self.voltage_setting_entry = Entry(ch_settings_frame, width = 5) self.voltage_setting_entry.insert(0,str(voltage_settings[ch])) self.voltage_setting_entries.append(self.voltage_setting_entry) #Create and store the buttons for enabling/disabling the channel voltage outputs. self.power_btn = Button(ch_settings_frame, text='Set\n Voltage', width=3, height=1, font='Helvetica 8 bold') self.power_btn.configure(command=lambda button=self.power_btn, buttons=self.power_buttons, indicator_lights=self.indicator_lights, voltage_setting_entries=self.voltage_setting_entries: toggle_power(button,buttons,indicator_lights,voltage_setting_entries)) self.power_buttons.append(self.power_btn) #Create and store indicator 'lights' to show whether a channel is energized or not. self.canvas = Canvas(ch_settings_frame, width = 45,height = 45) my_oval = self.canvas.create_oval(15, 5, 40, 30)#(x0,y0,x1,y1)=(top left corner of rectangle, bottom right corner) self.canvas.itemconfig(my_oval, fill="red") self.canvas.create_text(27,18,font='Helvetica 8 bold',text='OFF') self.indicator_lights.append(self.canvas) #Create labels for the columns. col_labels = [] col_labels_text = ['Output Channels','Current Voltage\n Setting (Volts)','Predicted\n Discriminator\n Threshold (mV)','Enter New\n Voltage Setting\n (Volts)','Set & Save\n Single Channel\n Voltage','Error\n Indicator'] for col in range(ncols): col_label_text = StringVar() col_label_text.set(col_labels_text[col]) col_label = Label(ch_settings_frame, width = 14,height=3,textvariable=col_label_text,font='Helvetica 10 bold') col_labels.append(col_label) #Define the rows and cols for the button grid. for row in range(0,nrows+1): ch_settings_frame.rowconfigure(row, pad=3, weight=1) for col in range(0,ncols): ch_settings_frame.columnconfigure(col, pad=3, weight=1) #Place widgets on the grid. for row in range(0,nrows+1): if row!=0: self.ch_labels[row-1].grid(row=row, column=0, sticky='NSEW') self.readback_labels[row-1].grid(row=row, column=1, sticky='NSEW') self.predicted_threshold_labels[row-1].grid(row=row, column=2, sticky='NSEW') self.voltage_setting_entries[row-1].grid(row=row, column=3) self.power_buttons[row-1].grid(row=row, column=4) self.indicator_lights[row-1].grid(row=row, column=5) for col in range(0,ncols): if row==0: col_labels[col].grid(row=row, column=col, sticky='NSEW')
class Game: def __init__(self): self.window = Tk() self.window.title("Click Me!!") self.createwidgets() def createframes(self): self.frame1 = Frame(self.window) self.frame2 = Frame(self.window) self.frame1.configure(bg='silver', relief='raised', border='15') self.frame2.configure(bg='blue', relief='raised', border='15') self.frame1.rowconfigure(6) self.frame1.columnconfigure(5) self.frame2.rowconfigure(15) self.frame2.columnconfigure(5) self.frame1.grid(row=0, column=0, rowspan=6, columnspan=5) self.frame2.grid(row=6, column=0, rowspan=15, columnspan=5) def createtitle(self): self.title = Label(self.frame1) self.title.configure(bg='silver', fg='SlateBlue4', font='serif 30', justify='center', padx='10', pady='10', text="Click Me! And Don't Don't Click Me!!") self.title.grid(row=0, column=0, rowspan=1, columnspan=5) def createstart(self): self.start = Button(self.frame1) self.start['text'] = 'Start' self.start['command'] = partial(self.start_game) self.start.grid(row=1, column=2, rowspan=1, columnspan=1) def createstop(self): self.stop = Button(self.frame1) self.stop['text'] = 'Stop.' self.stop['command'] = partial(self.stop_game) self.stop.grid(row=1, column=3, rowspan=1, columnspan=1) def createscore(self): self.score_label = Label(self.frame1) self.score_label.configure(fg='black', font='serif 10') self.score_label['text'] = 'Score:' self.score_label.grid(row=3, column=2, rowspan=1, columnspan=1) self.score = Label(self.frame1) self.score.configure(bg='black', fg='white', font='serif 16') self.score.grid(row=5, column=2, rowspan=1, columnspan=1) def createtime(self): self.time_label = Label(self.frame1) self.time_label.configure(fg='black', font='serif 10') self.time_label['text'] = 'Time:' self.time_label.grid(row=3, column=3, rowspan=1, columnspan=1) self.time = Label(self.frame1) self.time.configure(bg='black', fg='white', font='seriv 16') self.time.grid(row=5, column=3, rowspan=1, columnspan=1) def createbuttons(self): self.buttons = [] for item in range(75): button = Button(self.frame2, width=len("Don't Click Me!")) rownum, colnum = divmod(item, 5) button.grid(row=rownum, column=colnum, rowspan=1, columnspan=1) button['command'] = partial(self.clicked, button) self.buttons.append(button) self.shuffle() def createwidgets(self): self.createframes() self.createtitle() #self.createinstr() self.createstart() self.createstop() self.createscore() self.createtime() self.createbuttons()
def __init__(self): """ Methode speciale initialisant une nouvelle fenêtre de jeu Ultimate Tic-Tac-Toe. """ super().__init__() # Nom de la fenêtre. self.title("Ultimate Tic-Tac-Toe") # La partie de ultimate Tic-Tac-Toe self.partie = Partie() # Un ditionnaire contenant les 9 canvas des 9 plateaux du jeu self.canvas_uplateau = {} # Création de deux joueurs. self.JoueursDuJeux() Popup() # Création des frames et des canvas du jeu for i in range(0, 3): for j in range(0, 3): cadre = Frame(self, borderwidth=5, relief=GROOVE, background = '#e1e1e1') cadre.grid(row=i, column=j, padx=5, pady=5) cadre.columnconfigure(0, weight=1) cadre.rowconfigure(0, weight=1) cadre.columnconfigure(1, weight=1) cadre.rowconfigure(1, weight=1) cadre.columnconfigure(2, weight=1) cadre.rowconfigure(2, weight=1) #cadre.columnconfigure(j, weight=1) #cadre.rowconfigure(i, weight=1) #Dessiner le cadre en jaune si la sourie entre dans le cadre cadre.bind('<Enter>', self.entrer_frame) cadre.bind('<Leave>', self.sortir_frame) self.canvas_uplateau[i, j] = CanvasPlateau(cadre, self.partie.uplateau[i, j]) self.canvas_uplateau[i, j].grid() # On lie un clic sur le Canvas à une méthode. self.canvas_uplateau[i, j].bind('<Button-1>', self.selectionner) #Pour redimensionner automatiquement la fenêtre principale self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(1, weight=1) self.grid_rowconfigure(1, weight=1) self.grid_columnconfigure(2, weight=1) self.grid_rowconfigure(2, weight=1) # Ajout d'une étiquette d'information. self.messages = Label(self) self.messages.grid(column=0, row=4, columnspan=3) # Ajout d'une étiquette pour le nom des joueurs. self.labNoms = Label(self) self.labNoms.grid(column=0, row=5) # Ajout d'une étiquette pour la date et le chronometre. self.labDate = Label(self) self.labDate.grid(column=0, row=6) # Les bouttons en dessous B1 = Button(self, text='Règles', width=15, command=self.regles).grid(row=7,column=0) B2 = Button(self, text='Nouvelle Partie', width=15, command=self.nouvellePartie).grid(row=7, column=1) B3 = Button(self, text='Statistiques', width=15, command=self.statistiques).grid(row=7, column=2) B4 = Button(self, text='Historique', width=15, command=self.regles).grid(row=8, column=1) B5 = Button(self, text='Quitter', width=5, command=self.quitter).grid(row=8, column=2) B5 = Button(self, text='Tout recommencer', width=15, command=self.regles).grid(row=8, column=0)
def main(): root = Tk() root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) root.geometry('900x600+50+50') root.title('Imagepreview Test') window = Frame(root) window.grid(column=0, row=0, sticky='news') window.columnconfigure(0, weight=1) window.rowconfigure(0, weight=0) window.rowconfigure(1, weight=1) topWidget = Label(window, text='Image Preview', font=('Arial', '32')) topWidget.grid(column=0, row=0, sticky='we') topWidget.columnconfigure(0, weight=1) topWidget.rowconfigure(0, weight=1) '''************ImagePreview************''' previewFrame = Frame(window) previewFrame.grid(column=0, row=1, sticky='news') previewFrame.columnconfigure(0, weight=1) previewFrame.rowconfigure(0, weight=1) try: testImage = Image.open('test.jpg') except: testImage = Image.new('RGB', (100, 100), color='#999999') preview = Imagepreview.Imagepreview(previewFrame, testImage, zoomscale=1.2, minzoomlevel=0.1, maxzoomlevel=20.0, quality=0, backgroundcolor='#999999') preview.grid(column=0, row=0, sticky='news') '''************************************''' buttonColor = 'gray80' controlFrame = Frame(window) controlFrame.grid(column=1, row=0, rowspan=3, padx=3) previewFrame.rowconfigure(2, weight=0) def update_label(event=None): infoLabel.config( anchor='w', text= 'Scale:\t\tx{}\n\nWidth:\t\t{}\nHeight:\t\t{}\n\nScale width:\t{}\nScale height:\t{}' .format(round(preview.canvasScale, 2), testImage.width, testImage.height, preview.resizedImage.width, preview.resizedImage.height)) def reset_button(event=None): preview.reset_preview() update_label() def original_button(event=None): preview.original_zoom() update_label() resetButton = Button(controlFrame, text='Reset Preview (Ctrl+R)', command=reset_button, bg=buttonColor) resetButton.grid(column=0, row=0, sticky='we') originalButton = Button(controlFrame, text='x1.0 zoom (Num 1)', command=original_button, bg=buttonColor) originalButton.grid(column=0, row=1, sticky='we') seperatorOne = Separator(controlFrame) seperatorOne.grid(column=0, row=2, sticky='we', pady=10) infoLabel = Label(controlFrame, anchor='w') infoLabel.grid(column=0, row=3, sticky='s') infoLabel.config( text= 'Scale:\t\tx{}\n\nWidth:\t\t{}\nHeight:\t\t{}\n\nScale width:\t{}\nScale height:\t{}' .format(round(preview.canvasScale, 2), testImage.width, testImage.height, preview.resizedImage.width, preview.resizedImage.height)) if os.name == 'nt': root.bind('<MouseWheel>', update_label) elif os.name == 'posix': root.bind('<Button-4>', update_label) root.bind('<Button-5>', update_label) # root.bind('<MouseWheel>', update_label) root.bind('1', original_button) root.bind('<Control-r>', reset_button) def update_quality(x): for child in qualityFrame.winfo_children(): try: child.configure(bg='white', fg='black') except: pass if x == 0: qualityZero.configure(bg='gray10', fg='white') elif x == 1: qualityOne.configure(bg='gray10', fg='white') elif x == 2: qualityTwo.configure(bg='gray10', fg='white') elif x == 3: qualityThree.configure(bg='gray10', fg='white') elif x == 4: qualityFour.configure(bg='gray10', fg='white') preview.resizeQuality = x preview.scaleChanged = True preview.display_image(image=preview.previewImage, quality=x) seperatorTwo = Separator(controlFrame) seperatorTwo.grid(column=0, row=4, sticky='we', pady=10) qualityFrame = Frame(controlFrame) qualityFrame.grid(column=0, row=5, sticky='we', padx=30) qualityFrame.columnconfigure(0, weight=1) qualityLabel = Label(qualityFrame, text='Resize Filter', font=('Arial', '10', 'bold')) qualityLabel.grid(column=0, row=0, sticky='we', pady=5) qualityZero = Button(qualityFrame, text='0 (NEAREST)', anchor='w', command=lambda: update_quality(0)) qualityZero.grid(column=0, row=1, sticky='we') qualityOne = Button(qualityFrame, text='1 (BILINEAR)', anchor='w', command=lambda: update_quality(1)) qualityOne.grid(column=0, row=2, sticky='we') qualityTwo = Button(qualityFrame, text='2 (HAMMING)', anchor='w', command=lambda: update_quality(2)) qualityTwo.grid(column=0, row=3, sticky='we') qualityThree = Button(qualityFrame, text='3 (BICUBIC)', anchor='w', command=lambda: update_quality(3)) qualityThree.grid(column=0, row=4, sticky='we') qualityFour = Button(qualityFrame, text='4 (LANCZOS)', anchor='w', command=lambda: update_quality(4)) qualityFour.grid(column=0, row=5, sticky='we') update_quality(0) seperatorThree = Separator(controlFrame) seperatorThree.grid(column=0, row=6, sticky='we', pady=10) def load_image(): try: filetypes = [('JPEG', '*.jpg *.jpeg'), ('PNG', '*.png'), ("all files", "*.*")] testImage = Image.open( askopenfilename(title='Load Image...', defaultextension='.', filetypes=filetypes)) preview.update_image(image=testImage) except AttributeError: pass loadButton = Button(controlFrame, text='Load Image', font=('Arial', '18'), command=load_image, bg=buttonColor) loadButton.grid(column=0, row=7, sticky='we') window.update() root.minsize(root.winfo_width(), root.winfo_height()) preview.reset_preview() window.mainloop()
class GroupeParametre(AbstractSchedulableParametre): """ Notebook qui contient tous les paramètres du groupe fournis dans le constructeur. Permet aussi de changer ses attributs (au groupe) """ def __init__(self, master, groupe, **kw): """ @param master : <tkinter.frame> @param groupe : <Groupe> ceux qui sont à afficher """ super().__init__(master, groupe, **kw) # page des schedulables in self.__frameSchedu = Frame(self) super().add(self.__frameSchedu, text = "Tâches") # Initialisation des variables self.__listParamTask = [] # Liste des TaskParametres dont il faudra appeler onClose self.__varNbTask = IntVar() self.__varListTasks = StringVar() self.__varComboLT = StringVar() # Affectation des variables self.__varNbTask.set(len(self._getSchedulable().getListTasks())) self.__varListTasks.set([(str(s) + " ID : " + s.getUniqueID()) for s in self._getSchedulable().getListTasks()]) # Attributs généraux self.__lbTaskNb = Label(self._frameGeneral, text = "Nombre de taches :") self.__lbResultTaskNb = Label(self._frameGeneral, textvariable = self.__varNbTask) self.__lbTask = Label(self._frameGeneral, text = "Taches :") self.__lbListTask = Listbox(self._frameGeneral, listvariable = self.__varListTasks, height = len(self._getSchedulable().getListTasks()), selectmode = "extended") self.__btnRetireGen = Button(self._frameGeneral, text = "Retirer", command = lambda : self.__removeTask(strTask = self.__lbListTask.get(ACTIVE))) # Attributs avancées # Attributs taches self.__cbSchedu = Combobox(self.__frameSchedu, value = [(str(s) + " ID : " + s.getUniqueID()) for s in self._getSchedulable().getListTasks()], state = "readonly", textvariable = self.__varComboLT) self.__cbSchedu.bind("<<ComboboxSelected>>", self.__updateTask) self.__btnRetireTask = Button(self.__frameSchedu, text = "Retirer", command = lambda : self.__removeTask(strTask = self.__varComboLT.get())) ## Affichage # Générale (grid Obligé) self.__lbTaskNb.grid( row = 6, column = 0, sticky = "e") self.__lbResultTaskNb.grid(row = 6, column = 1) self.__lbTask.grid( row = 7, column = 0, sticky = "e") self.__lbListTask.grid( row = 7, column = 1, sticky = NSEW, rowspan = 2) self.__btnRetireGen.grid( row = 8, column = 0, sticky = "e") # Taches (libre) self.__cbSchedu.grid(row = 0, column = 0, sticky = "we") self.__btnRetireTask.grid(row = 0, column = 1) # Final self._frameGeneral.columnconfigure(1, weight = 1) self.__frameSchedu.columnconfigure(0, weight = 1) self.__frameSchedu.rowconfigure(1, weight = 1) "" ############ # Méthodes # ############ "" def __removeTask(self, strTask = None): """ Méthode qui retire la task du groupe @param task : <str> de la tache AVEC son UID """ # S'il n'y a rien if strTask is None or strTask == "": return # On cherche l'ID id = strTask.split("ID")[-1] id = id[id.rfind(" ")+1:] # On retire le schedulable task = [s for s in self._getSchedulable().getListTasks() if s.getUniqueID() == id][0] ## Test de si on supprime le groupe # S'il reste plein de taches : if len(self._getSchedulable().getListTasks()) > 1: self._getSchedulable().removeTask(task, testDelete = True) # On remet à jour tout le monde self.__cbSchedu.config(value = [(str(s) + " ID : " + s.getUniqueID()) for s in self._getSchedulable().getListTasks()]) self.__varComboLT.set("") self.__updateTask() self.__varNbTask.set(len(self._getSchedulable().getListTasks())) self.__varListTasks.set([(str(s) + " ID : " + s.getUniqueID()) for s in self._getSchedulable().getListTasks()]) # Si c'est notre dernier Schedulable elif len(self._getSchedulable().getListTasks()) == 1 and askyesnowarning("Retrait de la dernière tache", "Vous êtes sur le point de retirer du groupe sa dernière tache.\nSi vous continuez, cela supprimera le groupe, êtes vous sur de vouloir retirer la tache ?"): self._getSchedulable().removeTask(task, testDelete = True) self.master.execute("Supprimer") # On fait comme si on cliquait sur le bouton suppr else: return def __updateTask(self, e = None): """ Méthode pour mettre à jour l'affichage de la tache en question dont on doit afficher les pramatres """ t = [task for task in self._getSchedulable().getListTasks() if (str(task) + " ID : " + task.getUniqueID()) == self.__cbSchedu.get()] # Si rien de correspond on grid_forget et on annule tout (c'est si on retire la tache en question) if t == []: # ne pas mettre if self.__listParamTask != [] self.__listParamTask[-1].grid_forget() if self.__listParamTask != [] else None self.__listParamTask.pop(-1) if self.__listParamTask != [] else None return else : t = t[0] # Si la liste est vide on a juste à grid et enregistrer ce nouveau TaskParametre if self.__listParamTask == []: self.__listParamTask.append(TaskParametre(self.__frameSchedu, t)) self.__listParamTask[-1].grid(row = 1, column = 0, columnspan = 2, sticky = NSEW) # Sinon il faut gridForget le dernier else : self.__listParamTask[-1].grid_forget() for paramTask in self.__listParamTask: if paramTask._getSchedulable() == t: paramTask.grid(row = 1, column = 0, columnspan = 2, sticky = NSEW) # On le remet à la fin, prêt à être grid_forget() self.__listParamTask.append(self.__listParamTask.pop(self.__listParamTask.index(paramTask))) break else: self.__listParamTask.append(TaskParametre(self.__frameSchedu,t)) self.__listParamTask[-1].grid(row = 1, column = 0, columnspan = 2, sticky = NSEW) "" # Pour le repli de code ########### # onClose # ########### "" def onClose(self): """ On change les attributs """ super().onClose() for p in self.__listParamTask: p.onClose()
class MainGUI(Frame): def __init__(self, master, kernel): self.kernel = kernel self.master = master self.master.columnconfigure(1, weight=1) Grid.rowconfigure(self.master, 0, weight=1) self.left_frame = Frame(master) self.left_frame.grid(row=0, column=0, sticky=W+E+N+S) self.left_frame.columnconfigure(1, weight=1) Grid.rowconfigure(self.left_frame, 0, weight=1) self.right_frame = Frame(master) self.right_frame.grid(row=0, column=1, sticky=W+E+N+S) self.right_frame.columnconfigure(1, weight=1) Grid.rowconfigure(self.right_frame, 1, weight=1) # Variables self.include_cols = [] self.col_map = [] self.settings = {} self.om = None # Settings frame self.build_settings_frame() # Info frame self.build_info_frame() # Menu bar self.build_menue_bar() # Overview frame self.overview_frame = Frame(self.right_frame, bd=1, relief=GROOVE) self.overview_frame.grid(row=0, column=1, rowspan=2, sticky=W+E+N+S) def build_overview(self, data, header): self.overview_frame.destroy() self.overview_frame = Frame(self.right_frame, bd=1, relief=GROOVE) self.overview_frame.grid(row=0, column=1, rowspan=2, sticky=W+E+N+S) self.overview_frame.columnconfigure(0, weight=1) self.overview_frame.rowconfigure(0, weight=1) win_frame = Frame(self.overview_frame, background="#ffffff") x_frame = Frame(self.overview_frame) y_frame = Frame(self.overview_frame) z_frame = Frame(self.overview_frame) win_frame.grid(row=0, column=0, sticky=W+E+N+S) x_frame.grid(row=1, column=0, sticky=W+E) y_frame.grid(row=0, column=1, sticky=N+S) z_frame.grid(row=1, column=1, sticky=W+E+N+S) scroll_frame = ScrollableFrame(win_frame, x_frame, y_frame) # (De) select all Button(scroll_frame, text="Select", justify=LEFT, anchor=W, command=lambda: self.toggle_all(1)).grid(row=0, column=0, sticky=W+E) Button(scroll_frame, text="Deselect", justify=LEFT, anchor=W, command=lambda: self.toggle_all(0)).grid(row=0, column=1, sticky=W+E) if header: self.include_cols = [] for i, genre in enumerate(header): var = IntVar(self.master) var.set(1) self.include_cols.append(var) Checkbutton(scroll_frame, text=str(genre), justify=LEFT, anchor=W, variable=var, command=lambda: self.toggle_col()).grid(row=i+1, column=0, sticky=W+E, columnspan=2) self.col_map = [var.get() for var in self.include_cols] self.settings["max_clust"].set(str(len(header))) self.toggle_col() def toggle_all(self, var): for style in self.include_cols: style.set(var) self.col_map = [var.get() for var in self.include_cols] if int(self.settings["max_clust"].get()) > sum(self.col_map): self.settings["max_clust"].set(str(sum(self.col_map))) def toggle_col(self): self.col_map = [var.get() for var in self.include_cols] if int(self.settings["max_clust"].get()) > sum(self.col_map): self.settings["max_clust"].set(str(sum(self.col_map))) self.kernel.update_info() def build_menue_bar(self): menubar = Menu(self.master) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Import...", command=self.kernel.cmd_import, accelerator = 'cmd+i') filemenu.add_separator() filemenu.add_command(label="View log", command=self.kernel.cmd_view_log) self.master.bind_all('<Mod1-i>', self.kernel.cmd_import) menubar.add_cascade(label="File", menu=filemenu) self.master.config(menu=menubar) def build_settings_frame(self): frame = Frame(self.left_frame, bd=1, relief=GROOVE) frame.grid(row=0, column=0, sticky=W+E+N+S) self.settings = {"pos_val": StringVar(self.master), "neg_val": StringVar(self.master), "max_clust": StringVar(self.master), "min_clust": StringVar(self.master), "max_age": StringVar(self.master), "min_age": StringVar(self.master), "sex": StringVar(self.master), "ffan_var": StringVar(self.master), "ffan_list": []} self.settings["pos_val"].set("5") self.settings["neg_val"].set("1 2") self.settings["max_clust"].set("0") self.settings["max_clust"].trace("w", self.kernel.cmd_max_cluster_updated) self.settings["min_clust"].set("1") self.settings["min_clust"].trace("w", self.kernel.cmd_min_cluster_updated) self.settings["max_age"].set("0") self.settings["max_age"].trace("w", self.kernel.cmd_age_updated) self.settings["min_age"].set("0") self.settings["min_age"].trace("w", self.kernel.cmd_age_updated) self.settings["sex"].set("1 2") self.settings["sex"].trace("w", self.kernel.cmd_age_updated) self.settings["ffan_var"].set("All") self.settings["ffan_var"].trace("w", self.kernel.cmd_age_updated) lbls = ["Positive values:", "Negative values:", "Maximum cluster size:", "Minimum cluster size:", "Maximum age:", "Minimum age:", "Gender:", "Format fan:"] for i, lbl_text in enumerate(lbls): Label(frame, text=lbl_text).grid(row=i, column=0, sticky=W) lbls = ["pos_val", "neg_val", "max_clust", "min_clust", "max_age", "min_age", "sex"] for i, lbl_text in enumerate(lbls): Entry(frame, textvariable=self.settings[lbl_text], width=4).grid(row=i, column=1, sticky=W) # TODO Add format fan handle. self.om = OptionMenu(frame, self.settings["ffan_var"], self.settings["ffan_list"]) self.om.grid(row=i+1, column=1, sticky=W) Button(frame, text="Execute", command=self.kernel.cmd_execute).grid(row=100, column=0, sticky=W) self.kernel.default_settings(app=self) def update_ffan(self): if self.om: menu = self.om["menu"] menu.delete(0, "end") for string in self.settings["ffan_list"]: print(string) menu.add_command(label=string, command=lambda value=string: self.settings["ffan_var"].set(value)) def build_info_frame(self): info_frame = Frame(self.left_frame, bd=1, relief=GROOVE) info_frame.grid(row=1, column=0, sticky=W+E+N+S) Label(info_frame, text="Number of columns:").grid(row=0, column=0, sticky=W) Label(info_frame, text="Number of combinations:").grid(row=1, column=0, sticky=W) Label(info_frame, text="Number of participants:").grid(row=2, column=0, sticky=W) Label(info_frame, text="Estimated time:").grid(row=3, column=0, sticky=W) self.info_text = [StringVar(), StringVar(), StringVar(), StringVar()] for i, str_var in enumerate(self.info_text): str_var.set("N/A") Label(info_frame, textvariable=str_var).grid(row=i, column=1, sticky=W) def _bin_array(self, num, m): """Convert a positive integer num into an m-bit bit vector """ return array(list(binary_repr(num).zfill(m))).astype(int8)
class TimelapseGUI(): # CLASS CONSTANTS READY_TEXT = "Ready!" ICON_NAME = "assets/favicon.png" MIN_WIDTH = 500 MIN_HEIGHT = 300 CHOICES = [ 'Choose Speed', '2x', '5x', '10x', '20x', '30x', '50x', '100x', '200x', '300x', '500x', '1000x', ] SUPPORTED_FORMATS = [ '.mp4', '.webm', '.mpg', '.avi', '.mov', '.m4v', '.flv', '.mkv' ] def __init__(self): """ __init__ Initializes the GUI elements """ # variables self.files = None self.file_status = None self.var_open_files = None self.progress = None # Root Window Properties self.root = Tk() self.root.title("Timelapse Creator") self.root.minsize(self.MIN_WIDTH, self.MIN_HEIGHT) # This part is to make sure that the program runs with or without n icon file. try: if os.path.exists(self.ICON_NAME): self.icon = PhotoImage(file=self.ICON_NAME) self.root.iconphoto(False, self.icon) elif os.path.exists(os.path.split(self.ICON_NAME)[-1]): self.icon = PhotoImage(file=os.path.split(self.ICON_NAME)[-1]) self.root.iconphoto(False, self.icon) except Exception as e: print(f"Could not load Icon due to Error: {e}") # Buttons and Widgets self.config_frames() self.config_buttons() self.config_progress_bar() self.config_label() def config_frames(self): """ config_frames Set up the different sections of the GUI window """ # BUTTON SPACE self.buttons_frame = Frame(self.root) self.buttons_frame.grid(row=0, column=0, columnspan=3, padx=10, pady=10, sticky=E + W) # PROGRESS BAR SPACE self.progress_frame = Frame(self.root) self.progress_frame.grid(row=1, column=0, columnspan=3, padx=10, pady=10, sticky=E + W) # Configure how many rows and columns are there in and progress_frame self.root.columnconfigure(0, weight=1) self.root.rowconfigure(1, weight=1) self.progress_frame.columnconfigure(0, weight=1) self.progress_frame.rowconfigure(0, weight=1) def config_buttons(self): """ config_buttons Define the interactive Buttons used for the GUI App """ # Open File Browser Button self.btn_open_files = Button(self.buttons_frame, command=self.browseFiles, text='Select Videos') self.btn_open_files.grid(row=0, column=0, padx=(10), pady=10) # Dropdown Selector button self.var_open_files = StringVar(self.buttons_frame) self.dropdown_button = OptionMenu(self.buttons_frame, self.var_open_files, *self.CHOICES) self.dropdown_button.grid(row=0, column=1, padx=(10), pady=10) # Convert Button self.btn_convert = Button(self.buttons_frame, text='Convert', command=self.convert_video) self.btn_convert.grid(row=0, column=2, padx=(10), pady=10) def config_progress_bar(self): """ config_progress_bar Configure the Progress bar """ self.progress = Progressbar(self.progress_frame, orient=HORIZONTAL, length=100, mode='determinate') self.progress.grid(row=1, column=0, sticky=E + W) def config_label(self): """ config_label Add the Dynamic labels for progress tracking """ self.file_status = Label(self.progress_frame, text=self.READY_TEXT) self.file_status.grid(row=0, column=0, padx=(10), pady=10) self.file_status_percent = Label(self.progress_frame, text="0%") self.file_status_percent.grid(row=1, column=0, padx=(0), pady=0) def run(self): """ run Run the GUI Loop. """ self.root.mainloop() def file_format_generator(self, formats: list): """ file_format_generator Generates the required file format - helper function Takes a List of strings as input, adds their upper case versions as well Converts them to a space separated string, and returns the same Args: formats (list): comma separated strings of file extensions in lower case Returns: string: space separated file extensions along with corresponding upper case format """ formats = formats + [value.upper() for value in formats] return " ".join(formats) def browseFiles(self): """ browseFiles Creates the File Selector dialogbox Returns: boolean: True if valid file is selected, False if invalid """ self.files = filedialog.askopenfilenames( # initialdir="/media/Data/Downloads/", title="Videos", filetypes=(("Video Files", self.file_format_generator(self.SUPPORTED_FORMATS)), )) # Check file validity valid = bulk_validate_video(self.files) if not valid: messagebox.showerror( title="Invalid File", message="The File that you entered is invalid. Please retry!") return False return True def convert_video(self): """ convert_video Main video converter function Uses OpenCV to read and write the video While skipping frames based on the given input Returns: boolean: Returns True or False based on success or failure """ # Warning Box for if proper files have not been selected if not self.files: messagebox.showwarning( title="File Not Selected", message= "You have not selected any file. Please Click on \"Select Videos\"" ) return False # Extract the multiplier number fps_multiplier = self.var_open_files.get() if not fps_multiplier: return False # If invalid multiplier selected, raise warning try: fps_multiplier = int(fps_multiplier[:-1]) except Exception as e: messagebox.showwarning( title="Select Speed", message= "Please Select Speed of the video from the dropdown menu") return True # Disable the button during converstion to avoid multiple inputs self.btn_convert["state"] = "disabled" # Start the main conversion in a different thread to avoid UI freeze _thread.start_new_thread(bulk_video_converter, (self.files, fps_multiplier, None, self.file_status, self.file_status_percent, self.progress, self.root, self.btn_convert))
for r in data: workout_line = r.split(",") if workout_line[1] == "" or workout_line[1] == 0: workout_line[1] = "1" Rept_text.append(workout_line[1]) Dist_text.append(workout_line[2]) Ti_text.append(workout_line[3]) Remarks_text.append(workout_line[4].rstrip('\n')) print("Display workout") # Display workout set_label.append("X") SetsFrame = Frame(root, bg="blue") SetsFrame.grid(row=0, column=0, rowspan=2, sticky='nswe') SetsFrame.rowconfigure(0, weight=1) SetsFrame.columnconfigure(0, weight=1) SetsCanvas = Canvas(SetsFrame, width=400, height=screen_height - 260, bg="blue") SetsCanvas.grid(row=0, column=0, sticky='nswe') canvasFrame = Frame(SetsCanvas, bg="blue") SetsCanvas.create_window(0, 0, window=canvasFrame, anchor="nw") for row in range(1, num_of_sets + 1): l = Label(canvasFrame, text=set_display(row) + "\n" + Remarks_text[row], justify=LEFT,
class ScrolledFrame(Frame): """This widget behaves like a tkFrame widget with scrollbars. The scrollbars can be on any 2 edges of the widget, and can automatically disappear when not needed. Configuration options are passed to the <class> widget, along with most method calls; however, geometry methods are redirected to the <container> widget. Attributes ---------- container : tkFrame The outermost widget. Contains the <scroll_canvas>, <scrollbar_v>, and <scrollbar_h> widgets scroll_canvas : tkCanvas The Canvas widget that allows scrolling. Contains the <class> widget scrollbar_v : tkScrollbar The vertical Scrollbar widget scrollbar_h : tkScrollbar The horizontal Scrollbar widget <class> : tkFrame The Frame widget that will hold all child widgets dohide : bool Whether to hide the scrollbars when not needed doupdate : bool Whether to automatically redraw the widget whenever it's resized scrollspeed : int The number of lines to scroll by. 0 disables mousewheel scrolling Methods ------- redraw() -> None Updates the widget's scroll-area and (un)hide the scrollbars Any <tkFrame> methods """ __padding: tuple[int, int, int, int] __BG: str __CURSOR: str dohide: bool doupdate: bool scrollspeed: int scrollbar_h: O[Scrollbar] scrollbar_v: O[Scrollbar] __showVScroll: bool __showHScroll: bool __allChildren: set[Widget] __sfc: str __sbX: str __sbY: str __mainWinId: int def __init__(self, master: O[Widget] = None, scrollbars: str = 'SE', dohide: bool = True, padding: U[int, tuple[int], list[int]] = (3, 0, 0, 3), doupdate: bool = True, scrollspeed: int = 2, **kwargs): """\ Parameters ---------- master : tkWidget, optional (default is tkTk) The parent widget scrollbars : str, optional (default is "SE") Where to put the scrollbars padding : int | sequence[int] where len=(2 or 4), optional (default is (3, 0, 0, 3)) Padding around the scroll_canvas widget dohide : bool, optional (default is True) Whether to hide the scrollbars when not needed doupdate : bool, optional (default is True) Whether to automatically redraw the widget whenever it's resized scrollspeed : int, optional (default is 2) The number of lines to scroll by. 0 disables mousewheel scrolling **kwargs : keyword arguments, optional Any additional tkFrame parameters """ self.__validateVars(padding, scrollbars) # set var defaults if not specified kwargs.update(bd=kwargs.pop('borderwidth', kwargs.pop('bd', 2)), relief=kwargs.pop('relief', 'ridge'), width=kwargs.pop('width', 300), height=kwargs.pop('height', 200)) # set initial values self.__BG = (kwargs.get('background') or kwargs.get('bg', 'SystemButtonFace')) self.__CURSOR = kwargs.get('cursor', '') self.dohide = dohide self.doupdate = doupdate self.scrollspeed = scrollspeed self.scrollbar_h = None self.scrollbar_v = None self.__showVScroll = False self.__showHScroll = False self.__allChildren = set() # create widget self.__createContainer(master, kwargs) self.__sfc = f'{self.container.winfo_id()}_children' self.__createScrollFrame() self.redraw() if doupdate: self.container.bind(sequence='<Configure>', func=self.redraw) # Pass geometry methods to container def meths(cls): return vars(cls).keys() all_frame_methods = meths(Frame) all_geo_methods = meths(Pack) | meths(Grid) | meths(Place) geo_methods = all_geo_methods.difference(all_frame_methods) for method in geo_methods: if not re_search(r'^_|config|slaves|propagate|location', method): setattr(self, method, getattr(self.container, method)) def __validateVars(self, pad: U[int, list, tuple], sbars: str) -> None: # validate padding errmsg_pad = ("the <padding> parameter must be either an integer " "(pad_ALL) or a sequence of 2 (pad_NS, pad_EW) or 4 " "(pad_N, pad_E, pad_S, pad_W) integers") if not isinstance(pad, (int, list, tuple)): raise TypeError(errmsg_pad) elif isinstance(pad, int): self.__padding = tuple([pad] * 4) else: if len(pad) not in [2, 4] or False in [isinstance(n, int) for n in pad]: raise ValueError(errmsg_pad) else: self.__padding = tuple(pad if len(pad) == 4 else (pad * 2)) # validate scrollbars errmsg_sbar = ('the <scrollbars> parameter must be a combination of ' 'up to 2 non-opposing strings from the following: ' '("N"="T"=North | "S"="B"=South), ("E"="R"=East | "W"="L"=West)') if not isinstance(sbars, str): raise TypeError(errmsg_sbar) sbs = sbars.upper() repl = sbs.maketrans('TBRL', 'NSEW') s = sbs.translate(repl) if re_search(r'^[NS](?:$|[EW]$)|^[EW](?:$|[NS]$)', s): self.__sbX = ''.join(set('NS') & set(s)) self.__sbY = ''.join(set('EW') & set(s)) else: raise ValueError(errmsg_sbar) def __createContainer(self, master: Widget, kwargs: dict) -> None: # create the container that holds everything self.container = Frame(master=master, **kwargs) self.container.grid_propagate(0) self.container.rowconfigure(1 if self.__sbX == 'N' else 0, weight=1) self.container.columnconfigure(1 if self.__sbY == 'W' else 0, weight=1) def __createScrollFrame(self) -> None: pad_n, pad_e, pad_s, pad_w = self.__padding # create the canvas that holds the scrolled window self.scroll_canvas = Canvas(master=self.container, highlightthickness=0, bg=self.__BG, cursor=self.__CURSOR) self.scroll_canvas.grid(column=(1 if self.__sbY == 'W' else 0), row=(1 if self.__sbX == 'N' else 0), sticky='nsew', padx=(pad_w, pad_e), pady=(pad_n, pad_s)) # create the scrolled window Frame.__init__(self, master=self.scroll_canvas, background=self.__BG, cursor=self.__CURSOR) # create scrollbars if self.__sbY: self.scrollbar_v = Scrollbar(master=self.container, orient='vertical', command=self.scroll_canvas.yview) self.scrollbar_v.grid(column=(0 if self.__sbY == 'W' else 1), row=(1 if self.__sbX == 'N' else 0), sticky='ns') self.scroll_canvas.configure(yscrollcommand=self.scrollbar_v.set) self.__showVScroll = True if self.__sbX: self.scrollbar_h = Scrollbar(master=self.container, orient='horizontal', command=self.scroll_canvas.xview) self.scrollbar_h.grid(column=(1 if self.__sbY == 'W' else 0), row=(0 if self.__sbX == 'N' else 1), sticky='ew') self.scroll_canvas.configure(xscrollcommand=self.scrollbar_h.set) self.__showHScroll = True # create the window self.__mainWinId = self.scroll_canvas.create_window(0, 0, anchor='nw', window=self) def __bindScroll(self, func: C) -> None: def scrollView(e: Event): val = (self.scrollspeed * (-1 if e.delta > 0 else 1)) func(val, 'units') self.bind_class(className=self.__sfc, sequence='<MouseWheel>', func=scrollView) def __updateScrolling(self, sbars: str) -> None: if self.scrollbar_v and 'v' in sbars: # there is a vert scrollbar and it needs to be updated if self.__showVScroll: # the vScroll is needed self.scrollbar_v.grid() if self.scrollspeed: # bind scroll to the vScroll self.__bindScroll(self.scroll_canvas.yview_scroll) else: # the vScroll isn't needed self.scroll_canvas.yview_moveto(0) if self.dohide: # hide the vScroll self.scrollbar_v.grid_remove() if self.scrollspeed and self.__showHScroll and 'h' not in sbars: # there is a horz scrollbar and it won't be updated otherwise self.__bindScroll(self.scroll_canvas.xview_scroll) if self.scrollbar_h and 'h' in sbars: # there is a horz scrollbar and it needs to be updated if self.__showHScroll: # the hScroll is needed self.scrollbar_h.grid() if self.scrollspeed and not self.__showVScroll: # there isn't a vert scrollbar, so bind the hScroll self.__bindScroll(self.scroll_canvas.xview_scroll) else: # the hScroll isn't needed self.scroll_canvas.xview_moveto(0) if self.dohide: self.scrollbar_h.grid_remove() if self.scrollspeed and not self.__showVScroll and not self.__showHScroll: # neither scrollbar is needed self.unbind_class(className=self.__sfc, sequence='<MouseWheel>') def __retag(self) -> None: # recurse through all children of widget and add the custom class tag c = [self.container] for w in c: c.extend(w.winfo_children()) curChildren = set(c) newWidgets = curChildren.difference(self.__allChildren) for w in newWidgets: w.bindtags((self.__sfc,) + w.bindtags()) self.__allChildren = curChildren def redraw(self, _=None) -> None: self.__retag() self.update_idletasks() reqWd = self.winfo_reqwidth() scrCnvWd = self.scroll_canvas.winfo_width() reqHt = self.winfo_reqheight() scrCnvHt = self.scroll_canvas.winfo_height() rebind = str() # check if the window is wider than the container iswide = scrCnvWd < reqWd # update horz scroll if it exists and is in the wrong state if self.scrollbar_h and ((iswide and not self.__showHScroll) or (not iswide and self.__showHScroll)): self.__showHScroll = not self.__showHScroll rebind += 'h' # check if the window is taller than the container istall = scrCnvHt < reqHt # update vert scroll if it exists and is in the wrong state if self.scrollbar_v and ((istall and not self.__showVScroll) or (not istall and self.__showVScroll)): self.__showVScroll = not self.__showVScroll rebind += 'v' # update the scrollbars if necessary if rebind: self.__updateScrolling(rebind) # update the window with the new sizes self.scroll_canvas.configure(scrollregion=(0, 0, reqWd, reqHt)) self.scroll_canvas.itemconfigure(tagOrId=self.__mainWinId, width=max(reqWd, scrCnvWd), height=max(reqHt, scrCnvHt)) self.update_idletasks() def configure(self, **kwargs) -> None: # intercept configure commands kw = dict() bg = kwargs.get('background', kwargs.get('bg')) if bg: # get requested background kw['bg'] = self.__BG = bg cur = kwargs.get('cursor') if cur: # get requested cursor kw['cursor'] = self.__CURSOR = cur if kw: # update config for sub-widgets self.container.configure(**kw) self.scroll_canvas.configure(**kw) # update config for main widget Frame.configure(self, **kwargs) config = configure def destroy(self) -> None: Frame.destroy(self) self.container.destroy()
def initialize_tree(self): """Draw a user interface allowing interaction with tree items - insert, select, add sub-comment """ self.parent.title("Treeview Example") self.parent.grid_rowconfigure(0, weight=1) self.parent.grid_columnconfigure(0, weight=1) self.parent.config(background="coral") '''create a subframe to isolate the upper button/entry widget grid from the lower table view ''' topbuttonframe = Frame(self.parent) ''' note grid_columnconfigure() sets the relative weight of each of the columns 0..3 without these calls, the default button spacing without these is usually not visually well balanced ''' topbuttonframe.grid_columnconfigure(0, weight=1) topbuttonframe.grid_columnconfigure(1, weight=3) topbuttonframe.grid_columnconfigure(2, weight=1) topbuttonframe.grid_columnconfigure(3, weight=1) topbuttonframe.config(background="yellow") topbuttonframe.columnconfigure(0, weight=1) topbuttonframe.rowconfigure(0, weight=1) topbuttonframe.grid(row=0,column=0,rowspan=4,columnspan=10,sticky=W+E) me = topbuttonframe # Define the different GUI widgets self.dose_label = Tkinter.Label(me, text="TopItem1") self.dose_entry = Tkinter.Entry(me) self.dose_label.grid(row=0, column=0, sticky=E+W) self.dose_entry.grid(row=0, column=1, sticky=E+W) self.modified_label = Tkinter.Label(me, text="TopItem2") self.modified_entry = Tkinter.Entry(me) self.modified_label.grid(row=1, column=0, sticky=E+W) self.modified_entry.grid(row=1, column=1, sticky=E+W) self.comment_label = Tkinter.Label(me, text="SubItem1") self.comment_entry = Tkinter.Entry(me) self.comment_label.grid(row=2, column=0, sticky=E+W) self.comment_entry.grid(row=2, column=1, sticky=E+W) self.submit_button = Tkinter.Button(me, text="InsertTop", command=self.insert_data) self.submit_button.grid(row=1, column=3, sticky=Tkinter.W) self.submit_button = Tkinter.Button(me, text="InsertSubnode", command=self.insert_comment) self.submit_button.grid(row=2, column=3, sticky=Tkinter.W) # Set the treeview self.tree = ttk.Treeview(self.parent, columns=('Item1', 'Item2')) self.tree.heading('#0', text='Item1') self.tree.heading('#1', text='Item2') self.tree.heading('#2', text='SubItem') self.tree.column('#1', stretch=Tkinter.YES) self.tree.column('#2', stretch=Tkinter.YES) self.tree.column('#0', stretch=Tkinter.YES) self.tree.grid(row=4, columnspan=4, sticky=N+W+E+W) self.treeview = self.tree # Initialize the counter self.i = 0 # self.tree.bind("<Button-1>", self.OnClick) self.tree.bind("<<TreeviewSelect>>", self.OnSelChange) self.tree.bind("<Button-3>", self.OnRtClick) self.tree.bind("<Double-1>", self.OnDoubleClick) self.mg_setentrytext(self.dose_entry,'D%02d_'%(self.i)+datetime.now().strftime("%H-%M-%S")) #%Y-%m-%d- self.mg_setentrytext(self.modified_entry,'M_01'+datetime.now().strftime("%H-%M-%S")) self.mg_setentrytext(self.comment_entry,'C00_'+datetime.now().strftime("%H-%M-%S")) self.exit_button = Tkinter.Button(self.parent, text="Exit", command=self.parent.quit) self.exit_button.grid(row=15, column=3)
def create_window(self, master, conf): master.geometry('700x500') frame = Frame(master) frame.config(bg='black') master.title('SZA-SAR') frame.pack(fill=BOTH, expand=True) fr_config = Frame(frame, bg='black', borderwidth=1, highlightbackground='white', relief=FLAT) fr_config.grid(row=0, column=0, padx=5, pady=1, sticky=W + E) image = Image.open(conf['icon']).resize((40, 40), Image.ANTIALIAS) self.image = ImageTk.PhotoImage(image) self.lbl_image = Label(fr_config, image=self.image) self.lbl_image.grid(row=0, column=0, rowspan=3, padx=5, pady=5, sticky=W) self.username = StringVar() self.server = StringVar() self.port = StringVar() self.lbl_username = Label(fr_config, text='User', bg='black', fg='red') self.lbl_username.grid(row=0, column=1, padx=5, pady=1, sticky=W) self.lbl_server = Label(fr_config, text='Server', bg='black', fg='red') self.lbl_server.grid(row=1, column=1, padx=5, pady=1, sticky=W) self.lbl_port = Label(fr_config, text='Port', bg='black', fg='red') self.lbl_port.grid(row=2, column=1, padx=5, pady=1, sticky=W) self.txt_username = Entry(fr_config, textvariable=self.username, bg='black', fg='red', width=10) self.txt_username.grid(row=0, column=2, padx=5, pady=1, sticky=W) self.txt_server = Entry(fr_config, textvariable=self.server, bg='black', fg='red', width=10) self.txt_server.grid(row=1, column=2, padx=5, pady=1, sticky=W) self.txt_port = Entry(fr_config, textvariable=self.port, bg='black', fg='red', width=10) self.txt_port.grid(row=2, column=2, padx=5, pady=1, sticky=W) self.username.set(conf['username']) self.server.set(conf['server']) self.port.set(conf['port']) frame.columnconfigure(1, weight=1) frame.rowconfigure(1, weight=1) fr_features = Frame(frame) fr_features.config(bg='black') fr_features.grid(row=4, column=0, columnspan=1, sticky=W + E, pady=2, padx=5) self.lbl_file = Label(fr_features, font='Helvetica 9 bold') self.lbl_cen = Label(fr_features, font='Helvetica 9 bold') self.lbl_nop = Label(fr_features, font='Helvetica 9 bold') self.lbl_tls = Label(fr_features, font='Helvetica 9 bold') self.lbl_file.grid(row=0, column=0, columnspan=1, sticky=W + E, pady=2, padx=5) self.lbl_file.config(bg='black', fg='white') self.lbl_cen.grid(row=0, column=1, columnspan=1, sticky=W + E, pady=2, padx=5) self.lbl_cen.config(bg='black', fg='white') self.lbl_nop.grid(row=0, column=2, columnspan=1, sticky=W + E, pady=2, padx=5) self.lbl_nop.config(bg='black', fg='white') self.lbl_tls.grid(row=0, column=3, columnspan=1, sticky=W + E, pady=2, padx=5) self.lbl_tls.config(bg='black', fg='white') fr_info = Frame(frame, bg='black', borderwidth=1, relief=FLAT) fr_info.grid(row=0, column=1, columnspan=2, padx=5, pady=1, sticky=W + E) self.info = StringVar() self.lbl_info = Label(fr_info, textvariable=self.info, width=80, anchor='w') self.lbl_info.grid(row=0, column=0, pady=2, padx=5) self.lbl_info.config(background='gray13', fg='white') self.debug_info = StringVar() self.lbl_debug = Label(fr_info, textvariable=self.debug_info, width=80, anchor='w') self.lbl_debug.grid(row=1, column=0, sticky=W + E, pady=2, padx=5) self.lbl_debug.config(background='black', fg='black') fr_buttons = Frame(frame, bg='black', borderwidth=1, background='black', relief=FLAT) fr_buttons.grid(row=0, column=3, columnspan=1, padx=5, pady=1, sticky=W + E) self.bt_connect = Button(fr_buttons, text='Connect', width=5, command=self.open_connection) self.bt_connect.grid(row=0, column=0, sticky=E, pady=2, padx=5) self.bt_connect.config(relief=FLAT, bg='gray13', fg='white', borderwidth=0, highlightthickness=0) self.bt_config = Button(fr_buttons, text='Conf', width=5, command=self.config_window) self.bt_config.grid(row=1, column=0, sticky=W + E, pady=2, padx=5) self.bt_config.config(relief=FLAT, bg='gray13', fg='white', borderwidth=0, highlightthickness=0) self.bt_debug = Button(fr_buttons, text='Debug', width=5, command=self.toggle_debug) self.bt_debug.grid(row=0, column=1, sticky=E, pady=2, padx=0) self.bt_debug.config(relief=FLAT, bg='gray13', activeforeground='white', fg='white', borderwidth=0, highlightthickness=0) self.bt_close = Button(fr_buttons, text='Close', width=5, command=self.close) self.bt_close.grid(row=1, column=1, sticky=W + E, pady=2, padx=0) self.bt_close.config(relief=FLAT, bg='gray13', fg='white', borderwidth=0, highlightthickness=0) self.lb_users = Listbox(frame) self.lb_users.grid(row=1, column=0, rowspan=3, pady=5, padx=5, sticky=S + N + E + W) self.lb_users.config(bg='gray18', borderwidth=1, highlightbackground='gray15', highlightthickness=1, fg='white', relief='solid') self.txt_chat = scrolledtext.ScrolledText(frame) self.txt_chat.grid(row=1, column=1, columnspan=3, rowspan=3, pady=5, padx=5, sticky=E + W + S + N) self.txt_chat.config(bg='gray18', borderwidth=0, highlightbackground='gray15', highlightthickness=1, relief='solid', padx=10, pady=5, font=('', 10)) self.txt_chat.vbar.config(troughcolor='black', bg='gray18') self.txt_chat.tag_config('sender', background='gray30', foreground='brown1', justify=RIGHT, font=('Bold', 10)) self.txt_chat.tag_config('username', background='gray30', foreground='olive drab', justify=LEFT, font=('Bold', 10)) self.txt_chat.tag_config('timestamp', background='gray30', foreground='black', justify=RIGHT, font=('Bold', 8)) self.txt_chat.tag_config('message', background='gray30', foreground='white', justify=RIGHT, font=('Bold', 10)) self.txt_chat.tag_config('file', background='red4', foreground='white', justify=RIGHT, font=('Bold', 10)) self.txt_chat.tag_config('newline', background='gray18', foreground='gray18', justify=RIGHT, font=('Bold', 4)) self.txt_chat.config(state=DISABLED) self.txt_msg = Entry(frame) self.txt_msg.grid(row=4, column=1, rowspan=1, columnspan=1, sticky=E + W + S + N, padx=5, pady=2) self.txt_msg.config(bg='gray13', fg='white', borderwidth=0, highlightthickness=0, insertbackground='white', state=DISABLED) self.txt_msg.bind('<Key>', self.key_pressed) self.txt_msg.bind('<FocusIn>', self.enable_send) self.txt_msg.bind('<FocusOut>', self.disable_send) self.txt_msg.bind('<Return>', self.send_message) fr_buttons_send = Frame(frame, bg='black', borderwidth=1, background='black', relief=FLAT) fr_buttons_send.grid(row=4, column=2, columnspan=2, padx=5, pady=1, sticky=W + E) self.bt_send = Button(fr_buttons_send, text='Send', width=5, command=self.send_message) self.bt_send.grid(row=0, column=0, sticky=E + W, pady=0, padx=5) self.bt_send.config(relief=FLAT, bg='gray13', fg='white', borderwidth=0, highlightthickness=0, state=DISABLED) self.bt_file = Button(fr_buttons_send, text='File', width=5, command=self.send_file) self.bt_file.grid(row=0, column=1, sticky=E + W, pady=0, padx=0) self.bt_file.config(relief=FLAT, bg='gray13', fg='white', borderwidth=0, highlightthickness=0, state=DISABLED) master.protocol('WM_DELETE_WINDOW', self.close)
class MainWindow: """ Class representing the main window, hence the user interface of the application. | Places all UI elements, in the right place, and connects necessary events to the corresponding handler. | Constantly updates the UI based on the given states received from the controller. .. note :: Tkinter | This class does not need any external dependency for the UI, instead it uses | the built-in Tkinter library .. attribute:: window The main window of the application .. attribute:: dial The dialog window responsible for the connection .. attribute:: channel A Channel object, which is responsible for the communication between this application, and the controller. :var: FILL :var: MIN_SIZE :var: WEIGHT :var: BACKGROUND_COLOR :var: ACTIVE_ARROW_COLOR :var: DISTANCE_TEXT :var: DISTANCE_MES :var: DISTANCE_LEN :var: SPEED_TEXT :var: SPEED_MES :var: SPEED_LEN :var: LEFT_INDICATOR_TEXT :var: RIGHT_INDICATOR_TEXT :var: HAZARD_WARNING_TEXT :var: LIGHTS_SWITCH_TEXT :var: FORWARD_ARROW_TEXT :var: BACK_ARROW_TEXT :var: LEFT_ARROW_TEXT :var: RIGHT_ARROW_TEXT :var: HORN_TEXT :var: REVERSE_SWITCH_TEXT """ FILL = 'nesw' MIN_SIZE = 100 WEIGHT = 1 BACKGROUND_COLOR = '#87edfa' ACTIVE_ARROW_COLOR = '#ffb2f4' DISTANCE_TEXT = 'Distance: ' DISTANCE_MES = 'cm' DISTANCE_LEN = len(DISTANCE_TEXT) SPEED_TEXT = 'Speed: ' SPEED_MES = 'm/s' SPEED_LEN = len(SPEED_TEXT) LEFT_INDICATOR_TEXT = 'тоИ' RIGHT_INDICATOR_TEXT = 'тоК' HAZARD_WARNING_TEXT = 'тЪа' LIGHTS_SWITCH_TEXT = 'ЁЯФж' FORWARD_ARROW_TEXT = 'тоЭ' BACK_ARROW_TEXT = 'тоЯ' LEFT_ARROW_TEXT = 'тоЬ' RIGHT_ARROW_TEXT = 'тоЮ' HORN_TEXT = 'ЁЯУп' REVERSE_SWITCH_TEXT = 'R' def __init__(self): """Initializing the main window""" self.window = Tk() self.window.columnconfigure(0, weight=self.WEIGHT) self.window.rowconfigure(0, weight=self.WEIGHT) self.window.protocol('WM_DELETE_WINDOW', self.__on_close_event) self.__handle_labels_layout() self.__handle_light_button_layout() self.__handle_move_button_layout() self.dial = ConnectionDialog(self.window) self.__connect_on_top = True self.window.after(100, self.__ensure_connect_on_top) self.window.wait_window(self.dial.top) self.__connect_on_top = False # tmp!!!!! TODO: self.channel = Channel('192.168.1.11', 8000 + int(self.dial.port), '69420') # self.channel = Channel(self.dial.host, self.dial.port, self.dial.password) self.switcher = self.__create_switcher() self.__key_event_modifier = defaultdict(bool) self.__ctrl_pressed = False self.window.bind('<KeyPress>', self.__on_key_press_event) self.window.bind('<KeyRelease>', self.__on_key_release_event) self.__continue_update = True self.window.after(10, self.__upadte_widgets) self.window.mainloop() def __on_close_event(self) -> None: """ Function that handles the user clicked exit event. * The channel with the controller itself should be closed properly, before exiting the application. * The UI updating thread should be stopped :Assumptions: None :return: None """ self.channel.set_value(self.channel.DISTANCE_KEEPING, False) self.channel.set_value(self.channel.LINE_FOLLOWING, False) self.__continue_update = False self.channel.deactivate() self.window.destroy() def __ensure_connect_on_top(self): if self.__connect_on_top: self.dial.top.lift() self.window.after(100, self.__ensure_connect_on_top) def __handle_labels_layout(self) -> None: """ Creates, and manages the layout for the labels, such as the distance label, speed label, and the follow the line label :Assumptions: None :return: """ self.label_layout = Frame(master=self.window) self.label_layout.rowconfigure(0, weight=self.WEIGHT, minsize=self.MIN_SIZE) for i in range(3): self.label_layout.columnconfigure(i, weight=self.WEIGHT, minsize=self.MIN_SIZE) self.label_layout.grid(row=0, column=0, sticky=self.FILL) self.distance_label = Label(master=self.label_layout, text=self.DISTANCE_TEXT, background=self.BACKGROUND_COLOR) self.distance_label.grid(row=0, column=0, sticky=self.FILL) self.line_label = Label(master=self.label_layout, background='white') self.line_label.grid(row=0, column=1, sticky=self.FILL) self.speed_label = Label(master=self.label_layout, text=self.SPEED_TEXT, background=self.BACKGROUND_COLOR) self.speed_label.grid(row=0, column=2, sticky=self.FILL) def __handle_light_button_layout(self) -> None: """ Creates, and manages the layout for the buttons, such as the light, and hazard warning switch, and the indicators :Assumptions: None :return: None """ self.lights_layout = Frame(master=self.window) self.lights_layout.rowconfigure(0, weight=self.WEIGHT, minsize=self.MIN_SIZE) for i in range(3): self.lights_layout.columnconfigure(i, weight=self.WEIGHT, minsize=self.MIN_SIZE) self.lights_layout.grid(row=1, column=0, sticky=self.FILL) self.left_indicator = Button( master=self.lights_layout, text=self.LEFT_INDICATOR_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.L_INDICATOR, not self.channel.get_value( self.channel.L_INDICATOR))) self.left_indicator.grid(row=0, column=0, sticky=self.FILL) self.right_indicator = Button( master=self.lights_layout, text=self.RIGHT_INDICATOR_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.R_INDICATOR, not self.channel.get_value( self.channel.R_INDICATOR))) self.right_indicator.grid(row=0, column=2, sticky=self.FILL) self.middle_light_frame = Frame(master=self.lights_layout) self.middle_light_frame.columnconfigure(0, weight=self.WEIGHT) self.middle_light_frame.rowconfigure(0, weight=self.WEIGHT) self.middle_light_frame.rowconfigure(1, weight=self.WEIGHT) self.middle_light_frame.grid(row=0, column=1, sticky=self.FILL) self.hazard_warning = Button( master=self.middle_light_frame, text=self.HAZARD_WARNING_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.HAZARD_WARNING, not self.channel.get_value( self.channel.HAZARD_WARNING))) self.hazard_warning.grid(row=0, column=0, sticky=self.FILL) self.light_switch = Button(master=self.middle_light_frame, text=self.LIGHTS_SWITCH_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.LIGHTS, not self.channel. get_value(self.channel.LIGHTS))) self.light_switch.grid(row=1, column=0, sticky=self.FILL) def __handle_move_button_layout(self) -> None: """ Creates, and manages the layout for the buttons, such as the arrows, the reverse switch, and the horn :Assumptions: None :return: None """ self.button_layout = Frame(master=self.window) self.button_layout.rowconfigure(0, weight=self.WEIGHT, minsize=self.MIN_SIZE) self.button_layout.rowconfigure(1, weight=self.WEIGHT, minsize=self.MIN_SIZE) for i in range(3): self.button_layout.columnconfigure(i, weight=self.WEIGHT, minsize=self.MIN_SIZE) self.button_layout.grid(row=2, column=0, sticky=self.FILL) self.reverse_button = Button(master=self.button_layout, text=self.REVERSE_SWITCH_TEXT, foreground='red', background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.REVERSE, not self.channel .get_value(self.channel.REVERSE))) self.reverse_button.grid(row=0, column=0, sticky=self.FILL) self.horn_button = Button(master=self.button_layout, text=self.HORN_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.HORN, not self.channel. get_value(self.channel.HORN))) self.horn_button.grid(row=0, column=2, sticky=self.FILL) self.forward_button = Button(master=self.button_layout, text=self.FORWARD_ARROW_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.FORWARD, not self.channel .get_value(self.channel.FORWARD))) self.forward_button.grid(row=0, column=1, sticky=self.FILL) self.backward_button = Button( master=self.button_layout, text=self.BACK_ARROW_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.BACKWARD, not self.channel.get_value(self.channel. BACKWARD))) self.backward_button.grid(row=1, column=1, sticky=self.FILL) self.left_button = Button(master=self.button_layout, text=self.LEFT_ARROW_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.LEFT, not self.channel. get_value(self.channel.LEFT))) self.left_button.grid(row=1, column=0, sticky=self.FILL) self.right_button = Button(master=self.button_layout, text=self.RIGHT_ARROW_TEXT, background=self.BACKGROUND_COLOR, command=lambda: self.channel.set_value( self.channel.RIGHT, not self.channel. get_value(self.channel.RIGHT))) self.right_button.grid(row=1, column=2, sticky=self.FILL) def __create_switcher(self): """ Create the switcher object, for the key events, so implementing a switch case is possible, without creating a new object every time a key is pressed :Assumptions: * The Channel object have been created, before this method is called :return: the switcher object """ return defaultdict( lambda: 'None', { 65362: self.channel.FORWARD, 119: self.channel.FORWARD, 65364: self.channel.BACKWARD, 115: self.channel.BACKWARD, 65361: self.channel.LEFT, 97: self.channel.LEFT, 65363: self.channel.RIGHT, 100: self.channel.RIGHT, 98: self.channel.HORN, 108: self.channel.LIGHTS, 104: self.channel.HAZARD_WARNING, 114: self.channel.REVERSE, 113: self.channel.L_INDICATOR, 101: self.channel.R_INDICATOR }) def __on_key_press_event(self, event: Event) -> None: """ Handles the event, when the user presses a key :Assumption: * This method should only be called from the Tkinter main loop :param event: Contains the events object :return: None """ mod_switcher = defaultdict(lambda: 'None', { 100: self.channel.DISTANCE_KEEPING, 108: self.channel.LINE_FOLLOWING }) case = self.switcher[event.keysym_num] if event.keysym_num in [65507, 65508 ] and not self.__key_event_modifier['Ctrl']: self.__key_event_modifier['Ctrl'] = True self.__ctrl_pressed = True elif self.__ctrl_pressed and event.keysym_num not in [65507, 65508]: self.channel.set_value( mod_switcher[event.keysym_num], not self.channel.get_value(mod_switcher[event.keysym_num])) elif not self.__ctrl_pressed and event.keysym_num in [ 101, 104, 108, 113, 114 ]: self.channel.set_value(case, not self.channel.get_value(case)) elif not self.__ctrl_pressed and not self.__key_event_modifier[ case] and event.keysym_num not in [65507, 65508]: self.channel.set_value(case, True) self.__key_event_modifier[case] = True
def __init__(self, parent, controller): Frame.__init__(self, parent) self.controller = controller KOPTIONS = ["1024 bits", "2048 bits", "4096 bits"] self.columnconfigure(0) self.columnconfigure(1, weight=1) self.rowconfigure(0, pad=5) self.rowconfigure(1, pad=5) self.rowconfigure(2, weight=1, pad=5) self.rowconfigure(3, pad=5) self.rowconfigure(4, pad=5) self.rowconfigure(5, pad=5) self.rowconfigure(6, pad=5) self.rowconfigure(7, pad=5) # Title bbutton = Button(self, text="<", command=lambda: controller.show_frame("MainPage")) bbutton.grid(row=0, column=0, padx=10, sticky=W) title = Label(self, text="RSA Key Generator") title.grid(row=0, columnspan=2, padx=10) # Key length kframe = Frame(self) klength_label = Label(kframe, text="Key Length") klength_label.pack(side=LEFT) kselect = StringVar(self) kselect.set(KOPTIONS[0]) # default value koption = OptionMenu(kframe, kselect, *KOPTIONS) koption.pack(side=LEFT, padx=10) koption.configure(width=40) gbutton = Button(kframe, text="Generate", width=15) gbutton.pack(side=LEFT, padx=10) gbutton.configure(command=lambda: self.generate(kselect.get())) kframe.grid(row=1, columnspan=2, padx=10, pady=5, sticky=E + W + N) # Result key frame keyframe = Frame(self) keyframe.columnconfigure(0, weight=1, pad=5) keyframe.columnconfigure(1, pad=5) keyframe.columnconfigure(2, weight=1, pad=5) keyframe.rowconfigure(0, pad=5) keyframe.rowconfigure(1, weight=1, pad=5) # Box labels pub_label = Label(keyframe, text="Public Key") pub_label.grid(row=0, column=0, padx=10, sticky=W) priv_label = Label(keyframe, text="Private Key") priv_label.grid(row=0, column=2, sticky=W) # Public key box self.pub_output = Text(keyframe, wrap=WORD) self.pub_output.grid(row=1, column=0, padx=10, pady=10, sticky=N + E + S + W) self.pub_output.bind("<1>", lambda event: self.pub_output.focus_set()) scrolli = Scrollbar(keyframe, command=self.pub_output.yview) self.pub_output.configure(yscrollcommand=scrolli.set) scrolli.grid(row=1, column=0, pady=10, sticky=N + S + E) self.pub_output.configure(state="disabled") self.pub_output.bind("<Control-Key-a>", select_all) # select-all Windows/Linux self.pub_output.bind("<Command-Key-a>", select_all) # select-all Mac # Private key box self.priv_output = Text(keyframe, wrap=WORD) self.priv_output.grid(row=1, column=2, padx=10, pady=10, sticky=N + E + S + W) self.priv_output.bind("<1>", lambda event: self.priv_output.focus_set()) scrolli = Scrollbar(keyframe, command=self.priv_output.yview) self.priv_output.configure(yscrollcommand=scrolli.set) scrolli.grid(row=1, column=2, pady=10, sticky=N + S + E) self.priv_output.configure(state="disabled") self.priv_output.bind("<Control-Key-a>", select_all) # select-all Windows/Linux self.priv_output.bind("<Command-Key-a>", select_all) # select-all Mac keyframe.grid(row=2, columnspan=2, pady=5, sticky=E + W + N + S) plabel = Label(self, text="p") plabel.grid(row=3, column=0, padx=3, pady=3) self.p = Entry(self) self.p.grid(row=3, column=1, padx=10, pady=3, sticky=E + W) self.p.bind("<Control-Key-a>", select_all_entry) # select-all Windows/Linux self.p.bind("<Command-Key-a>", select_all_entry) # select-all Mac # q qlabel = Label(self, text="q") qlabel.grid(row=4, column=0, padx=3, pady=3) self.q = Entry(self) self.q.grid(row=4, column=1, padx=10, pady=3, sticky=E + W) self.q.bind("<Control-Key-a>", select_all_entry) # select-all Windows/Linux self.q.bind("<Command-Key-a>", select_all_entry) # select-all Mac # N Nlabel = Label(self, text="N") Nlabel.grid(row=5, column=0, padx=3, pady=3) self.N = Entry(self) self.N.grid(row=5, column=1, padx=10, pady=3, sticky=E + W) self.N.bind("<Control-Key-a>", select_all_entry) # select-all Windows/Linux self.N.bind("<Command-Key-a>", select_all_entry) # select-all Mac # e elabel = Label(self, text="e") elabel.grid(row=6, column=0, padx=3, pady=3) self.e = Entry(self) self.e.grid(row=6, column=1, padx=10, pady=3, sticky=E + W) self.e.bind("<Control-Key-a>", select_all_entry) # select-all Windows/Linux self.e.bind("<Command-Key-a>", select_all_entry) # select-all Mac # d dlabel = Label(self, text="d") dlabel.grid(row=7, column=0, padx=3, pady=3) self.d = Entry(self) self.d.grid(row=7, column=1, padx=10, pady=3, sticky=E + W) self.d.bind("<Control-Key-a>", select_all_entry) # select-all Windows/Linux self.d.bind("<Command-Key-a>", select_all_entry) # select-all Mac
class Interface(Frame): # Une classe qui hérite de la classe Frame """Inherited from tkinter.Frame class. Generate the search_engine's user interface. """ def __init__(self, master: object = None): super().__init__(master, width="13c", height="12c") self.grid_propagate(0) self.pack() self.rowconfigure(0, minsize=10) # BOUTON D'AUTHENTIFICATION # Frame parent self.auth_frame = Frame(self, width="13c", height="0.75c") self.auth_frame.grid_propagate(0) self.auth_frame.grid(row=1) self.auth_frame.columnconfigure(0, minsize="13c") # Bouton enfant self.Auth_btn = Button(self.auth_frame, text="Tester l'Authentification") self.Auth_btn.grid(column=0, row=0, sticky="ns") # LA ZONE DE RECHERCHE DE TEXTE LIBRE: # Frame Parent self.search_frame = Frame(self, width="13c", height="2c") self.search_frame.grid(row=2) self.search_frame.columnconfigure(0, minsize="13c") self.search_frame.rowconfigure(0, minsize="0.5c") self.search_frame.rowconfigure(2, minsize="0.5c") # Zone de texte enfant self.str_search = StringVar() self.search_box = Entry(self.search_frame, textvariable=self.str_search, width=70) #self.search_box = Entry(self.search_frame, width=70) self.search_box.grid(row=1) # LES FILTRES et LANCEMENT # Frame parent filtres self.filters_frame = Frame(self, width="13c", height="8c") self.filters_frame.grid_propagate(0) self.filters_frame.grid(row=3) filters_frame_grid = { "row0": "0.5c", "row2": "0.75c", "row4": "0.75c", "col0": "1c", "col2": "1.5c", "col4": "0.5c" } for dimension in filters_frame_grid: if dimension[0:3] == "row": self.filters_frame.rowconfigure( int(dimension[3]), minsize=filters_frame_grid[dimension]) else: self.filters_frame.columnconfigure( int(dimension[3]), minsize=filters_frame_grid[dimension]) # Frame parent Fournisseur self.fourn_frame = FilterFrame(self.filters_frame, field="Fournisseur") self.fourn_frame.grid(row=1, column=1) # Frame parent Groupe de travail self.grpTrav_frame = FilterFrame(self.filters_frame, field="Groupe de travail") self.grpTrav_frame.grid(row=1, column=3) # Frame parent Type self.type_frame = FilterFrame(self.filters_frame, field="Type") self.type_frame.grid(row=3, column=1) # Frame parent Mot-clef self.keyW_frame = FilterFrame(self.filters_frame, field="Mot-Clef") self.keyW_frame.grid(row=3, column=3) # Frame parent Format self.format_frame = FilterFrame(self.filters_frame, field="Format") self.format_frame.grid(row=5, column=1) # Frame parent Bouton Lancement self.resetBtn_frame = Frame(self.filters_frame, width="5.5c", height="2c") self.resetBtn_frame.grid_propagate(0) self.resetBtn_frame.grid(row=5, column=3) self.resetBtn_frame.rowconfigure(0, minsize="1c") self.resetBtn_frame.columnconfigure(0, minsize="4c") # Bouton enfant self.reset_btn = Button(self.resetBtn_frame, text="Reset", width=20) self.reset_btn.grid(row=1, column=0, sticky="w") #RESULTAT DE L'INVENTAIRE # Frame parent self.result_frame = Frame(self, width="13c", height="1c") self.result_frame.grid_propagate(0) self.result_frame.grid(row=4) self.result_frame.rowconfigure(0, minsize="0.5c") self.result_frame.columnconfigure(0, minsize="1c") # Texte enfant self.str_result = StringVar() self.str_result.set("0 métadonnées correspondantes") self.result_lbl = Label(self.result_frame, textvariable=self.str_result, justify="left") self.result_lbl.grid(column=1, row=1, sticky="w")
class mgSSDhealth(): def __init__(self, healthframe, healthdict): #super().__init__() # create a scrollable canvas to hold the buttons, labels, drawing canvases healthframe.grid_propagate(False) #healthframe.columnconfigure(0,minsize=750) #healthframe.rowconfigure(0,minsize=750) # thse minsize just push the canvas down on the main frame! NOT INTENDED ACTION self.canvas = Canvas(healthframe, bg='#FFFFFF', width=650, height=400, scrollregion=(0, 0, 100, 100)) self.scrollframe = Frame(self.canvas, bg="gray", width=400, height=450) self.scrollframe.grid(row=0, column=0, rowspan=1, columnspan=1, sticky="nsew") self.scrollframe.grid_propagate( True) #creates dynamic scrollable canvas size self.scrollframe.rowconfigure(0, weight=4) #,minsize=650) #self.scrollframe.rowconfigure(1,weight=1 ) #self.scrollframe.rowconfigure(2,weight=1 ) myscrollbary = Scrollbar(healthframe, orient="vertical", command=self.canvas.yview) myscrollbarx = Scrollbar(healthframe, orient="horizontal", command=self.canvas.xview) self.canvas.config(width=1250, height=1200) self.canvas.configure(yscrollcommand=myscrollbary.set, xscrollcommand=myscrollbarx.set) myscrollbary.grid(row=0, column=3, rowspan=5, sticky=N + S) #pack(side="right",fill="y") myscrollbarx.grid(row=4, column=0, columnspan=3, sticky=W + E) #pack(side="right",fill="y") self.canvas.grid( row=0, column=0, rowspan=4, columnspan=3 ) # this actually establishes the scrollable CANVAS size! #self.canvas.columnconfigure(0,minsize=550) #self.canvas.rowconfigure(0,minsize=550) self.canvas.grid_propagate(False) self.canvas.create_window((0, 0), window=self.scrollframe, anchor='nw') self.scrollframe.bind("<Configure>", self.myfunction) capacity = 1024 used = 157 self.drawpiechart(used, capacity, 0, 0) self.drawpiechart(400, capacity, 4, 1) self.drawpiechart(50, capacity, 7, 2) self.drawpiechart(5, capacity, 9, 3) capacity = 512 used = 256 self.drawpiechart(used, capacity, 0, 4) self.drawpiechart(400, capacity, 4, 5) self.drawpiechart(50, capacity, 7, 6) self.drawpiechart(5, capacity, 9, 7) #self.progress = Progressbar(self.infoframe, orient="horizontal", # length=200, mode="determinate") #self.progress.grid(row=1,column=2) #self.setprogress( 20000 ) maxbytes = 100 self.drawprogressrect(25, maxbytes, 8) self.drawprogressrect(50, 100, 9) self.drawprogressrect(80, 100, 10) self.drawprogressrect(90, 300, 11) self.drawprogressrect(18, 60, 12) def myfunction(self, event): self.canvas.configure(scrollregion=self.canvas.bbox("all"), width=650, height=480) #self._canvas.itemconfig(self._frame_id, height=e.height, width=e.width) def setprogress(self, currvalue): self.progress["value"] = currvalue self.maxbytes = 50000 self.progress["maximum"] = 50000 #self.read_bytes() def read_bytes(self): '''simulate reading 500 bytes; update progress bar''' self.bytes += 500 self.progress["value"] = self.bytes pass def drawbarchart(self): hostframe = self.summaryinfoframe x = Label(hostframe, text='Bar Chart') x.grid(row=4, column=1, columnspan=5) data = [21, 20, 19, 16, 14, 13, 11, 9, 4, 3] c_width = 53 * 10 c_height = 40 * 10 c = Canvas(self.scrollframe, width=c_width, height=c_height, bg='white') c.grid(row=5, column=1) c.grid_rowconfigure(4, weight=1) c.grid_columnconfigure(5, weight=3) #experiment with the variables below size to fit your needs y_stretch = 15 y_gap = 20 x_stretch = 10 x_width = 20 x_gap = 20 for x, y in enumerate(data): # calculate reactangle coordinates x0 = x * x_stretch + x * x_width + x_gap y0 = c_height - (y * y_stretch + y_gap) x1 = x * x_stretch + x * x_width + x_width + x_gap y1 = c_height - y_gap # Here we draw the bar c.create_rectangle(x0, y0, x1, y1, fill="red") c.create_text(x0 + 2, y0, anchor=tk.SW, text=str(y)) def drawprogressrect(self, current, max, segment): legendwid = 150 wid0 = (current / max * legendwid) wid1 = legendwid - wid0 baseX = 100 #10 baseY = 2 #+200*segment legendxy = (baseX, baseY, baseX + wid0, baseY + 19) legendxy1 = (baseX + wid0, baseY, baseX + wid0 + wid1, baseY + 19) legendtxt = (baseX, baseY + 20) legendtxt1 = (baseX + legendwid, baseY + 20) labeltxt1 = (baseX, baseY + 40) currpct = 100 * current / max x1 = Label(self.scrollframe, text='LABEL %02d%% free space' % (currpct), bg="green") x1.grid(row=1 + segment, column=3) #, sticky=C) x = Button(self.scrollframe, text='BUTTON %02d%% free space' % (currpct), bg="light grey") ##x.grid(row=rowval,column=0) #x.place(x = 20, y = baseY+30)#, width=120, height=25) x.grid(row=1 + segment, column=0) #, sticky=C) if True: c = Canvas(self.scrollframe, width=400, height=100) c.grid(row=1 + segment, column=1) c.grid_rowconfigure(1 + segment, weight=1) c.grid_columnconfigure(1, weight=1) warningzones = [(80, 'green2', 'Good'), (50, 'yellow', 'Worn'), (0, 'red', 'Low')] for i in warningzones: if currpct >= i[0]: healthcolor = i[1] healthstate = i[2] break c.create_rectangle(legendxy, fill=healthcolor) c.create_rectangle(legendxy1, fill="gray") c.create_text(legendtxt, anchor=tk.SW, text="%5d" % current, font='-*-helvetica-*-r-*-*-*-120-*-*-*-*-*-*') c.create_text(legendtxt1, anchor=tk.SW, text="max=%5d" % max, font='-*-helvetica-*-r-*-*-*-120-*-*-*-*-*-*') c.create_text(labeltxt1, anchor=tk.SW, text='SSD health is %s (%02d%%)' % (healthstate, currpct), font='-*-helvetica-*-r-*-*-*-120-*-*-*-*-*-*') #here is for pie chart def drawpiechart(self, used, capacity, rowval, segment): #compute arc by pct def prop(n): return 360.0 * n / 1000.0 piewid = 50 legendwid = 50 greenthousandths = float(used) / float(capacity) * 1000.0 freespace = capacity - used currpct = 100 * (freespace / capacity) baseX = 100 #10 baseY = 2 #+200*segment piexy = (baseX, baseY, baseX + +piewid, baseY + piewid) legendxy = (baseX + piewid + 5, baseY + 5, baseX + piewid + 5 + 13, baseY + 19) legendxy1 = (baseX + piewid + 5, baseY + 25, baseX + piewid + 5 + 13, baseY + 39) legendtxt = (baseX + piewid + 5 + 20, baseY + 20) legendtxt1 = (baseX + piewid + 5 + 20, baseY + 40) labeltxt1 = (baseX, baseY + 65) x1 = Label(self.scrollframe, text='LABEL %02d%% free space' % (currpct), bg="green") x1.grid(row=1 + segment, column=3) #, sticky=C) x = Button(self.scrollframe, text='BUTTON %02d%% free space' % (currpct), bg="light grey") ##x.grid(row=rowval,column=0) #x.place(x = 20, y = baseY+30)#, width=120, height=25) x.grid(row=1 + segment, column=0) #, sticky=C) if True: c = Canvas(self.scrollframe, width=piewid + legendwid + 300, height=piewid + 50) c.grid(row=1 + segment, column=1) c.grid_rowconfigure(1 + segment, weight=1) c.grid_columnconfigure(1, weight=1) warningzones = [(80, 'green2', 'Good'), (50, 'yellow', 'Moderate'), (0, 'red', 'Low')] for i in warningzones: if currpct >= i[0]: healthcolor = i[1] healthstate = i[2] break c.create_arc(piexy, fill="gray", outline="#FAF402", start=prop(0), extent=prop(greenthousandths)) c.create_arc(piexy, fill=healthcolor, outline="black", start=prop(greenthousandths), extent=prop(1000 - greenthousandths)) c.create_rectangle(legendxy, fill=healthcolor) c.create_rectangle(legendxy1, fill="gray") c.create_text(legendtxt, anchor=tk.SW, text="%5dGB" % freespace, font='-*-helvetica-*-r-*-*-*-120-*-*-*-*-*-*') c.create_text(legendtxt1, anchor=tk.SW, text="%5dGB" % used, font='-*-helvetica-*-r-*-*-*-120-*-*-*-*-*-*') c.create_text(labeltxt1, anchor=tk.SW, text='Free space state is %s (%02d%%)' % (healthstate, currpct), font='-*-helvetica-*-r-*-*-*-120-*-*-*-*-*-*')
delays = [] recording = False running = False window = Tk() frame_left = Frame(window, padx=10, pady=10) frame_left.grid(row=0, column=0) frame_right = Frame(window, padx=10, pady=10) frame_right.grid(row=0, column=1) window.title("Click recorder") frame_left.columnconfigure(0, minsize=120) frame_left.columnconfigure(1, minsize=180) frame_left.columnconfigure(2, minsize=50) frame_left.rowconfigure(1, pad=20) frame_left.grid(sticky='N') frame_right.grid(sticky='N') b1_text = StringVar(frame_left) b3_text = StringVar(frame_left) rec_dur = IntVar(frame_right) human_like = IntVar(frame_right) fixed_cycle_nr = IntVar(frame_right) init_delay = StringVar(frame_right) default_delay = StringVar(frame_right) b1_text.set("Start recording") b3_text.set("Start clicks") init_delay.set("1") default_delay.set("1")
class OptimizerMainWindow: """ classdocs """ # TODO: change that name def reactToClick(self, event): a = AddRestrictionDialog(self) def __init__(self, optimizer): # always have a reference to model/controller self.optimizer = optimizer # setup main GUI and make stretchable self.guiRoot = Tk() self.guiRoot.title("OPTIMIZR") self.guiRoot.columnconfigure(1, weight=1) self.guiRoot.rowconfigure(0, weight=1) # left (settings) and right (sequences) part self.frameLeft = Frame(self.guiRoot) self.frameLeft.grid(row=0, column=0, sticky=W + E + N + S) self.frameLeft.columnconfigure(0, weight=1) self.frameRight = Frame(self.guiRoot) self.frameRight.grid(row=0, column=1, sticky=W + E + N + S) self.frameRight.columnconfigure(0, weight=1) self.frameRight.rowconfigure(0, weight=1) self.frameRight.rowconfigure(1, weight=1) self.frameSpeciesControll = LabelFrame(self.frameLeft, text="Species", pady=10, padx=10) self.frameSpeciesControll.columnconfigure(1, weight=1) self.frameOptimizationControll = LabelFrame(self.frameLeft, text="Optimization", pady=10, padx=10) self.frameRestrictionControll = LabelFrame(self.frameLeft, text="Restriction Enzymes", pady=10, padx=10) self.frameSpeciesControll.grid(row=0, column=0, sticky=W + E, padx=10, pady=10) self.frameOptimizationControll.grid(row=1, column=0, sticky=W + E, padx=10, pady=10) self.frameRestrictionControll.grid(row=2, column=0, sticky=W + E, padx=10, pady=10) # Species Controll Label(self.frameSpeciesControll, text="Source:").grid(row=0, column=0) Label(self.frameSpeciesControll, text="Target:").grid(row=1, column=0) self.comboSourceSpecies = Combobox(self.frameSpeciesControll, state="readonly") self.comboSourceSpecies.grid(row=0, column=1, pady=5, sticky="ew") self.comboTargetSpecies = Combobox(self.frameSpeciesControll, state="readonly") self.comboTargetSpecies.grid(row=1, column=1, pady=5, sticky="we") self.buttonSpeciesList = Button(self.frameSpeciesControll, text="Edit Species List") self.buttonSpeciesList.grid(row=2, column=1, pady=5, sticky="e") self.comboSourceSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) self.comboTargetSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) # Optimization Controll Label(self.frameOptimizationControll, text="Optimization Strategy:").grid(row=0, column=0) self.comboOptimizationStrategy = Combobox(self.frameOptimizationControll, state="readonly") self.comboOptimizationStrategy.grid(row=0, column=1) self.comboOptimizationStrategy["values"] = self.optimizer.possibleOptimizationStrategies self.comboOptimizationStrategy.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) # Restriction Enzymes self.listRestriction = Listbox(self.frameRestrictionControll) self.listRestriction.grid(row=0, column=0, columnspan=3, pady=5, sticky=W + E) self.frameRestrictionControll.columnconfigure(0, weight=1) self.buttonRestricionAdd = Button(self.frameRestrictionControll, text=" + ") self.buttonRestricionDel = Button(self.frameRestrictionControll, text=" - ") self.buttonRestricionAdd.grid(row=1, column=1, padx=5) self.buttonRestricionDel.grid(row=1, column=2, padx=5) # Source Sequence Frame self.frameSourceSequence = LabelFrame(self.frameRight, text="Source Sequence", padx=10, pady=10) self.frameResultSequence = LabelFrame(self.frameRight, text="Result Sequence", padx=10, pady=10) self.frameSourceSequence.grid(row=0, column=0, sticky="wens", padx=10, pady=10) self.frameResultSequence.grid(row=1, column=0, sticky="wens", padx=10, pady=10) self.buttonSourceLoad = Button(self.frameSourceSequence, text=" Load ") self.textSourceSeq = ScrolledText(self.frameSourceSequence, height=10) self.buttonSourceLoad.grid(row=0, column=1, sticky="e", pady=5) self.textSourceSeq.grid(row=1, column=0, columnspan=2, sticky="wens") self.frameSourceSequence.columnconfigure(0, weight=1) self.frameSourceSequence.rowconfigure(1, weight=1) self.textSourceSeq.frame.columnconfigure(1, weight=1) self.textSourceSeq.frame.rowconfigure(0, weight=1) self.buttonOptimize = Button(self.frameResultSequence, text=" OPTIMIZE! ") self.buttonOptimize.bind("<ButtonRelease>", self.actionOptimize) self.buttonRemoveRestriction = Button(self.frameResultSequence, text=" RESTRICTION-B-GONE! ") self.buttonRemoveRestriction.bind("<ButtonRelease>", self.actionRemoveRestricion) self.buttonSaveResult = Button(self.frameResultSequence, text=" Save ") self.textResultSequence = ScrolledText(self.frameResultSequence, height=10) self.buttonOptimize.grid(column=0, row=0, pady=5, sticky="w") self.buttonRemoveRestriction.grid(column=1, row=0, pady=5, padx=10, sticky="w") self.textResultSequence.grid(row=1, column=0, columnspan=4, sticky="wens") self.buttonSaveResult.grid(row=2, column=3, pady=5, sticky="e") self.frameResultSequence.columnconfigure(2, weight=1) self.frameResultSequence.rowconfigure(1, weight=1) self.textResultSequence.frame.columnconfigure(1, weight=1) self.textResultSequence.frame.rowconfigure(0, weight=1) self.textSourceSeq.bind("<<Modified>>", self.actionSequenceModified) self.textResultSequence.bind("<<Modified>>", self.actionSequenceModified) # generate color tags for textboxes for i in range(101): # green for normal codons (r, g, b) = colorsys.hsv_to_rgb(210 / 360, i / 100, 1.0) colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255)) self.textSourceSeq.tag_config("normal" + str(i), background=colorHex) self.textResultSequence.tag_config("normal" + str(i), background=colorHex) # red for codons with restriction sites (r, g, b) = colorsys.hsv_to_rgb(5 / 360, i / 100, 1.0) colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255)) self.textSourceSeq.tag_config("restrict" + str(i), background=colorHex) self.textResultSequence.tag_config("restrict" + str(i), background=colorHex) # Set (minimum + max) Window size self.guiRoot.update() self.guiRoot.minsize(self.guiRoot.winfo_width(), self.guiRoot.winfo_height()) self.buttonRestricionAdd.bind("<ButtonRelease>", self.reactToClick) self.buttonRestricionDel.bind("<ButtonRelease>", self.actionRestrictionEnzymeDelete) self.buttonSpeciesList.bind("<ButtonRelease>", self.actionEditSpeciesButton) self.buttonSourceLoad.bind("<ButtonRelease>", self.actionLoadSequence) self.buttonSaveResult.bind("<ButtonRelease>", self.actionSaveSequence) # TEST # self.listRestriction.insert("end", "EcoRI") # self.listRestriction.insert("end", "BamHI") # # dummy event to manually trigger update self.guiRoot.bind("<<Update>>", self.actionUpdate) self.actionUpdate(None) self.guiRoot.mainloop() def actionRestrictionEnzymeDelete(self, event): try: selectedEnzyme = self.listRestriction.selection_get() self.optimizer.restrictionEnzymeList.remove(selectedEnzyme) self.guiRoot.event_generate("<<Update>>") except tkinter.TclError: # no selection pass def actionUpdate(self, event): # print("update called") # clear list of restriction enzymes self.listRestriction.delete(0, "end") for r in self.optimizer.restrictionEnzymeList: self.listRestriction.insert("end", r) self.comboSourceSpecies.delete(0, "end") self.comboTargetSpecies.delete(0, "end") speciesValues = list() for (taxid, name) in self.optimizer.speciesList: speciesValues.append(taxid + ": " + name) self.comboSourceSpecies["values"] = speciesValues self.comboTargetSpecies["values"] = speciesValues if self.comboSourceSpecies.get() not in speciesValues: self.comboSourceSpecies.set("") if self.comboTargetSpecies.get() not in speciesValues: self.comboTargetSpecies.set("") self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) self.optimizer.saveConfig("config.ini") def actionEditSpeciesButton(self, event): speciesListDialog = SpeciesListDialog(self) def actionOptimizerSettingsChanged(self, event=None): # print("Something happened") strategy = self.comboOptimizationStrategy.get() sourceString = self.comboSourceSpecies.get() targetString = self.comboTargetSpecies.get() if not (strategy and sourceString and targetString): return sourceTaxid = sourceString.split(":")[0] targetTaxid = targetString.split(":")[0] self.optimizer.setOptimizer(sourceTaxid, targetTaxid, strategy) self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) # self.optimizer.testPrint() def actionOptimize(self, event=None): self.optimizer.runOptimization() self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) def actionRemoveRestricion(self, event=None): self.optimizer.runRestricionRemoval() self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) def actionSequenceModified(self, event=None): # necessary if, otherwise -> infinite loop if self.textSourceSeq.edit_modified(): seq = self.textSourceSeq.get("1.0", "end").strip() seq = stripCharsNotInList(seq.upper(), ["A", "C", "G", "T"]) self.optimizer.setSourceSeq(seq) oldInsert = self.textSourceSeq.index("insert") self.textSourceSeq.delete("1.0", "end") sourceCodons = self.optimizer.getCodonsForPrint(True) if not sourceCodons: self.textSourceSeq.insert("end", self.optimizer.sourceSequence) else: for (co, sc, r) in sourceCodons: if sc: if not r: self.textSourceSeq.insert("end", co, "normal" + str(int(sc * 100))) # print("normal"+str(int(sc*100))) else: self.textSourceSeq.insert("end", co, "restrict" + str(int(sc * 100))) else: # remainder without color self.textSourceSeq.insert("end", co) self.textSourceSeq.mark_set("insert", oldInsert) # reset the modified status at the very end self.textSourceSeq.edit_modified(False) if self.textResultSequence.edit_modified(): seq = self.textResultSequence.get("1.0", "end").strip() # self.optimizer.setOptimizedSeq(seq) oldInsert = self.textResultSequence.index("insert") self.textResultSequence.delete("1.0", "end") targetCodons = self.optimizer.getCodonsForPrint(False) if not targetCodons: self.textSourceSeq.insert("end", self.optimizer.optimizedSequence) else: for (co, sc, r) in targetCodons: if sc: if not r: self.textResultSequence.insert("end", co, "normal" + str(int(sc * 100))) # print("normal"+str(int(sc*100))) else: self.textResultSequence.insert("end", co, "restrict" + str(int(sc * 100))) else: # remainder without color self.textResultSequence.insert("end", co) self.textSourceSeq.mark_set("insert", oldInsert) self.textResultSequence.edit_modified(False) def actionLoadSequence(self, event=None): filename = tkinter.filedialog.askopenfilename() if filename: seq = sequenceIO.readFile(filename) self.textSourceSeq.delete("1.0", "end") self.textSourceSeq.insert("end", seq) self.textSourceSeq.edit_modified(True) def actionSaveSequence(self, event=None): filename = tkinter.filedialog.asksaveasfilename() if filename: # print("file is " + filename) with open(filename, mode="w") as fd: fd.write(self.optimizer.optimizedSequence)
class EguanaGUI(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() # if not EguanaInit.eguana_root_dir_exists(): # EguanaInit.create_eguana_root_dir() 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.supportedDevices = [] for fileName in [name for name in os.listdir('./machineConfig') if os.path.isfile('./machineConfig/' + name) and not name == 'eguanaMachineConfig.py' and name.endswith('.py')]: # try:{ components = fileName.split('.') fileName = components[0] className = fileName[0].upper() + fileName[1:] try: module = __import__("machineConfig."+fileName,fromlist=["machineConfig."]) classVar = getattr(module,className) except: continue self.supportedDevices.append(classVar()) # except: # pass self.selectMachineFrame = Frame(self.frame,relief=FLAT,bg='#FADC46') self.selectMachineFrame.pack(fill=BOTH,expand=True) self.setupSelectMachineButtons() def setupSelectMachineButtons(self): numDevices = len(self.supportedDevices) numColumns = 3 numRows = math.ceil((numDevices+1)/3) self.photo = PhotoImage(file="eguana.gif") self.photo = self.photo.subsample(2); self.photo_label = Label(self.selectMachineFrame,image=self.photo,borderwidth=0,highlightthickness=0) self.photo_label.configure(bg='#FADC46') self.photo_label.grid(row=int(numRows/2),column=1, sticky=N+S+E+W,padx=2,pady =2) self.photo_label.image = self.photo index = 0 for i in range(numRows): for j in range(numColumns): if not(j == 1 and i == int(numRows/2)) and (index < numDevices): device = self.supportedDevices[index] b = Button(self.selectMachineFrame,text=device.name,relief=RAISED, command=lambda device=device :self.machineButtonPressed(device)) b.grid(row=i,column=j, sticky=N+S+E+W,padx=2,pady =2) index += 1 for i in range(numRows): self.selectMachineFrame.rowconfigure(i,weight=1) for i in range(numColumns): self.selectMachineFrame.columnconfigure(i,weight=1) def machineButtonPressed(self,inputDevice): dirStr = filedialog.askdirectory() if len(dirStr) and inputDevice.isDirectoryValid(dirStr): inputDevice.setDirPath(dirStr) EguanaModel().machine = inputDevice self.selectMachineFrame.destroy() self.menubar.inputSelected() self.photo_label.destroy() dirStr = 'Input Path : '+dirStr self.selectPlotFrame = Frame(self.frame, relief=FLAT,bg='#FADC46') self.selectPlotFrame.pack(fill=BOTH,expand=True) self.selectPlotFrame.rowconfigure(0,weight=1) self.selectPlotFrame.rowconfigure(1,weight=2) self.selectPlotFrame.columnconfigure(0,weight=1) self.infoFrame = Frame(self.selectPlotFrame, relief=FLAT, bg='#FADC46') self.infoFrame.grid(row=0,column=0, sticky=N+S+E+W,padx=2,pady =2) self.machineNameLabel = Label(self.infoFrame, text=inputDevice.name,relief=FLAT) self.machineNameLabel.grid(row=0,column=0,columnspan=2, 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=1,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=2,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=3,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=4,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=4,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=10) self.infoFrame.rowconfigure(2, weight=10) self.infoFrame.rowconfigure(3, weight=10) self.infoFrame.rowconfigure(4, weight=10) 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.config(text=dirStr) def showPlotTools(self): f2= Frame(self.selectPlotFrame, relief=FLAT,bg='#FADC46') f2.grid(row=1,column=0,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) b1.config(state=EguanaModel().machine.plot3DKButtonState) b2.config(state=EguanaModel().machine.plot3DDstButtonState) b3.config(state=EguanaModel().machine.plot3DDpButtonState) b4.config(state=EguanaModel().machine.plot2DKButtonState) b5.config(state=EguanaModel().machine.plot2DDstButtonState) b6.config(state=EguanaModel().machine.plot2DDpButtonState) 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 = int(trialNum) print(EguanaModel().machine.ifTrialExists(trialNum)) if EguanaModel().machine.ifTrialExists(trialNum): self.plotFigure(number) return True else: messagebox.showerror( "Trial Number Error", "The trial doesn't exist" ) 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()) EguanaModel().machine.getDataForTrialNumber(number) def selectFilter(self): ffPopup = FilterFunctionPopup(self) if ffPopup.selectedFilter is not None: EguanaModel().filterFunction = ffPopup.selectedFilter ftPopup = FilterTypePopup(self,ffPopup.selectedFilter) if (ftPopup.selectedHeadFilterType is not None) and (ftPopup.selectedHeadFilterType is not None): self.menubar.setSelectedFilters(ffPopup.selectedFilter,ftPopup.selectedHeadFilterType,ftPopup.selectedJawFilterType) EguanaModel().filterTypeHead = ftPopup.selectedHeadFilterType EguanaModel().filterTypeJaw = ftPopup.selectedJawFilterType EguanaModel().filterFunction = ffPopup.selectedFilter buttonText = '{} - Jaw Filter : {} - Head Filter {}'.format(ffPopup.selectedFilter.name,ftPopup.selectedJawFilterType.name, ftPopup.selectedHeadFilterType.name) self.filterButton.config(text=buttonText) def updateSelectedFilters(self,ffName,ftHeadName,ftJawName): buttonText = '{} - Jaw Filter : {} - Head Filter {}'.format(ffName,ftHeadName,ftJawName) self.filterButton.config(text=buttonText) 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 SpeciesSearchDialog: def __init__(self, parent, caller): # main window self.parent = parent # dialog that called this second dialog self.caller = caller self.gui = Toplevel(parent.guiRoot) self.gui.grab_set() self.gui.focus() self.gui.columnconfigure(0, weight=1) self.gui.rowconfigure(1, weight=1) self.entrySearch = Entry(self.gui) self.buttonSearch = Button(self.gui, text=" Search ") self.buttonAdd = Button(self.gui, text=" Add Species ") self.buttonClose = Button(self.gui, text=" Close Window ") self.frameResults = Frame(self.gui) self.frameResults.columnconfigure(0, weight=1) self.frameResults.rowconfigure(0, weight=1) self.scrollResults = Scrollbar(self.frameResults, orient="vertical") self.scrollResults.grid(row=0, column=1, sticky="ns") self.listResults = Listbox(self.frameResults, width=70, height=20) self.listResults.grid(row=0, column=0, sticky="nswe") self.listResults.config(yscrollcommand=self.scrollResults.set) self.scrollResults.config(command=self.listResults.yview) self.entrySearch.grid(row=0, column=0, columnspan=2, sticky="we", padx=5, pady=5) self.frameResults.grid(row=1, column=0, columnspan=3, sticky="nswe", padx=5, pady=5) self.buttonSearch.grid(row=0, column=2, padx=5, pady=5, sticky="e") self.buttonAdd.grid(row=2, column=1, padx=5, pady=5, sticky="e") self.buttonClose.grid(row=2, column=2, padx=5, pady=5, sticky="e") self.gui.protocol("WM_DELETE_WINDOW", self.actionClose) self.buttonClose.bind("<ButtonRelease>", self.actionClose) self.buttonAdd.bind("<ButtonRelease>", self.actionAdd) self.buttonSearch.bind("<ButtonRelease>", self.actionSearch) self.entrySearch.bind("<Return>", self.actionSearch) self.gui.update() self.gui.minsize(self.gui.winfo_width(), self.gui.winfo_height()) self.gui.mainloop() def actionAdd(self, event): try: selection = self.listResults.selection_get() selectionSplit = selection.split(":\t", 1) selectionSplit2 = selectionSplit[1].split("\t") if not (selectionSplit[0], selectionSplit2[0]) in self.parent.optimizer.speciesList: self.parent.optimizer.speciesList.append((selectionSplit[0], selectionSplit2[0].strip())) self.caller.gui.event_generate("<<Update>>") except tkinter.TclError: # no selection pass def actionSearch(self, event): query = self.entrySearch.get() if query: self.listResults.delete(0, "end") results = self.parent.optimizer.SPSUMHandler.search(query) # sort results by nr of CDS results = sorted(results.items(), reverse=True, key=lambda x: (int(x[1][1]))) for name, (taxid, ncs) in results: self.listResults.insert("end", taxid + ":\t " + name + " \t(" + ncs + " CDS)") def actionClose(self, event=None): self.caller.gui.event_generate("<<Update>>", when="tail") self.gui.destroy()
def BuildMainFrame(self): from tkinter import Menu, IntVar, StringVar, Toplevel, Listbox, Frame, PanedWindow, Text, Scrollbar, Entry from tkinter import X, N, S, W, E, VERTICAL, TOP, END, DISABLED, RAISED menu = Menu(self.master,activeborderwidth=0,bd=0) self.master.config(menu=menu) filemenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="File", underline=0, menu=filemenu) filemenu.add_command(label="New", accelerator='Ctrl+N',command=self.NewCommand) filemenu.add_command(label="Open...",accelerator='Ctrl+O', command=self.OpenCommand) filemenu.add_command(label="Save as...",accelerator='Ctrl+S', command=self.SaveCommand) filemenu.add_separator() filemenu.add_command(label="Quit",accelerator='Ctrl+Q', command=self.QuitCommand) self.log_on = IntVar() self.log_on.set(1) self.output_to_file = StringVar() self.output_to_file.set('n') scriptmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) modulenames = ['vmtkscripts'] for modulename in modulenames: scriptsubmenu = self.BuildScriptMenu(menu,modulename) if scriptsubmenu: scriptmenu.add_cascade(label=modulename,menu=scriptsubmenu) editmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Edit",underline=0, menu=editmenu) editmenu.add_cascade(label="Insert script",menu=scriptmenu) editmenu.add_command(label="Insert file name", accelerator='Ctrl+F',command=self.InsertFileName) editmenu.add_separator() editmenu.add_command(label="Clear input", command=self.ClearInputCommand) editmenu.add_command(label="Clear output", command=self.ClearOutputCommand) editmenu.add_command(label="Clear all", command=self.ClearAllCommand) editmenu.add_separator() editmenu.add_checkbutton(label="Log", variable=self.log_on) editmenu.add_separator() editmenu.add_radiobutton(label="No output to file", variable=self.output_to_file,value='n') editmenu.add_radiobutton(label="Write output to file", variable=self.output_to_file,value='w') editmenu.add_radiobutton(label="Append output to file", variable=self.output_to_file,value='a') editmenu.add_command(label="Output file...", command=self.OutputFileCommand) runmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Run", underline=0, menu=runmenu) runmenu.add_command(label="Run all", command=self.RunAllCommand) runmenu.add_command(label="Run current line", command=self.RunLineCommand) runmenu.add_command(label="Run selection", command=self.RunSelectionCommand) helpmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Help", underline=0, menu=helpmenu) helpmenu.add_command(label="Help", underline=0, accelerator='F1',command=self.ShowHelpCommand) helpmenu.add_command(label="About", underline=0, command=self.AboutCommand) self.master.bind("<Control-KeyPress-q>", self.QuitHandler) self.master.bind("<Control-KeyPress-n>", self.NewHandler) self.master.bind("<Control-KeyPress-o>", self.OpenHandler) self.master.bind("<Control-KeyPress-s>", self.SaveHandler) self.master.bind("<Control-KeyPress-f>", self.InsertFileNameHandler) self.master.bind("<KeyPress-F1>", self.ShowHelpHandler) self.master.bind("<KeyPress>", self.KeyPressHandler) self.wordIndex = ['1.0','1.0'] self.suggestionswindow = Toplevel(bg='#ffffff',bd=0,height=50,width=600,highlightthickness=0,takefocus=True) self.suggestionswindow.overrideredirect(1) self.suggestionslist = Listbox(self.suggestionswindow,bg='#ffffff',bd=1,fg='#336699',activestyle='none',highlightthickness=0,height=9) self.suggestionslist.insert(END,"foo") self.suggestionslist.pack(side=TOP,fill=X) self.suggestionswindow.bind("<KeyPress>", self.TopKeyPressHandler) self.suggestionswindow.withdraw() self.master.rowconfigure(0,weight=1) self.master.columnconfigure(0,weight=1) content = Frame(self.master,bd=0,padx=2,pady=2) content.grid(row=0,column=0,sticky=N+S+W+E) content.rowconfigure(0,weight=1,minsize=50) content.rowconfigure(1,weight=0) content.columnconfigure(0,weight=1) panes = PanedWindow(content,orient=VERTICAL,bd=1,sashwidth=8,sashpad=0,sashrelief=RAISED,showhandle=True) panes.grid(row=0,column=0,sticky=N+S+W+E) frame1 = Frame(panes,bd=0) frame1.grid(row=0,column=0,sticky=N+S+W+E) frame1.columnconfigure(0,weight=1) frame1.columnconfigure(1,weight=0) frame1.rowconfigure(0,weight=1) panes.add(frame1,height=300,minsize=20) frame2 = Frame(panes,bd=0) frame2.grid(row=1,column=0,sticky=N+S+W+E) frame2.columnconfigure(0,weight=1) frame2.columnconfigure(1,weight=0) frame2.rowconfigure(0,weight=1) panes.add(frame2,minsize=20) self.text_input = Text(frame1, bg='#ffffff',bd=1,highlightthickness=0) self.text_input.bind("<KeyPress>", self.KeyPressHandler) self.text_input.bind("<Button-3>", self.PopupHandler) self.text_input.bind("<Control-Return>", self.RunKeyboardHandler) self.input_scrollbar = Scrollbar(frame1,orient=VERTICAL,command=self.text_input.yview) self.text_input["yscrollcommand"] = self.input_scrollbar.set self.text_output = Text(frame2,state=DISABLED,bd=1,bg='#ffffff',highlightthickness=0) self.output_scrollbar = Scrollbar(frame2,orient=VERTICAL,command=self.text_output.yview) self.text_output["yscrollcommand"] = self.output_scrollbar.set self.text_entry = Entry(content,bd=1,bg='#ffffff',state=DISABLED,highlightthickness=0) self.text_input.focus_set() self.text_input.grid(row=0,column=0,sticky=N+S+W+E) self.input_scrollbar.grid(row=0,column=1,sticky=N+S+W+E) self.text_output.grid(row=0,column=0,sticky=N+S+W+E) self.output_scrollbar.grid(row=0,column=1,sticky=N+S+W+E) self.text_entry.grid(row=1,column=0,sticky=N+S+W+E) self.popupmenu = Menu(self.text_input, tearoff=1, bd=0) self.popupmenu.add_command(label="Context help", command=self.ShowHelpCommand) self.popupmenu.add_cascade(label="Insert script",menu=scriptmenu) self.popupmenu.add_command(label="Insert file name...", command=self.InsertFileName) self.popupmenu.add_separator() self.popupmenu.add_command(label="Run all", command=self.RunAllCommand) self.popupmenu.add_command(label="Run current line", command=self.RunLineCommand) self.popupmenu.add_command(label="Run selection", command=self.RunSelectionCommand) self.output_stream = TkPadOutputStream(self.text_output) self.input_stream = TkPadInputStream(self.text_entry,self.output_stream)
class MainWin(Tk) : downloadVideo = video(); def __init__(self, title , *args , **kwargs) : Tk.__init__(self,*args,**kwargs); self.minsize(500,600) self.last = History(); self.downloadDir = DDIR; self.title(title + " - " + self.downloadDir); self.downloading = False; self.protocol("WM_DELETE_WINDOW", self._onClose) try : self.iconbitmap("icons/ytb.ico") except : pass; self._mainmenu() self._tabs() self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self._upperEntries(); self._defaultFrames(); self._downloadingFrame() self._metaDataFrame() convertTab(self.converter) def _onClose(self) : if self.downloading == True : ans = msg.askyesno("quit" , "your downloading hasn't finished yet are your sure to quit ?"); if ans == True : self.last.write("n" , self.url);self.destroy(); else : return; else : self.destroy() def popupmsg(self): msg = "jesus christ" popup = Tk() popup.geometry("600x200") popup.wm_title("jesus christ") def listBox() : scrollbar = Scrollbar(popup) scrollbar.grid(row=0,column=1,sticky="ns") listbox = Listbox(popup) listbox.grid(row=0,column=0,sticky="snew") listbox.config(yscrollcommand=scrollbar.set) scrollbar.config(command=listbox.yview) self.columnconfigure(0,weight=1) self.rowconfigure(0,weight=1) def addLogsToListBox() : i = 0; for log in self.last.read() : listbox.insert(END, log.replace("\n","")); if i % 2 == 1 : listbox.itemconfig(i,{"bg":"#e8dada"}) i += 1; addLogsToListBox(); listBox() popup.columnconfigure(0,weight=1) popup.rowconfigure(0,weight=1) popup.mainloop() def _startNewThread(self , func , args) : thrd = Thread(target=func ,args=args) thrd.setDaemon(True); thrd.start(); def _mainmenu(self) : mainM = Menu(self); self.config(menu=mainM); sub1 = Menu(mainM , tearoff=False); mainM.add_cascade(label=" File " , menu=sub1); sub1.add_command(label="Change Download Path ",command=self._changeDownloadPath); sub1.add_command(label="History ",command=self.popupmsg); sub1.add_command(label="Exit ",command=self.destroy); self._sub1 = sub1; sub2 = Menu(mainM , tearoff=False); mainM.add_cascade(label=" Help " , menu=sub2); #add list of command here for <Help> sub2.add_command(label="About us " , command=None); sub2.add_command(label="Application manual " , command=None); self._mainM = mainM; def _tabs(self) : note = k.Notebook(self); note.grid(row=0 , column=0 , sticky="snew"); note.columnconfigure(0,weight=1); self.videof = Frame(self); self.plist = Frame(self); self.converter = Frame(self); note.add(self.videof , text="Video"); note.add(self.plist , text="Playlist"); note.add(self.converter , text="Convert"); self.videof.columnconfigure(0,weight=1) self.plist.columnconfigure(0,weight=1) self.converter.columnconfigure(0,weight=1) self.converter.rowconfigure(1,weight=1) def _changeDownloadPath(self) : folder = askdirectory(initialdir=self.downloadDir); if folder == "" : pass; else : self.downloadDir = folder self.title("jesus - " + self.downloadDir) self.pathEntry.delete(0,END); self.pathEntry.insert(0,self.downloadDir) def _upperEntries(self) : frame = LabelFrame(self.videof,text="Paths"); frame.grid(row=0,column=0,sticky="we",ipady=10,pady=(5,5),padx=(5,5),ipadx=10); frame.columnconfigure(1,weight=1); self.urlEntry = Entry(frame,font=("Consolas",10)); self.urlEntry.grid(row=0,column=0,ipady=2,sticky="we",padx=(10,10),pady=(15,6),columnspan=2); Label(frame,text="Save to").grid(row=1,column=0,padx=(10,0)) self.pathEntry = Entry(frame,font=("Consolas",10)); self.pathEntry.grid(row=1,column=1,ipady=2,sticky="we",padx=(10,10),pady=6); self.pathEntry.insert(0,self.downloadDir) add_placeholder_to(self.urlEntry , "add youtube video url...") self.checkBtn = Button(frame,text="attach",relief="groove",command=self._checkEntries) self.checkBtn.grid(row=0,column=2,sticky="we",pady=(15,6),padx=(0,10),ipadx=15,ipady=1); chngdir = Button(frame,relief="flat",command=self._changeDownloadPath) chngdir.grid(row=1,column=2,padx=(0,10),sticky="w") try : image = PhotoImage(file="icons/dir.png"); chngdir.image = image; chngdir.configure(image=image); except : chngdir.configure(text="...",relief="groove") def _checkEntries(self) : data = self.urlEntry.get(); if data.replace(" ","") == "" : return; data = data.replace(" ",""); allSols = [ "https://www.youtube.com/watch?v=", "http://www.youtube.com/watch?v=", "www.youtube.com/watch?v=", "youtube.com/watch?v=" ]; flag = False; for sol in allSols : if data.startswith(sol) : flag = True; if flag == False : msg.showerror("URL Error","please enter valid URL youtube video"); else : save = self.pathEntry.get(); if save.replace(" ","") == "" : return; if not (path.exists(save) and path.isdir(save)) : msg.showerror("Directory Error","the directory specified not found"); else : try : self.checkBtn.config(text="wait..",state="disabled"); MainWin.downloadVideo.setLink(data); except HTTPError : msg.showerror("Network Error" , "No network available at this time or path not resolved") except URLError : msg.showerror("Network Error" , "No network available at this time or path not resolved") except Exception as e: msg.showerror("URL Error","No network available at this time or path not resolved " + str(e)); else : self.url = data; self.path = save; self._viewMetadata() streams = []; for s in MainWin.downloadVideo.getStreams() : stream = str(s); sol = ""; sol = stream.split(":")[0] + " " + stream.split(":")[1].split("@")[0] + " " + stream.split(":")[1].split("@")[1]; streams.append(sol) self.combo.config(state="readonly" , values=streams) self.combo.set(streams[0]) if self.downloading == False : self._startNewThread(lambda : playsound("notification/canDownload.mp3"),()); self.downloadBtn.config(state="active") print(self.url , " " , self.path); finally : self.checkBtn.config(text="attach",state="active"); def _viewMetadata(self) : def formateTitle(title) : formatted = ""; for index in range(len(title)) : if index % 34 == 0 and index != 0 : if title[index] != " " : formatted += "-" formatted += "\n"+title[index] else : formatted += title[index]; return formatted; metadata = MainWin.downloadVideo.getMetaData(); self.metaLabels[0].config(text=metadata["author"]) self.metaLabels[1].config(text=metadata["duration"]) self.metaLabels[2].config(text=metadata["category"]) self.metaLabels[3].config(text=metadata["published"]) self.metaLabels[4].config(text=metadata["likes"]) self.metaLabels[5].config(text=metadata["dislikes"]) self.metaLabels[6].config(text=metadata["rating"]) self.metaLabels[7].config(text=metadata["viewcount"]) self.metaLabels[8].config(text=formateTitle(metadata["title"])) self.metaLabels[-1].destroy(); self.metaLabels.pop(); self.metaLabels.append(imagedLabel(self.mFrame , MainWin.downloadVideo.getThumbURL())); self.metaLabels[-1].grid(row=0,column=0,pady=(15,0),padx=(10,10)) def startDownload(self) : choice = self.combo.get(); choice = choice.split(); #choice now is ["normal" , "mp4" , "480x360"]; for s in MainWin.downloadVideo.getStreams() : if s.mediatype == choice[0] and s.extension == choice[1] and s.quality == choice[2] : print("downloading : " , s.mediatype , s.extension , s.quality) try : self.downloading = True; MainWin.downloadVideo.download(self , self.path , s , self.progressBarCallback); self.last.write("s" , self.url); except HTTPError : msg.showerror("Network Error" , "No network available at this time or path not resolved") self.last.write("e" , self.url); except URLError : msg.showerror("Network Error" , "No network available at this time or path not resolved") self.last.write("e" , self.url); except PermissionError : msg.showerror("Saving Error" , "Cant't download your file in the given path , permission denied") self.last.write("e" , self.url); except MemoryError : msg.showerror("Memory Error" , "Not enough memory"); self.last.write("e" , self.url); except FileExistsError : msg.showerror("Error" , "the files name is already found in the given path") self.last.write("e" , self.url); except : msg.showerror("Error" , "An error accurred") self.last.write("e" , self.url); finally : self.downloadBtn.config(state="active") self.progress["value"] = 0; self.downloading = False; break; def progressBarCallback(self,total, recvd, ratio, rate, eta) : self.downloaded.config(text="Downloaded " + " : " + str(recvd / 1024 / 1024)[:4] + " MB" + " Of " + str(total / 1024 / 1024)[:4] + " ETA: " + str(eta / 60)[:4] + " Min"); self.netRate.config(text="[ " + str(rate)[:4] + " kbps ]"); self.progRate.config(text="[ " + str(ratio*100).split(".")[0] +" % ]"); self.progress["value"] = float(str(ratio*100).split(".")[0]) def threadedDownloading(self) : self._startNewThread(self.startDownload , ()) def _defaultFrames(self) : frame = LabelFrame(self.videof,text="Video metadata") frame.grid(row=2,column=0,sticky="we",padx=(5,5),pady=(5,5),ipady=10,ipadx=10); self.mFrame = frame; frame = LabelFrame(self.videof , text="Downloading"); frame.grid(row=3,column=0,sticky="snew",padx=(5,5),pady=(5,5),ipady=10,ipadx=10) self.videof.rowconfigure(3,weight=1) self.dFrame = frame; def _downloadingFrame(self) : self.progress=k.Progressbar(self.dFrame,orient="horizontal",mode='determinate') self.progress["value"] = 0; #self.dFrame.rowconfigure(1,weight=1) #self.dFrame.rowconfigure(0,weight=1) self.dFrame.rowconfigure(2,weight=1) #self.dFrame.columnconfigure(0,weight=1) self.dFrame.columnconfigure(1,weight=1) Label(self.dFrame,text="Options").grid(row=0,column=0,sticky="w",padx=(10,0)) self.combo = k.Combobox(self.dFrame , values=["jesus","christ","mariam","karas"],state='disabled'); self.combo.grid(row=0,column=1,sticky="e",columnspan=2,padx=(0,10),pady=(5,15)) self.combo.set("Select : ") self.progress.grid(row=2,column=0,sticky="wen",padx=(10,10),pady=(5,5),columnspan=3); self.netRate = Label(self.dFrame,text="[ -- ]") self.netRate.grid(row=1,column=1,sticky="es"); self.progRate = Label(self.dFrame,text="[ -- ]") self.progRate.grid(row=1,column=2,sticky="es",padx=(0,10)); self.downloaded = Label(self.dFrame,text="Downloaded : -- Of -- ETA : --") self.downloaded.grid(row=1,column=0,sticky="ws",padx=(10,10)); self.downloadBtn = Button(self.dFrame,command=self.threadedDownloading,text="Download",state="disabled",relief="groove") self.downloadBtn.grid(row=3,column=1,sticky="se",columnspan=2,padx=(10,10),pady=(10,5),ipady=2,ipadx=3) #self.cancelBtn = Button(self.dFrame,text="Cancel",state="disabled",relief="groove") #self.cancelBtn.grid(row=3,column=0,sticky="se",columnspan=2,padx=(10,50),pady=(10,5),ipady=2,ipadx=10) def _metaDataFrame(self) : def label(root,text) : return Label(root,text=text,font=("Consolas","10","italic")); #http://i.ytimg.com/vi/j2Obuh4Sv9A/default.jpg #imgLbl = imagedLabel(self.mFrame, "https://dummyimage.com/160x110/875d87/000000.png&text=++No+Video"); imgLbl = Label(self.mFrame); imgLbl.grid(row=0,column=0,pady=(15,0),padx=(15,15)) try : img = PhotoImage(file="icons/novideo.png") imgLbl.image = img; imgLbl.configure(image=img) except : imgLbl.grid(row=0,column=0,ipadx=70,ipady=40); imgLbl.configure(bg="#875d87") title = label(self.mFrame,"no title") title.grid(row=1,column=0,padx=(10,10)) frame = Frame(self.mFrame) frame.grid(row=0,column=1,sticky="snew",rowspan=2,padx=(0,10),pady=(15,0)); lbls = []; lblsTxts = [ "author","duration","category","published","--","--","--","--", "likes","dislikes","rating","viewcount","--","--","--","--" ] for i in range(16) : lbls.append(label(frame , lblsTxts[i])); if i >= 0 and i <= 3 : lbls[-1].grid(row=i,column=0,pady=(8,8));lbls.pop(); if i >= 4 and i <= 7 : lbls[-1].grid(row=i-4,column=1,pady=(8,8),sticky="w");lbls[-1].config(font=("Consolas",10,"bold italic")) if i >= 8 and i <= 11 : lbls[-1].grid(row=i-8,column=2,pady=(8,8));lbls.pop(); if i >= 12 and i <= 15 : lbls[-1].grid(row=i-12,column=3,pady=(8,8),sticky="w");lbls[-1].config(font=("Consolas",10,"bold italic")) self.metaLabels = lbls; self.metaLabels.append(title) self.metaLabels.append(imgLbl) self.mFrame.columnconfigure(1,weight=1) frame.columnconfigure(0,weight=1) frame.columnconfigure(1,weight=1) frame.columnconfigure(2,weight=1) frame.columnconfigure(3,weight=1) def run(self) : self.mainloop();
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()
def show_items(self, items, upper=[]): """ Creates a new page on the stack, automatically adds a back button when there are pages on the stack already :param items: list the items to display :param upper: list previous levels' ids :return: None """ num = 0 # create a new frame wrap = Frame(self, bg="black") # when there were previous frames, hide the top one and add a back button for the new one if len(self.framestack): self.hide_top() back = FlatButton( wrap, text='back…', image=self.get_icon("arrow.left"), command=self.go_back, ) back.set_color("#00a300") # green back.grid(row=0, column=0, padx=1, pady=1, sticky=TkC.W + TkC.E + TkC.N + TkC.S) num += 1 # add the new frame to the stack and display it self.framestack.append(wrap) self.show_top() # calculate tile distribution all = len(items) + num rows = floor(sqrt(all)) cols = ceil(all / rows) # make cells autoscale for x in range(int(cols)): wrap.columnconfigure(x, weight=1) for y in range(int(rows)): wrap.rowconfigure(y, weight=1) # display all given buttons for item in items: act = upper + [item['name']] if 'icon' in item: image = self.get_icon(item['icon']) else: image = self.get_icon('scrabble.'+item['label'][0:1].lower()) btn = FlatButton( wrap, text=item['label'], image=image ) if 'items' in item: # this is a deeper level btn.configure(command=lambda act=act, item=item: self.show_items(item['items'], act), text=item['label']+'…') btn.set_color("#2b5797") # dark-blue else: # this is an action btn.configure(command=lambda act=act: self.go_action(act), ) if 'color' in item: btn.set_color(item['color']) # add buton to the grid btn.grid( row=int(floor(num / cols)), column=int(num % cols), padx=1, pady=1, sticky=TkC.W + TkC.E + TkC.N + TkC.S ) num += 1