class FileChooser: def __init__(self): self.filechooser = Tk() self.filechooser.geometry('500x500+0+0') self.button = Button(self.filechooser,text="Add Directory",command=self.addDir) self.listview = Listbox(self.filechooser) self.closebutton = Button(self.filechooser,text="Scan",command=self.Done) self.listview.pack(fill="both") self.button.pack(fill='x') helptext = """Select directories by pressing the "Add Directory" Button, then press Scan. \n When the file tree appears, red text means the file or folder is a duplicate. \n purple means the folder contains duplicates but itself is not a duplicate. \n Double Click on red text entries to view matches""" self.instructions = Label(self.filechooser, text=helptext) self.instructions.pack(fill='both') self.closebutton.pack() self.filechooser.mainloop() def Done(self): self.filechooser.destroy() def addDir(self): dir = askdirectory() if os.path.isdir(dir): dirlist.append(dir) self.listview.insert('end',str(dir))
class Mjolnir3(KRCCModule): def __init__(self, root): super().__init__() self.root = root self.exception = None self.list_string = StringVar() self.listbox = Listbox(root, listvariable=self.list_string, font='TkFixedFont', width=300) self.load() def establish_connection_and_run(self): error = None dots = 0 connection = None while not self.terminate: try: if connection is None: connection = krpc.connect(name=self.name) self.run_with_connection(connection) error = None dots = 0 except Exception as e: if error != e.args[0]: error = e.args[0] print('\n') print(traceback.format_exc()) sys.stdout.write('Retrying...\n') if dots > 80: dots = 0 sys.stdout.write('\n') sys.stdout.write('.') dots += 1 sys.stdout.flush() time.sleep(1) if connection is not None: connection.close() def run_with_connection(self, connection): logging.debug('KRPC connection established') strategy = PreLaunch(connection) while not self.terminate: strategy = strategy.update() self.list_string.set(tuple(strategy.display())) def run(self): try: self.establish_connection_and_run() self.listbox.destroy() except RuntimeError: # Should only happen when KeyboardInterrupt is thrown in the MainThread. pass @property def name(self): return 'Mjolnir 3' def load(self): self.listbox.pack(side=LEFT, fill=BOTH)
def insert_list(self, items): frame = self.frame frame.pack(fill="y") lb = Listbox(frame, selectmode="multiple") for i in items: lb.insert("end", i) lb.pack() self.ok_cancel_buttons(call=lambda : self.del_items(lb.curselection()))
def __init__(self, *, multiple_runner_class, input_spec, left_name, right_name): """Sets up windows and the instance of RunMultipleTimes that will do the actual work.""" #: The input_spec is an iterable of #: :py:class:`farg.core.read_input_spec.SpecificationForOneRun`. self.input_spec = input_spec #: Class responsible for the actual running multiple times. self.multiple_runner_class = multiple_runner_class #: Main window self.mw = mw = Tk() #: Statistics thus far, grouped by input. self.stats = AllStats(left_name=left_name, right_name=right_name) #: Are we in the process of quitting? self.quitting = False self.status_label = Label( mw, text='Not Started', font=('Times', 20), foreground='#000000') self.status_label_text = self.status_label.cget('text') self.status_label.pack(side=TOP, expand=True, fill=X) #: Has a run started? Used to ensure single run. self.run_started = False details_frame = Frame(mw) details_frame.pack(side=TOP) #: listbox on left listing inputs. frame = Frame(details_frame) scrollbar = Scrollbar(frame, orient=VERTICAL) listbox = Listbox( frame, yscrollcommand=scrollbar.set, height=25, width=70, selectmode=SINGLE) scrollbar.config(command=listbox.yview) scrollbar.pack(side=RIGHT, fill=Y) listbox.pack(side=LEFT, fill=BOTH, expand=1) listbox.bind('<ButtonRelease-1>', self.SelectForDisplay, '+') frame.pack(side=LEFT) self.listbox = listbox #: Canvas on right for details self.canvas = Canvas( details_frame, width=kCanvasWidth, height=kCanvasHeight, background='#FFFFFF') self.canvas.pack(side=LEFT) #: which input are we displaying the details of? self.display_details_for = None #: Thread used for running self.thread = None self.mw.bind('<KeyPress-q>', lambda e: self.Quit()) self.mw.bind('<KeyPress-r>', lambda e: self.KickOffRun()) self.Refresher() self.mw.after(1000, self.KickOffRun)
class LabeledListBox(Frame): def __init__(self, parent, list_model, label_text): Frame.__init__(self, parent) self._list_model = list_model self._list_objects = [] self._selected_items = [] scrollbar = Scrollbar(self, orient=VERTICAL) Label(self, text=label_text).pack() self.listbox = Listbox(self, selectmode=EXTENDED, exportselection=0, yscrollcommand=scrollbar.set, borderwidth=0, highlightthickness=0) scrollbar.config(command=self.listbox.yview) scrollbar.pack(side=RIGHT, fill=Y) self.listbox.pack(side=LEFT, fill=BOTH, expand=1) self.listbox.bind('<<ListboxSelect>>', self._on_select) self._list_model.list_items_model.add_listener(self._list_items_changed) self._list_model.selected_items_model.add_listener(self._selected_items_changed) self._update_list_items() def _list_items_changed(self, values): self._update_list_items() def _selected_items_changed(self, values): self._update_selected_items() def _update_list_items(self): values, labels = self._list_model.list_items_model.get_list_values() if not values == self._list_objects: self._list_objects = [] self._selected_items = [] self.listbox.delete(0, END) for value, label in zip(values, labels): self._list_objects.append(value) self.listbox.insert(END, label) self._update_selected_items() def _update_selected_items(self): selected_items = self._list_model.selected_items_model.selected_items if not selected_items == self._selected_items: self._selected_items = selected_items for index, list_item in enumerate(self._list_objects): if list_item in selected_items: self.listbox.selection_set(index) def _on_select(self, evt): visible_selected_indices = self.listbox.curselection() for index, list_item in enumerate(self._list_objects): if index in visible_selected_indices: self._list_model.selected_items_model.select(list_item) else: self._list_model.selected_items_model.deselect(list_item)
class PRGListBox(Frame): def __init__(self, master=None,**args): Frame.__init__(self, master,**args) scrollbar = Scrollbar(self, orient=VERTICAL) #нужен для отображения длинных списков scrollbar.unbind("<Key-Up>") scrollbar.unbind("<Key-Down>") scrollbar.unbind("<Key-Left>") scrollbar.unbind("<Key-Right>") scrollbar.pack(side=RIGHT, fill=Y) self.lst = Listbox(self, yscrollcommand=scrollbar.set, bg="grey", selectmode=SINGLE) self.lst.insert(END,"Hide All") self.lst.insert(END,"Show All") self.lst.select_set(0) self.lst.pack(side=LEFT, fill=BOTH, expand=1) scrollbar.config(command=self.lst.yview)
def initUI(self): self.parent.title("Listbox") self.pack(fill=BOTH, expand=1) acts = ["Scarlett Johansson", "Rachel Weiss", "Natalie Portman", "Jessica Alba", "Angelina jolie", "Emma Stone", "Sandra Bullock", "Julia Roberts", "Jennifer Lawrence", "Mila Kunis", "Jennifer Aniston", "Charlize Theron", "Cameron Diaz", "Nicole Kidman", "Meryl Streep", "Reese Witherspoon"] lb = Listbox(self, selectmode="multiple") for i in acts: lb.insert(END, i) lb.bind("<<ListboxSelect>>", self.onSelect) lb.pack(pady=15) self.var = StringVar() self.label = Label(self, text=0, textvariable=self.var) self.label.pack()
class MiniWindow: def __init__(self,root,list): self.list = list self.mini = Toplevel(root) self.mini.wm_title("Matches") print (root.winfo_screenwidth()) self.mini.geometry("%dx%d+%d+%d" %(500,200,root.winfo_x()+root.winfo_width(),root.winfo_y())) self.filelist = Listbox(self.mini) for item in self.list: self.filelist.insert('end',str(item)) self.filelist.bind("<<ListboxSelect>>",self.onClick) self.filelist.pack(fill="both") def onClick(self,event): print(self.filelist.curselection()) index = int(self.filelist.curselection()[0]) link = self.list[index] filedir = os.path.dirname(link) if os.name == 'nt': os.startfile(filedir) elif os.name == 'posix': subprocess.Popen(["xdg-open",filedir])
class Tenacity2(KRCCModule): def __init__(self, root): super().__init__() self.arbitrary_list = [ ('bla', random.uniform(0, 500)), ('blub', random.randint(1, 10)), ('hurrz', 'yolo'), 'sploink', ] self.listbox = Listbox(root) self.canvas = Canvas(root) self.load() def __del__(self): self.canvas.destroy() self.listbox.destroy() def run(self): while not self.terminate: pass def name(self): return 'Tenacity 2' def load(self): for item in self.arbitrary_list: insert_item = 'error' if type(item) == type(''): insert_item = item elif type(item) == type(()): key = item[0] value = '%s' % item[1] if type(item[1]) == float: value = '%8.3f' % item[1] insert_item = '%s: %s' % (key, value) self.listbox.insert(END, insert_item) self.listbox.pack(side=LEFT, fill=Y) self.canvas.pack(side=RIGHT, fill=BOTH, expand=True)
class MemoryWatcher(): def __init__(self, parent): # Window stuff self.parent = parent self.parent.geometry("200x300") self.frame = Frame(parent) # List box stuff self.index = 2 self.memory_listener = MemoryListener(self.action) self.listbox = Listbox(self.frame) # Initialize the UI self.initUI() def action(self, data): mem = data[0] val = data[1] self.listbox.insert(hex(self.index), ("[" + hex(mem) + "]: " + hex(val))) self.index += 1 def handle_close(self): self.memory_listener.unregister() self.parent.destroy() def initUI(self): # Deal with the UI self.parent.title("Memory Watcher") self.frame.pack(fill=BOTH, expand=1) self.listbox.insert(1, "Memory changed: ") self.listbox.pack(fill=BOTH, expand=1) # Handle the closing event (unregister the event listener) self.parent.protocol("WM_DELETE_WINDOW", self.handle_close)
class App(Tk): def __init__(self): Tk.__init__(self) self.title(TITLE) self.db = load(open("database.pickle", "rb")) self.codes = self.db["codes"] self.ids = self.db["ids"] self.searchScope = self.ids[:] self.outText = None self.scroll = None self.resetButton = None self.searchFrame = Frame(self) self.searchFrame.pack() self.searchLabel = Label(self.searchFrame, text="Search term:") self.searchLabel.pack(side=LEFT) self.searchSubFrame = Frame(self.searchFrame) self.searchSubFrame.pack(side=RIGHT) self.searchEntry = Entry(self.searchSubFrame) self.searchEntry.pack(side=LEFT) self.searchButtonsFrame = Frame(self.searchSubFrame) self.searchButtonsFrame.pack(side=RIGHT) self.searchButton = Button(self.searchButtonsFrame, text="Search", command=self.search) self.searchButton.pack(side=LEFT) self.display = Frame(self) self.display.pack(expand=TRUE, fill=BOTH) def outputLevel(self, *args): level = self.codes[self.searchScope[self.outText.curselection()[0]][0]] try: import pyperclip pyperclip.copy(level) except: import subprocess subprocess.Popen("clip", stdin=subprocess.PIPE).communicate(level.encode()) showinfo(TITLE, "Copied level code to clipboard!") def reset(self): self.outText.destroy() self.scroll.destroy() self.resetButton.destroy() self.searchScope = self.ids[:] self.outText = None self.scroll = None self.searchButton.config(text="Search") def search(self): if self.outText is not None: self.outText.destroy() self.scroll.destroy() else: self.searchButton.config(text="Refine search") self.resetButton = Button(self.searchButtonsFrame, text="Reset search", command=self.reset, fg="#FF0000") self.resetButton.pack(side=RIGHT) results = [] searchTerm = self.searchEntry.get() for i in self.searchScope: if any(searchTerm.lower() in j.lower() for j in i[1:3]): results.append(i) self.searchScope = results self.outText = Listbox(self.display, width=75, height=min(len(results), 15)) self.outText.pack(side=LEFT, expand=TRUE, fill=BOTH) self.outText.bind("<Double-1>", self.outputLevel) self.scroll = Scrollbar(self.display, orient="vertical") self.scroll.config(command=self.outText.yview) self.scroll.pack(side=RIGHT, fill=Y) self.outText.config(yscrollcommand=self.scroll.set) [ self.outText.insert(END, "{} by {}".format(i[1], i[2])) for i in results ]
class myGUIhandler: def verification_des_entrees(self): ''' vérifie que les entrées numériques sont bien des nombres ''' ok = 0 if not (str(self.entree3.get()).isdigit()): ok = 3 if not (str(self.entree5.get()).isdigit()): ok = 5 if not (str(self.entree7.get()).isdigit()): ok = 7 if not (self.entree8.get().find('@') != -1 and self.entree8.get().find('@') != 0 and self.entree8.get().find('@') != len(self.entree8.get()) - 1 and (self.entree8.get().split('@')[1].split('.')[1] == 'fr' or self.entree8.get().split('@')[1].split('.')[1] == 'com')): ok = 8 return ok def __init__(self, db): ''' self.entree vaut un widget Entry self.chaine vaut un widget Label ''' self.mot_de_passe = '' self.user = '' self.ident = None # Entry identifiant self.mdp = None # Entry mdp self.chaine = None # Label self.fen1 = None # Fenetre self.entree1 = None # name self.entree2 = None # lastname self.entree3 = None # number self.entree4 = None # street self.entree5 = None # zipcode self.entree6 = None # city self.entree7 = None # phone number self.entree8 = None # email self.entree9 = None # link_photo # on ne gère pas les images self.mdps = None # table des mots de passe self.db = db pass def verif_mdp(self, s): ''' vérification que le mot de passe à plus de 8 lettres(sauf admin) une minuscule, une majuscule ''' ok = False isnum = False isMaj = False isMin = False for x in s: if str.isdigit(x): isnum = True if str.isupper(x): isMaj = True if str.islower(x): isMin = True if isnum and isMaj and isMin: ok = True if len(self.mdp.get()) >= 8 and ok: pass else: messagebox.showerror( "Mot de passe non conforme", "8 chiffres avec une majuscule, une minuscule et un chiffre minimum" ) def evaluer3(self): ''' méthode pour créer un compte ''' if self.db == None: pass else: self.db.ecris_db_mdp( self.ident.get(), hashlib.md5(self.mdp.get().encode('UTF-8')).hexdigest()) self.mdps = self.db.readmdp() def evaluer2(self): ''' méthode pour vérifier la saisie lors du login ''' self.evaluer('') def evaluer(self, event): ''' méthode pour vérifier la saisie lors du login ''' if self.ident.get() == "admin": self.chaine.configure(text="Admin", fg="brown") else: self.chaine.configure(text="Etudiant", fg="green") if self.mdp.get() == "" or self.ident.get() == "": self.chaine.configure(text="Mdp ou identifiant vide", fg="red") else: # vérification du mot de passe uniquement pour etudiant if self.ident.get() != 'admin': self.verif_mdp(self.mdp.get()) #print ( mdps ) for x in self.mdps: user, mdp = x #'\uFEFF'.encode('UTF-8') if user == self.ident.get() and mdp == hashlib.md5( self.mdp.get().encode('UTF-8')).hexdigest(): print("Utilisateur ", user, "mot de passe ", mdp) self.mot_de_passe = self.ident.get() self.user = self.ident.get() if self.ident.get() != 'admin': self.mot_de_passe = 'etudiant' break if self.mot_de_passe == self.ident.get(): pass else: self.chaine.configure(text="Mot de passe non valide", fg="red") self.chaine.grid(row=2, column=1) if self.mot_de_passe == 'admin' or self.mot_de_passe == 'etudiant': self.fen1.quit() pass def display_login(self): ''' création de la fenêtre de login ''' # Création du widget principal ("maître") : self.fen1 = Tk() w = 220 # width for the Tk root h = 100 # height for the Tk root # get screen width and height ws = self.fen1.winfo_screenwidth() # width of the screen hs = self.fen1.winfo_screenheight() # height of the screen # calculate x and y coordinates for the Tk root window x = (ws / 2) - (w / 2) y = (hs / 2) - (h / 2) # set the dimensions of the screen # and where it is placed self.fen1.geometry('%dx%d+%d+%d' % (w, h, x, y)) if self.db == None: pass else: self.mdps = self.db.readmdp() self.fen1.title('Bienvenue sur ce site "Alumni"') bou1 = Button(self.fen1, text='CONNEXION', command=self.evaluer2) bou1.grid(row=3, column=0) bou2 = Button(self.fen1, text='CREER COMPTE', command=self.evaluer3) bou2.grid(row=3, column=1) labelPseudo = Label(self.fen1, text=" Identifiant", justify='right') labelPseudo.grid(row=0, column=0) self.ident = Entry(self.fen1) self.ident.bind("<Return>", self.evaluer) self.ident.grid(row=0, column=1) self.chaine = Label(self.fen1) self.chaine.grid(row=2, column=1) labelMdp = Label(self.fen1, text="Mot de passe", justify='right') labelMdp.grid(row=1, column=0) self.mdp = Entry(self.fen1, show="*") self.mdp.bind("<Return>", self.evaluer) self.mdp.grid(row=1, column=1) self.chaine = Label(self.fen1) self.chaine.grid(row=2, column=1) self.fen1.mainloop() # démarrage du réceptionnaire d’événements self.fen1.destroy() # destruction (fermeture) de la fenêtre return self.mot_de_passe def creer(self): ''' affiche le volet du formulaire de la fiche ''' entree1 = Label(self.fen2, text=" Name", justify='right') entree1.grid(row=1, column=0) self.entree1 = Entry(self.fen2) self.entree1.grid(row=1, column=1) entree2 = Label(self.fen2, text=" Lastname", justify='right') entree2.grid(row=2, column=0) self.entree2 = Entry(self.fen2) self.entree2.grid(row=2, column=1) entree3 = Label(self.fen2, text=" Numero", justify='right') entree3.grid(row=3, column=0) self.entree3 = Entry(self.fen2) self.entree3.grid(row=3, column=1) entree4 = Label(self.fen2, text="Street name ", justify='right') entree4.grid(row=4, column=0) self.entree4 = Entry(self.fen2) self.entree4.grid(row=4, column=1) entree5 = Label(self.fen2, text=" ZIP code", justify='right') entree5.grid(row=5, column=0) self.entree5 = Entry(self.fen2) self.entree5.grid(row=5, column=1) entree6 = Label(self.fen2, text=" City", justify='right') entree6.grid(row=6, column=0) self.entree6 = Entry(self.fen2) self.entree6.grid(row=6, column=1) entree7 = Label(self.fen2, text=" phone number", justify='right') entree7.grid(row=7, column=0) self.entree7 = Entry(self.fen2) self.entree7.grid(row=7, column=1) entree8 = Label(self.fen2, text=" email", justify='right') entree8.grid(row=8, column=0) self.entree8 = Entry(self.fen2) self.entree8.grid(row=8, column=1) entree9 = Label(self.fen2, text=" photo", justify='right') entree9.grid(row=9, column=0) self.entree9 = Entry(self.fen2) self.entree9.grid(row=9, column=1) bou1 = Button(self.fen2, text='CREER UNE FICHE', command=self.creation) bou1.grid(row=10, column=1) pass def creation(self): ''' créer la partie création de l'interface ''' if self.mot_de_passe == 'admin' or self.mot_de_passe == 'etudiant' and ( self.user.upper() == self.entree1.get().upper()): if self.verification_des_entrees() == 0: # Recherche d'un fiche existante l = self.db.read(1) trouve = False for e in l: if (e[0] == self.entree1.get()): trouve = True if not trouve: self.db.create([ self.entree1.get(), self.entree2.get(), self.entree3.get(), self.entree4.get(), self.entree5.get(), self.entree6.get(), self.entree7.get(), self.entree8.get(), self.entree9.get() ]) if self.mot_de_passe == 'admin': self.db.ecris_db_mdp( self.entree1.get(), hashlib.md5( (self.entree1.get().lower().capitalize() + self.entree1.get().lower() + "42").encode('UTF-8')).hexdigest()) else: messagebox.showwarning( "Création de fiche", "Fiche " + self.entree1.get() + " existe déjà !") else: messagebox.showinfo( "Vérification du format des entrées", "Champ n°" + str(self.verification_des_entrees()) + " en erreur") pass pass else: messagebox.showinfo( "Droit d'accès", "Pour créer la fiche " + self.entree1.get().upper() + ", il faut être admin ou vous pouvez uniquement créer votre fiche " + self.user.upper()) def consulter(self): ''' affiche sur la console et dans une listebox, les lignes tronquées de la table Students ''' lignes = self.db.read(1) self.fen3 = Tk() self.fen3.title('Visualisation des données alumni') scrollbar = Scrollbar(self.fen3) scrollbar.pack(side=RIGHT, fill=Y) self.listbox = Listbox(self.fen3, yscrollcommand=scrollbar.set, width=-1) self.listbox.bind("<ButtonRelease-1>", self.cliqueLigne) for i, l in enumerate(lignes): print(i, l) la = l[0][:15] la = la.ljust(15, ' ') la = la + l[1][:15] la = la.ljust(30, ' ') la = la + l[5][:15] la = la.ljust(45, ' ') self.listbox.insert(END, la) self.listbox.pack(side=LEFT, fill=BOTH) scrollbar.config(command=self.listbox.yview) self.fen3.mainloop() #self.fen3.destroy() def modifier(self): ''' Update à partir du nom de la fiche courante ''' if (self.entree1 == None or self.entree1.get() == ''): pass else: if self.mot_de_passe == 'admin' or self.mot_de_passe == 'etudiant' and ( self.user.upper() == self.entree1.get().upper()): self.db.update([ self.entree1.get(), self.entree2.get(), self.entree3.get(), self.entree4.get(), self.entree5.get(), self.entree6.get(), self.entree7.get(), self.entree8.get(), self.entree9.get() ]) else: messagebox.showinfo( "Droit d'accès", "Pour modifier la fiche " + self.entree1.get().upper() + ", il faut être admin ou vous pouvez modifier uniquement la fiche " + self.user.upper()) pass pass def supprimer(self): ''' supprime à partir des champs nom, city et email soient requis ''' if (self.entree1 == None or self.entree6 == None or self.entree8 == None or self.entree1.get() == '' or self.entree6.get() == '' or self.entree8.get() == ''): messagebox.showinfo( "Informations manquantes", "nom + city + email, doivent être renseignés pour supprimer.") else: print(self.mot_de_passe) print(self.user) print(self.entree1.get()) print(self.entree6.get()) print(self.entree8.get()) if self.mot_de_passe == 'admin' or self.mot_de_passe == 'etudiant' and ( self.user.upper() == self.entree1.get().upper()): self.db.deletes([ self.entree1.get(), self.entree6.get(), self.entree8.get() ]) else: messagebox.showinfo( "Droit d'accès", "Pour supprimer la fiche " + self.entree1.get().upper() + ", il faut être admin ou vous pouvez supprimer uniquement la fiche " + self.user.upper()) pass pass def cliqueLigne(self, event): ''' selection du numéro de ligne pour la listebox ''' try: nSel = self.listbox.curselection()[0] # sélection self.entree1.delete(0, len(self.entree1.get())) self.entree1.insert(0, self.listbox.get(nSel).split(' ') [0]) # get() renvoie un tuple ou une liste ? self.trouver() except: pass pass def trouver(self): ''' affiche dans la fiche, les informations trouvées dans la base pour le nom de la fiche ''' l = self.db.read(1) trouve = False for e in l: if (self.entree1 != None and e[0] == self.entree1.get()): trouve = True print("Trouvé ", e[0]) #self.entree1.set(e[0]) self.entree2.delete(0, len(self.entree2.get())) self.entree2.insert(0, e[1]) self.entree3.delete(0, len(self.entree3.get())) self.entree3.insert(0, e[2]) self.entree4.delete(0, len(self.entree4.get())) self.entree4.insert(0, e[3]) self.entree5.delete(0, len(self.entree5.get())) self.entree5.insert(0, e[4]) self.entree6.delete(0, len(self.entree6.get())) self.entree6.insert(0, e[5]) self.entree7.delete(0, len(self.entree7.get())) self.entree7.insert(0, e[6]) self.entree8.delete(0, len(self.entree8.get())) self.entree8.insert(0, e[7]) self.entree9.delete(0, len(self.entree9.get())) self.entree9.insert(0, e[8]) if not trouve: if self.entree1 != None: messagebox.showinfo( "Recherche fiche", "Fiche de " + self.entree1.get() + " non trouvée !") def display_form(self): ''' affiche l'interface Alumni pour CRUD ''' self.fen2 = Tk() if self.mot_de_passe == 'admin': self.fen2.title('Bienvenue sur ce site "Alumni" : droits ADMIN.') else: self.fen2.title('Bienvenue sur ce site "Alumni"') bou1 = Button(self.fen2, text='VOIR FICHE', command=self.creer) bou1.grid(row=0, column=0) bou1 = Button(self.fen2, text='CONSULTER', command=self.consulter) bou1.grid(row=0, column=1) #if self.mot_de_passe == 'admin': bou1 = Button(self.fen2, text='MODIFIER', command=self.modifier) bou2 = Button(self.fen2, text='SUPPRIMER', command=self.supprimer) bou3 = Button(self.fen2, text='TROUVER', command=self.trouver) #else: # bou1 = Button(self.fen2,text='MODIFIER',command=self.modifier,state=DISABLED) # bou2 = Button(self.fen2,text='SUPPRIMER',command=self.supprimer,state=DISABLED) bou1.grid(row=0, column=2) bou2.grid(row=0, column=3) bou3.grid(row=0, column=4) self.fen1.mainloop() # démarrage du réceptionnaire d’événements #fen1.destroy() # destruction (fermeture) de la fenêtre pass pass
class PypeTkPad(object): def __init__(self, master, queue, pypeOutput): self.queue = queue self.pypeOutput = pypeOutput self.master = master self.master.title('PypePad') self.master.geometry("%dx%d%+d%+d" % (700, 500, 0, 0)) self.master.minsize(300, 100) self.output_file_name = None self.BuildMainFrame() self.UpdateOutput() def NewCommand(self): self.ClearAllCommand() def OpenCommand(self): import tkinter.filedialog from tkinter import END openfile = tkinter.filedialog.askopenfile() if not openfile: return for line in openfile.readlines(): self.text_input.insert(END,line) def SaveCommand(self): import tkinter.filedialog from tkinter import END saveasfile = tkinter.filedialog.asksaveasfile() if not saveasfile: return alltext = self.text_input.get("1.0",END) saveasfile.write(alltext) def QuitCommand(self): self.master.quit() def ClearInputCommand(self): from tkinter import END self.text_input.delete("1.0",END) def ClearOutputCommand(self): from tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.delete("1.0",END) self.text_output["state"] = DISABLED self.text_output.see(END) self.text_output.update() def ClearAllCommand(self): self.ClearInputCommand() self.ClearOutputCommand() def OutputFileCommand(self): import tkinter.filedialog outputfilename = tkinter.filedialog.asksaveasfilename() if sys.platform == 'win32' and len(outputfilename.split()) > 1: outputfilename = '"%s"' % outputfilename self.output_file_name = outputfilename def AboutCommand(self): self.OutputText('\n') self.OutputText('* PypePad, Copyright (c) Luca Antiga, David Steinman. *\n') self.OutputText('\n') def UpdateOutput(self): if self.pypeOutput: text = self.pypeOutput.pop(0) self.output_stream.write(text) self.master.after(10,self.UpdateOutput) def RunPype(self,arguments): if not arguments: return if self.output_to_file.get() is not 'n' and self.output_file_name: self.output_stream.output_to_file = True self.output_stream.output_file = open(self.output_file_name,self.output_to_file.get()) else: self.output_stream.output_to_file = False self.queue.append(arguments) def GetWordUnderCursor(self): from tkinter import CURRENT splitindex = self.text_input.index(CURRENT).split('.') line = self.text_input.get(splitindex[0]+".0",splitindex[0]+".end") wordstart = line.rfind(' ',0,int(splitindex[1])-1)+1 wordend = line.find(' ',int(splitindex[1])) if wordend == -1: wordend = len(line) word = line[wordstart:wordend] return word def GetWordIndex(self): startindex = self.text_input.index("insert-1c wordstart") endindex = self.text_input.index("insert-1c wordend") if self.text_input.get(startindex+'-1c') == '-' and self.text_input.get(startindex+'-2c') == '-': startindex = self.text_input.index("insert-1c wordstart -2c") elif self.text_input.get(startindex+'-1c') == '-' and self.text_input.get(startindex+'-2c') == ' ': startindex = self.text_input.index("insert-1c wordstart -1c") self.wordIndex[0] = startindex self.wordIndex[1] = endindex word = self.text_input.get(self.wordIndex[0],self.wordIndex[1]) return word def GetLogicalLine(self,physicallineid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallineid]] def GetLogicalLineRange(self,physicallinefirstid,physicallinelastid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallinefirstid]:indexes[physicallinelastid]+1] def GetAllLogicalLines(self): return self.GetLogicalLines()[1] def GetLogicalLines(self): from tkinter import END # Python 2 hack to remove the u'...' prefix from unicode literal strings. does not change py3 behavior physicallines = [str(line) for line in self.text_input.get("1.0",END).split('\n')] lines = [] indexes = [0] * len(physicallines) lineid = 0 previousline = "" join = 0 for line in physicallines: if line.startswith('#'): if join: indexes[lineid] = indexes[lineid-1] elif join: if line.endswith('\\'): lines[-1] = lines[-1] + " " + line[:-1] join = 1 else: lines[-1] = lines[-1] + " " + line join = 0 indexes[lineid] = indexes[lineid-1] else: if line.endswith('\\'): join = 1 lines.append(line[:-1]) else: lines.append(line) join = 0 if lineid > 0: indexes[lineid] = indexes[lineid-1]+1 lineid += 1 return indexes, lines def GetLineUnderCursor(self): from tkinter import INSERT currentlineid = int(self.text_input.index(INSERT).split('.')[0]) - 1 return self.GetLogicalLine(currentlineid) def RunAllCommand(self): lines = self.GetAllLogicalLines() for line in lines: if line and line.strip(): self.RunPype(line) def RunLineCommand(self): line = self.GetLineUnderCursor() if line and line.strip(): self.RunPype(line) def RunSelectionCommand(self): from tkinter import TclError, SEL_FIRST, SEL_LAST try: firstlineid = int(self.text_input.index(SEL_FIRST).split('.')[0]) - 1 lastlineid = int(self.text_input.index(SEL_LAST).split('.')[0]) - 1 lines = self.GetLogicalLineRange(firstlineid,lastlineid) for line in lines: self.RunPype(line) except TclError: pass def GetSuggestionsList(self,word): list = [] try: from vmtk import vmtkscripts from vmtk import pypes except ImportError: return None if word.startswith('--'): list = ['--pipe','--help'] elif word.startswith('-'): optionlist = [] scriptindex = self.text_input.search('vmtk',self.wordIndex[0],backwards=1) moduleName = self.text_input.get( scriptindex,scriptindex+' wordend' ) try: module = importlib.import_module('vmtk.'+moduleName) # Find the principle class to instantiate the requested action defined inside the requested writerModule script. # Returns a single member list (containing the principle class name) which satisfies the following criteria: # 1) is a class defined within the script # 2) the class is a subclass of pypes.pypescript scriptObjectClasses = [x for x in dir(module) if isclass(getattr(module, x)) and issubclass(getattr(module, x), pypes.pypeScript)] scriptObjectClassName = scriptObjectClasses[0] scriptObject = getattr(module, scriptObjectClassName) scriptObject = scriptObject() members = scriptObject.InputMembers + scriptObject.OutputMembers for member in members: optionlist.append('-'+member.OptionName) list = [option for option in optionlist if option.count(word)] except: return list else: list = [scriptname for scriptname in vmtkscripts.__all__ if scriptname.count(word)] for index, item in enumerate(list): # check if scriptname contains starting prefix 'vmtk.' and remove it before returning list to the user. if 'vmtk.' == item[0:5]: splitList = item.split('.') list[index] = splitList[1] else: continue return list def FillSuggestionsList(self,word): from tkinter import END self.suggestionslist.delete(0,END) suggestions = self.GetSuggestionsList(word) for suggestion in suggestions: self.suggestionslist.insert(END,suggestion) def ReplaceTextCommand(self,word): self.text_input.delete(self.wordIndex[0],self.wordIndex[1]) self.text_input.insert(self.wordIndex[0],word) self.text_input.focus_set() def ShowHelpCommand(self): word = self.GetWordUnderCursor() self.OutputText(word) if word: self.RunPype(word+' --help') else: self.OutputText('Enter your vmtk Pype above and Run.\n') def AutoCompleteCommand(self): word = self.GetWordIndex() self.suggestionswindow.withdraw() if word: self.FillSuggestionsList(word) self.suggestionswindow.geometry("%dx%d%+d%+d" % (400, 150, self.text_output.winfo_rootx(),self.text_output.winfo_rooty())) self.suggestionswindow.deiconify() self.suggestionswindow.lift() def InsertScriptName(self,scriptname): from tkinter import INSERT self.text_input.insert(INSERT,scriptname+' ') def InsertFileName(self): from tkinter import INSERT import tkinter.filedialog openfilename = tkinter.filedialog.askopenfilename() if not openfilename: return if len(openfilename.split()) > 1: openfilename = '"%s"' % openfilename self.text_input.insert(INSERT,openfilename+' ') def KeyPressHandler(self,event): if event.keysym == "Tab" : self.AutoCompleteCommand() self.suggestionslist.focus_set() self.suggestionslist.selection_set(0) return "break" else: self.text_input.focus_set() def TopKeyPressHandler(self,event): from tkinter import ACTIVE, INSERT if event.keysym in ['Down','Up'] : self.suggestionslist.focus_set() elif event.keysym == "Return": word = self.suggestionslist.get(ACTIVE) self.ReplaceTextCommand(word) self.suggestionswindow.withdraw() self.text_input.focus_set() elif len(event.keysym) == 1 : self.suggestionswindow.withdraw() self.text_input.insert(INSERT,event.keysym) self.text_input.focus_set() else : self.suggestionswindow.withdraw() self.text_input.focus_set() def NewHandler(self,event): self.NewCommand() def OpenHandler(self,event): self.OpenCommand() def SaveHandler(self,event): self.SaveCommand() def InsertFileNameHandler(self,event): self.InsertFileName() return "break" def QuitHandler(self,event): self.QuitCommand() def ShowHelpHandler(self,event): self.ShowHelpCommand() def RunKeyboardHandler(self,event): from tkinter import SEL_FIRST, TclError try: self.text_input.index(SEL_FIRST) self.RunSelectionCommand() except TclError: self.RunLineCommand() return "break" def RunAllHandler(self,event): self.RunAllCommand() def PopupHandler(self,event): try: self.popupmenu.tk_popup(event.x_root, event.y_root, 0) finally: self.popupmenu.grab_release() def OutputText(self,text): from tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.insert(END,text) self.text_output["state"] = DISABLED def BuildScriptMenu(self,parentmenu,modulename): from tkinter import Menu menu = Menu(parentmenu,bd=1,activeborderwidth=0) try: module = importlib.import_module('vmtk.'+modulename) except ImportError: return None scriptnames = [scriptname for scriptname in getattr(module, '__all__')] for index, scriptname in enumerate(scriptnames): # check if scriptname contains starting prefix 'vmtk.' and remove it before returning list to the user. if 'vmtk.' == scriptname[0:5]: splitList = scriptname.split('.') scriptnames[index] = splitList[1] else: continue menulength = 20 for i in range(len(scriptnames)//menulength+1): subscriptnames = scriptnames[i*menulength:(i+1)*menulength] if not subscriptnames: break submenu = Menu(menu,bd=1,activeborderwidth=0) menu.add_cascade(label=subscriptnames[0]+"...",menu=submenu) for scriptname in subscriptnames: callback = CallbackShim(self.InsertScriptName,scriptname) submenu.add_command(label=scriptname,command=callback) return menu 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 DrtGlueDemo(object): def __init__(self, examples): # Set up the main window. self._top = Tk() self._top.title('DRT Glue Demo') # Set up key bindings. self._init_bindings() # Initialize the fonts.self._error = None self._init_fonts(self._top) self._examples = examples self._readingCache = [None for example in examples] # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Set the data to None self._curExample = -1 self._readings = [] self._drs = None self._drsWidget = None self._error = None self._init_glue() # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_exampleListbox(self._top) self._init_readingListbox(self._top) self._init_canvas(self._top) # Resize callback self._canvas.bind('<Configure>', self._configure) ######################################### ## Initialization Helpers ######################################### def _init_glue(self): tagger = RegexpTagger([ ('^(David|Mary|John)$', 'NNP'), ('^(walks|sees|eats|chases|believes|gives|sleeps|chases|persuades|tries|seems|leaves)$', 'VB'), ('^(go|order|vanish|find|approach)$', 'VB'), ('^(a)$', 'ex_quant'), ('^(every)$', 'univ_quant'), ('^(sandwich|man|dog|pizza|unicorn|cat|senator)$', 'NN'), ('^(big|gray|former)$', 'JJ'), ('^(him|himself)$', 'PRP') ]) depparser = MaltParser(tagger=tagger) self._glue = DrtGlue(depparser=depparser, remove_duplicates=False) def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget('size')) self._boldfont = Font(family='helvetica', weight='bold', size=self._size.get()) self._font = Font(family='helvetica', size=self._size.get()) if self._size.get() < 0: big = self._size.get() - 2 else: big = self._size.get() + 2 self._bigfont = Font(family='helvetica', weight='bold', size=big) def _init_exampleListbox(self, parent): self._exampleFrame = listframe = Frame(parent) self._exampleFrame.pack(fill='both', side='left', padx=2) self._exampleList_label = Label(self._exampleFrame, font=self._boldfont, text='Examples') self._exampleList_label.pack() self._exampleList = Listbox(self._exampleFrame, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._exampleList.pack(side='right', fill='both', expand=1) for example in self._examples: self._exampleList.insert('end', (' %s' % example)) self._exampleList.config(height=min(len(self._examples), 25), width=40) # Add a scrollbar if there are more than 25 examples. if len(self._examples) > 25: listscroll = Scrollbar(self._exampleFrame, orient='vertical') self._exampleList.config(yscrollcommand=listscroll.set) listscroll.config(command=self._exampleList.yview) listscroll.pack(side='left', fill='y') # If they select a example, apply it. self._exampleList.bind('<<ListboxSelect>>', self._exampleList_select) def _init_readingListbox(self, parent): self._readingFrame = listframe = Frame(parent) self._readingFrame.pack(fill='both', side='left', padx=2) self._readingList_label = Label(self._readingFrame, font=self._boldfont, text='Readings') self._readingList_label.pack() self._readingList = Listbox(self._readingFrame, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._readingList.pack(side='right', fill='both', expand=1) # Add a scrollbar if there are more than 25 examples. listscroll = Scrollbar(self._readingFrame, orient='vertical') self._readingList.config(yscrollcommand=listscroll.set) listscroll.config(command=self._readingList.yview) listscroll.pack(side='right', fill='y') self._populate_readingListbox() def _populate_readingListbox(self): # Populate the listbox with integers self._readingList.delete(0, 'end') for i in range(len(self._readings)): self._readingList.insert('end', (' %s' % (i + 1))) self._readingList.config(height=min(len(self._readings), 25), width=5) # If they select a example, apply it. self._readingList.bind('<<ListboxSelect>>', self._readingList_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind('<Control-q>', self.destroy) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Escape>', self.destroy) self._top.bind('n', self.next) self._top.bind('<space>', self.next) self._top.bind('p', self.prev) self._top.bind('<BackSpace>', self.prev) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill='none', side='bottom', padx=3, pady=2) Button( buttonframe, text='Prev', background='#90c0d0', foreground='black', command=self.prev, ).pack(side='left') Button( buttonframe, text='Next', background='#90c0d0', foreground='black', command=self.next, ).pack(side='left') def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas['scrollregion'] = '%d %d %d %d' % (x1, y1, x2, y2) self._redraw() def _init_canvas(self, parent): self._cframe = CanvasFrame( parent, background='white', #width=525, height=250, closeenough=10, border=2, relief='sunken') self._cframe.pack(expand=1, fill='both', side='top', pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='q') menubar.add_cascade(label='File', underline=0, menu=filemenu) actionmenu = Menu(menubar, tearoff=0) actionmenu.add_command(label='Next', underline=0, command=self.next, accelerator='n, Space') actionmenu.add_command(label='Previous', underline=0, command=self.prev, accelerator='p, Backspace') menubar.add_cascade(label='Action', underline=0, menu=actionmenu) optionmenu = Menu(menubar, tearoff=0) optionmenu.add_checkbutton(label='Remove Duplicates', underline=0, variable=self._glue.remove_duplicates, command=self._toggle_remove_duplicates, accelerator='r') menubar.add_cascade(label='Options', underline=0, menu=optionmenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old DRS, widgets, etc. if self._drsWidget is not None: self._drsWidget.clear() if self._drs: self._drsWidget = DrsWidget(self._canvas, self._drs) self._drsWidget.draw() if self._error: self._drsWidget = DrsWidget(self._canvas, self._error) self._drsWidget.draw() ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def prev(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or before) the first item if index <= 0: self._select_previous_example() else: self._readingList_store_selection(index - 1) else: #select its first reading self._readingList_store_selection(readingListSize - 1) else: self._select_previous_example() def _select_previous_example(self): #if the current example is not the first example if self._curExample > 0: self._exampleList_store_selection(self._curExample - 1) else: #go to the last example self._exampleList_store_selection(len(self._examples) - 1) def next(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # if there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or past) the last item if index >= (readingListSize - 1): self._select_next_example() else: self._readingList_store_selection(index + 1) else: #select its first reading self._readingList_store_selection(0) else: self._select_next_example() def _select_next_example(self): #if the current example is not the last example if self._curExample < len(self._examples) - 1: self._exampleList_store_selection(self._curExample + 1) else: #go to the first example self._exampleList_store_selection(0) def about(self, *e): ABOUT = ( "NLTK Discourse Representation Theory (DRT) Glue Semantics Demo\n" + "Written by Daniel H. Garrette") TITLE = 'About: NLTK DRT Glue Demo' try: from tkMessageBox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size + 2))) self._redraw() def _toggle_remove_duplicates(self): self._glue.remove_duplicates = not self._glue.remove_duplicates self._exampleList.selection_clear(0, 'end') self._readings = [] self._populate_readingListbox() self._readingCache = [None for ex in self._examples] self._curExample = -1 self._error = None self._drs = None self._redraw() def _exampleList_select(self, event): selection = self._exampleList.curselection() if len(selection) != 1: return self._exampleList_store_selection(int(selection[0])) def _exampleList_store_selection(self, index): self._curExample = index example = self._examples[index] self._exampleList.selection_clear(0, 'end') if example: cache = self._readingCache[index] if cache: if isinstance(cache, list): self._readings = cache self._error = None else: self._readings = [] self._error = cache else: try: self._readings = self._glue.parse_to_meaning(example) self._error = None self._readingCache[index] = self._readings except Exception as e: self._readings = [] self._error = DrtVariableExpression( Variable('Error: ' + str(e))) self._readingCache[index] = self._error #add a star to the end of the example self._exampleList.delete(index) self._exampleList.insert(index, (' %s *' % example)) self._exampleList.config(height=min( len(self._examples), 25), width=40) self._populate_readingListbox() self._exampleList.selection_set(index) self._drs = None self._redraw() def _readingList_select(self, event): selection = self._readingList.curselection() if len(selection) != 1: return self._readingList_store_selection(int(selection[0])) def _readingList_store_selection(self, index): reading = self._readings[index] self._readingList.selection_clear(0, 'end') if reading: self._readingList.selection_set(index) self._drs = reading.simplify().normalize().resolve_anaphora() self._redraw()
class ProblemBrowser(object): def __init__(self): self.action = None self.root = root = Tk() root.title('Never gonna fold you up') root.protocol("WM_DELETE_WINDOW", self.close) root.pack_propagate(True) scrollbar = Scrollbar(root, orient=tkinter.VERTICAL) self.problem_list = Listbox(root, exportselection=False, yscrollcommand=scrollbar.set) self.problem_list.pack(expand=True, fill=tkinter.BOTH, side=tkinter.LEFT) scrollbar.config(command=self.problem_list.yview) scrollbar.pack(side=tkinter.LEFT, fill=tkinter.Y) self.problem_list.bind('<<ListboxSelect>>', lambda evt: self.populate_problem_canvas()) self.problem_canvas = Canvas(root, bd=1, relief=tkinter.SUNKEN, width=500, height=500) self.problem_canvas.pack(expand=True, fill=tkinter.BOTH, side=tkinter.LEFT) self.problem_canvas.bind("<Configure>", lambda evt: self.populate_problem_canvas()) button_frame = Frame(root) button_frame.pack(fill=tkinter.Y, side=tkinter.LEFT) # Reposition the figure so it's center of mass is at 0.5, 0.5 v = IntVar() self.center_cb = Checkbutton(button_frame, text="center", variable=v, command=lambda: self.populate_problem_canvas()) self.center_cb.var = v self.center_cb.pack(side=tkinter.TOP) # Use meshes.reconstruct_facets instead of polygon/hole logic. v = IntVar() self.reconstruct_cb = Checkbutton(button_frame, text="reconstruct", variable=v, command=lambda: self.populate_problem_canvas()) self.reconstruct_cb.var = v self.reconstruct_cb.pack(side=tkinter.TOP) self.populate_problems() self.current_problem_name = None self.current_problem = None def populate_problems(self): self.problem_list.delete(0, tkinter.END) for file in sorted((get_root() / 'problems').iterdir()): self.problem_list.insert(tkinter.END, file.stem) def populate_problem_canvas(self): sel = self.problem_list.curselection() if not sel: return assert len(sel) == 1 name = self.problem_list.get(sel[0]) if name != self.current_problem_name: self.current_problem_name = name self.current_problem = load_problem(name) if self.current_problem: p = self.current_problem if self.center_cb.var.get(): p = center_problem(p) if self.reconstruct_cb.var.get(): facets = meshes.reconstruct_facets(p) facets = meshes.keep_real_facets(facets, p) skeleton = [e for f in facets for e in edges_of_a_facet(f)] p = Problem(facets, skeleton) draw_problem(self.problem_canvas, p) def run(self): self.root.mainloop() def close(self): if self.root: self.root.destroy() self.root = None
class App(Frame): version = "0.1" padding = 10 screenWidth = 800 screenHeight = 600 def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.py = pydle() self._initUI() def _initUI(self): self.parent.title("Pydle v" + self.version) self.parent.minsize(width=str(self.screenWidth), height=str(self.screenHeight)) # self.parent.config(border=0) # Styles style = Style() style.configure("TFrame", background="gray", border=0) style.configure("TButton", background="gray", foreground="lightgray", highlightforeground="black", highlightbackground="darkgray", compound=RIGHT, relief=FLAT) self.config(style="TFrame") self.pack(fill=BOTH, expand=1) # Menus mnuBar = Menu(self.parent) self.parent.config(menu=mnuBar) mnuFile = Menu(mnuBar, background="gray") mnuFile.add_command(label="Exit", command=self.onExitMnu) mnuBar.add_cascade(label="File", menu=mnuFile) mnuHelp = Menu(mnuBar, background="gray") mnuHelp.add_command(label="About", command=self.onAboutMnu) mnuBar.add_cascade(label="Help", menu=mnuHelp) # Frame content frmBooks = Frame(self, style="TFrame") frmBooks.pack(side=LEFT, anchor=N+W, fill=BOTH, expand=1, padx=(self.padding, self.padding / 2), pady=self.padding) self.lstBooks = Listbox(frmBooks) self.lstBooks.config(background="lightgray", foreground="black", borderwidth=0) self.lstBooks.pack(fill=BOTH, expand=1) frmButtons = Frame(self) frmButtons.pack(anchor=N+E, padx=(self.padding / 2, self.padding), pady=self.padding) btnLoadBooks = Button(frmButtons, text="Load Books", style="TButton", command=self.onLoadBooksBtn) btnLoadBooks.pack(side=TOP, fill=X) btnGetNotes = Button(frmButtons, text="Get Notes", style="TButton", command=self.onGetNotesBtn) btnGetNotes.pack(side=TOP, fill=X) btnBackupBook = Button(frmButtons, text="Backup Book", style="TButton", command=self.onBackupBtn) btnBackupBook.pack(side=TOP, fill=X) btnBackupAllBooks = Button(frmButtons, text="Backup All Books", style="TButton", command=self.onBackupAllBtn) btnBackupAllBooks.pack(side=TOP, fill=X) def onLoadBooksBtn(self): books = self.py.getBooks() for book in books: self.lstBooks.insert(END, book["name"]) def onBackupBtn(self): pass def onBackupAllBtn(self): pass def onGetNotesBtn(self): notes = self.py.getNotes() for note in notes: self.lstBooks.insert(END, note) def onAboutMnu(self): pass def onExitMnu(self): self.onExit() def onExit(self): self.quit()
class GUI: def __init__(self, load_data): self.bill = Accountant() # bill is our accountant. He is the person we make all financial requests to # loads all data if load_data: # flag controls whether program automatically loads data try: self.bill.load_data() except InvalidOperationError: # exception is raised when file is not found self.last_error = "Note: Ledger file not found. Starting fresh database" except IndexError: #exception is raised when file is corrupted self.last_error = "Error: Ledger file corrupted." getcontext().prec = 2 # function of decimal class to control decimal precision # create the root window root = Tk() root.title("Per Diem Tracker") w = 380 # width for the Tk root h = 200 # height for the Tk root # get screen width and height ws = root.winfo_screenwidth() # width of the screen hs = root.winfo_screenheight() # height of the screen # calculate x and y coordinates for the Tk root window x = (ws/2) - (w/2) y = (hs/2) - (h/2) # set the dimensions of the screen # and where it is placed root.geometry('%dx%d+%d+%d' % (w, h, x, y)) # define all objects top_frame = Frame(root) # for buttons middle_frame = Frame(root) # for list of Transactions bottom_frame = Frame(root) # for error window self.transactions = Listbox(middle_frame) self.errors = Label(bottom_frame, text="no errors") add_button = Button(top_frame, text = "Add Transaction", command=self.add_transaction) save_button = Button(top_frame, text = "Save") clear_button = Button(top_frame, text = "Clear Data") load_button = Button(top_frame, text = "Load Data") # pack everything load_button.pack(side=RIGHT) save_button.pack(side=RIGHT) clear_button.pack(side=RIGHT) add_button.pack(side=RIGHT) self.transactions.pack() self.transactions.insert(END, "Test") # this is test data self.populate_transactions_list() self.errors.pack() # finall, pack the two frames using grid layout top_frame.grid(row = 0) middle_frame.grid(row = 1) bottom_frame.grid(row = 2) root.mainloop() # this keeps our UI running def populate_transactions_list(self): # check if we have any transactions if self.bill.num_transactions() < 1: return for transaction in range(1, self.bill.num_transactions()): pass # finish method here return def add_transaction(self): # create a new window root = Tk() root.title("Add a Transaction") main_frame = Frame(root) w = 280 # width for the Tk root h = 120 # height for the Tk root # get screen width and height ws = root.winfo_screenwidth() # width of the screen hs = root.winfo_screenheight() # height of the screen # calculate x and y coordinates for the Tk root window x = (ws/2) - (w/2) y = (hs/2) - (h/2) # set the dimensions of the screen # and where it is placed root.geometry('%dx%d+%d+%d' % (w, h, x, y)) # create all objects date_label = Label(main_frame, text = "Date:") name_label = Label(main_frame, text = "Name:") amount_label = Label(main_frame, text = "Amount:") remarks_label = Label(main_frame, text = "Remarks:") self.date_entry = Entry(main_frame) self.name_entry = Entry(main_frame) self.amount_entry = Entry(main_frame) self.remarks_entry = Entry(main_frame) submit_button = Button(main_frame, text = "Submit", command = self.submit_transaction(root)) cancel_button = Button(main_frame, text = "Cancel", command = root.destroy) date_label.grid(row = 0, column = 0) self.date_entry.grid(row= 0, column = 1) name_label.grid(row = 1, column = 0) self.name_entry.grid(row = 1, column = 1) amount_label.grid(row = 2, column = 0) self.amount_entry.grid(row = 2, column = 1) remarks_label.grid(row = 3, column = 0) self.remarks_entry.grid(row = 3, column = 1) submit_button.grid(row = 4, column = 0) cancel_button.grid(row = 4, column = 1) main_frame.pack() root.mainloop() def submit_transaction(self, root): date = self.date_entry.get() try: formatted_date = datetime.date(int(date[:4]), int(date[4:6]), int(date[6:])) except (ValueError): # in case we got bad data self.errors.text = "Invalid date format" # todo: this is not executing correctly root.destroy
class TextSelect(Frame): def __init__(self, client, anchor, items, destroyAnchor=False): """ Args: client: [SelectionClient] The window that text is returned to. anchor: A window that the text selection popup is created relative to. items: [str], items to display in the listbox. destroyAnchor: [bool] if true, destroy the anchor after positioning the window. """ self.top = Toplevel() self.anchor = anchor self.top.overrideredirect(1) self.top.wm_geometry('+%s+%s' % (anchor.winfo_rootx() + anchor.winfo_x(), anchor.winfo_rooty() + anchor.winfo_y() ) ) super(TextSelect, self).__init__(self.top) self.entry = Entry(self) self.client = client self.items = items self.place(x = 0.5, y = 0.5, height = 100, width = 100) self.entry.bind('<Return>', self.close) self.entry.bind('<KeyPress>', self.filter) self.entry.bind('<Escape>', self.abort) self.entry.bind('<Up>', self.up) self.entry.bind('<Down>', self.down) self.entry.pack() # Create the list of items. self.list = Listbox(self) for item in self.items: self.list.insert('end', item) self.list.pack() self.grid() self.entry.focus() # Reposition the select button against the anchor. We defer this # until after idle so that the anchor has a chance to get rendered. def reposition(*args): self.top.wm_geometry('+%s+%s' % ( anchor.winfo_rootx(), anchor.winfo_rooty()) ) if destroyAnchor: anchor.destroy() self.after_idle(reposition) def close(self, event): sel = self.list.curselection() if sel: item = self.list.get(sel[0]) else: item = self.entry.get() # Note that the order of this appears to be significant: destroying # before selecting leaves the focus in a weird state. self.client.selected(item) self.top.destroy() return 'braek' def abort(self, event): self.top.destroy() self.client.aborted() return 'break' def up(self, event): sel = self.list.curselection() if not sel: self.list.selection_set(0) return 'break' sel = sel[0] print('sel is %s size is %s' % (sel, self.list.size())) if sel > 0: print('setting selection to %s' % sel) self.list.selection_clear(sel) self.list.selection_set(sel - 1) self.list.see(sel) return 'break' def down(self, event): sel = self.list.curselection() if not sel: self.list.selection_set(0) return 'break' sel = sel[0] print('sel is %s size is %s' % (sel, self.list.size())) if sel < self.list.size() - 1: print('setting selection to %s' % (sel + 1)) self.list.selection_clear(sel) self.list.selection_set(sel + 1) self.list.see(sel) return 'break' def filter(self, event): """Filter the listbox based on the contents of the entryfield.""" # first add the character to the entry. currentText = self.entry.get() print(event.keysym) if event.keysym == 'BackSpace': # Handle backspace specially. if currentText: currentText = currentText[:-1] self.entry.delete(0, 'end') self.entry.insert(0, currentText) else: return 'break' else: # Assume normal character. Insert it. self.entry.insert('insert', event.char) currentText += event.char self.list.delete(0, 'end') pattern = currentText.upper() for item in self.items: if pattern in item.upper(): self.list.insert('end', item) return 'break'
class windowFrame(Frame): def __init__(self, parent): self.Data = Data() self.getReciepList() Frame.__init__(self, parent) self.parent = parent self.recipeList = None # Listbox self.recipeName = None # Entry self.prepTime = None # Entry self.prepTimeUnit = None # OptionMenu self.cookTime = None # Entry self.cookTimeUnit = None # OptionMenu self.ingredientName = None # Entry self.ingredientQuantity = None # Entry self.ingredientUnit = None # OptionMenu self.ingredientList = None # Listbox self.procedure = None # Text self.recipes = [] self.ingredients = [] self.activeRecipeID = {"lst": None, "db": None} # (listID, dbID) self.activeIngredientID = {"lst": None, "db": None} # (listID, dbID) self.initUI() self.bind_all("<Control-w>", self.onExit) self.bind_all("<Control-s>", self.recipeSave) # display an error message to the user def msgError(self, error): print("error: " + error) showerror("ERROR!", error) # dispaly a warning to the user def msgWarning(self, warning): showwarning("Warning!", warning) # display caution message to user def msgCaution(self, caution): return askokcancel("Caution!", caution) # Get current ingredient selection from ingredient list def getIngredientSelection(self): if self.ingredients == []: self.msgWarning("No ingredient selected. Try loading a recipe.") return -1 else: return self.ingredientList.index(ACTIVE) # Get current recipe selection from recipe list def getRecipeSelection(self): if self.recipes == []: self.msgError("No recipes available.") return -1 else: selection = list(self.recipeList.curselection()) if selection == []: self.msgError("No recipe selected.") return -1 else: return selection # retrieve recipe list from the database def getReciepList(self): self.recipes = self.Data.dbGetRecipeList() # retrieve recipe info from the database by recipe ID def getRecipeInfo(self, recipeID): return self.Data.dbGetRecipeInfo(recipeID) # retrieve ingredient info from the database by ingredient ID def getIngredientInfo(self, ingredientID): return self.Data.dbGetIngredientInfo(ingredientID) # Populate the recipe list from a provided list of recipes def populateIngredientList(self, ingredients): self.ingredients = sorted(self.ingredients, key=itemgetter(-1)) self.ingredientList.delete(0, END) for ingredient in self.ingredients: ingredientName = str(ingredient[2]) ingredientQuantity = str(ingredient[3]) ingredientUnit = str(ingredient[4]) self.ingredientList.insert(END, ingredientQuantity + " " + ingredientUnit + " of " + ingredientName) # Populate the recipe list from a provided list of recipes def populateRecipeList(self, recipes): self.recipeList.delete(0, END) for recipe in [recipe[1] for recipe in recipes]: self.recipeList.insert(END, recipe) # save currently loaded ingredient info to database def ingredientSaveInfo(self): if self.activeIngredientID["lst"] == None: self.msgWarning("No ingredient is loaded.") else: print("Saving ingredient info") name = self.ingredientName.get() quantity = self.ingredientQuantity.get() unit = self.ingredientUnit.get() ingredient = self.ingredients[self.activeIngredientID["lst"]] print(ingredient) ingredient = (ingredient[0], ingredient[1], name, quantity, unit, ingredient[-1]) print(ingredient) self.ingredients[self.activeIngredientID["lst"]] = ingredient self.populateIngredientList(self.ingredients) # load active ingredient info into GUI elements def ingredientLoadInfo(self, ID=None): if ID == None: currentSelection = self.getIngredientSelection() if currentSelection == -1: return -1 else: self.activeIngredientID["lst"] = currentSelection self.activeIngredientID["db"] = self.ingredients[currentSelection][0] print("\n\nLoading ingredient info for ID " + str(self.activeIngredientID)) ingredient = self.ingredients[self.activeIngredientID["lst"]] elif ID >= 0: self.activeIngredientID["lst"] = ID self.activeIngredientID["db"] = self.ingredients[ID][0] ingredient = self.ingredients[self.activeIngredientID["lst"]] elif ID == -1: print("Clearing ingredient info...") self.activeIngredientID = {"lst": None, "db": None} ingredient = ["", "", "", "", ""] name = ingredient[2] quantity = ingredient[3] unit = ingredient[4] self.ingredientName.delete(0, END) self.ingredientName.insert(END, name) self.ingredientQuantity.delete(0, END) self.ingredientQuantity.insert(END, quantity) self.ingredientUnit.delete(0, END) self.ingredientUnit.insert(END, unit) # Move an ingredient further up in the ingredient list def ingredientMoveUp(self): currentSelection = self.getIngredientSelection() if currentSelection == -1: return -1 elif currentSelection > 0: if ( currentSelection == self.activeIngredientID["lst"] or currentSelection - 1 == self.activeIngredientID["lst"] ): if not self.msgCaution( "Reordering the actively loaded ingredient could cause duplicate and deleted entries when saving. Continue?" ): return print("ingredient %d up\n\n" % currentSelection) self.ingredients[currentSelection] = self.ingredients[currentSelection][0:-1] + ( self.ingredients[currentSelection][-1] - 1, ) self.ingredients[currentSelection - 1] = self.ingredients[currentSelection - 1][0:-1] + ( self.ingredients[currentSelection - 1][-1] + 1, ) self.populateIngredientList(self.ingredients) self.ingredientList.select_set(currentSelection - 1) self.ingredientList.event_generate("<<ListboxSelect>>") # Move an ingredient further down in the ingredient list def ingredientMoveDown(self): ##################################################### # Bug: when repeatedly pressing the down button, # # every press after the first switches the order of # # the first ingredient with the second ingredient. # ##################################################### currentSelection = self.getIngredientSelection() if currentSelection == -1: return -1 elif currentSelection < len(self.ingredients) - 1: if ( currentSelection == self.activeIngredientID["lst"] or currentSelection + 1 == self.activeIngredientID["lst"] ): if not self.msgCaution( "Reordering the actively loaded ingredient could cause duplicate and deleted entries when saving. Continue?" ): return print("ingredient %d down\n\n" % currentSelection) self.ingredients[currentSelection] = self.ingredients[currentSelection][0:-1] + ( self.ingredients[currentSelection][-1] + 1, ) self.ingredients[currentSelection + 1] = self.ingredients[currentSelection + 1][0:-1] + ( self.ingredients[currentSelection + 1][-1] - 1, ) self.populateIngredientList(self.ingredients) self.ingredientList.select_set(currentSelection + 1) self.ingredientList.event_generate("<<ListboxSelect>>") # Add an ingredient slot to the bottom of the list def ingredientAdd(self): if self.activeRecipeID["lst"] == None: self.msgWarning("No recipe loaded.") else: blankIngredient = (None, self.activeRecipeID["db"], "blank", "?", "?", len(self.ingredients)) self.ingredients.append(blankIngredient) self.populateIngredientList(self.ingredients) self.ingredientLoadInfo(len(self.ingredients) - 1) # Delete the currently selected ingredient def ingredientDelete(self): ####################################################### # BUG: when pressing the delete button several times, # # all but the first press just deletes the first # # ingredient in the list. # ####################################################### currentSelection = self.getIngredientSelection() if currentSelection == -1 or self.activeRecipeID["lst"] == None: return -1 elif currentSelection < len(self.ingredients) and currentSelection >= 0: print("remove ingredient %d\n\n" % currentSelection) del self.ingredients[currentSelection] for ingredient in range(currentSelection, len(self.ingredients)): self.ingredients[ingredient] = self.ingredients[ingredient][0:-1] + ( self.ingredients[ingredient][-1] - 1, ) self.populateIngredientList(self.ingredients) self.ingredientList.select_set(currentSelection) self.ingredientList.event_generate("<<ListboxSelect>>") print(self.ingredients) # Display help: about dialogue def helpAbout(self): print("Digital Cookbook v1.0 - Theodore Lindsey") aboutDialog = Toplevel() aboutDialog.geometry("200x100+300+300") aboutDialog.title("About Digital Cookbook") Message(aboutDialog, text="Digital Cookbook v1.0\nTheodore Lindsey").pack(side=TOP, fill=BOTH, expand=1) Button(aboutDialog, text="Ok", command=aboutDialog.destroy).pack(side=TOP) # Import recipe from XML file - need to implement def xmlImport(self): print("Importing XML file...") # add a recipe to the database and create a blank space for the recipe to go - need to implement def recipeAdd(self): print("Adding recipe...") # delete the currently selected recipe - need to implement def recipeDelete(self): recipeID = self.recipeList.curselection() print(recipeID) if len(recipeID) == 0: self.msgError("No recipes selected.") return elif len(recipeID) > 1: if not askokcancel("Caution!", "Are you sure you want to delete these %d recipes?" % len(recipeID)): return print("\nDeleting %d recipes..." % len(recipeID)) else: if not askokcancel("Caution!", "Are you sure you want to delete this recipe?"): return print("\nDeleting recipe %d..." % recipeID) blankrecipe = ((None, "", None, "", "", "", "", ""), []) self.recipeLoad(blankrecipe) # load currently selected recipe def recipeLoad(self, recipe=None): activeSelection = self.getRecipeSelection() if activeSelection == -1: return -1 elif len(activeSelection) > 1: self.msgError("Too many recipes selected.") return -1 else: if recipe == None: listID = activeSelection[0] self.activeRecipeID["lst"] = listID self.activeRecipeID["db"] = self.recipes[listID][0] print(self.activeRecipeID) recipe = self.getRecipeInfo(self.activeRecipeID["db"]) else: print("Clearing recipe info...") self.activeRecipeID = {"lst": None, "db": None} self.ingredientLoadInfo(-1) print(recipe) name = recipe[0][1] servings = recipe[0][2] prepTime = recipe[0][3] prepTimeUnits = recipe[0][4] cookTime = recipe[0][5] cookTimeUnits = recipe[0][6] procedure = recipe[0][7] self.ingredients = recipe[1] self.recipeName.delete(0, END) self.recipeName.insert(END, name) self.prepTime.delete(0, END) self.prepTime.insert(END, prepTime) self.cookTime.delete(0, END) self.cookTime.insert(END, cookTime) self.populateIngredientList(self.ingredients) self.procedure.delete(0.0, END) self.procedure.insert(END, procedure) # save changes to active recipe to database def recipeSave(self, event=""): print(self.activeRecipeID) if self.activeRecipeID["lst"] == None: self.msgError("No active recipe to save.") return -1 listID = self.activeRecipeID["lst"] dbID = self.activeRecipeID["db"] name = self.recipeName.get() servings = 0 # self.recipes[listID][2] prepTime = self.prepTime.get() prepUnit = None # self.prepTimeUnit.????() cookTime = self.cookTime.get() cookUnit = None # self.cookTimeUnit.????() procedure = self.procedure.get(0.0, END) recipeInfo = (dbID, name, servings, prepTime, prepUnit, cookTime, cookUnit, procedure) recipe = (recipeInfo, self.ingredients) self.recipes[listID] = (dbID, name) self.populateRecipeList(self.recipes) # quit the program def onExit(self, event=""): print("Quitting...") sys.exit(0) # Create the UI layout def initUI(self): self.parent.title("Digital Cookbook") self.style = Style() self.style.theme_use("default") self.pack(fill=BOTH, expand=1, side=BOTTOM) # Establish menu bar # menubar = Menu(self.parent) self.parent.config(menu=menubar) # Add file menu # filemenu = Menu(menubar, tearoff=0) menubar.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="Import recipe from XML file", command=self.xmlImport) filemenu.add_command(label="Add blank recipe to database", command=self.recipeAdd) filemenu.add_command(label="Delete recipe from database", command=self.recipeDelete) filemenu.add_command(label="Load recipe", command=self.recipeLoad) filemenu.add_command(label="Save recipe to database", command=self.recipeSave, accelerator="Ctrl+S") filemenu.add_separator() filemenu.add_command(label="Exit", command=self.onExit, accelerator="Ctrl+W") # Add help menu # helpmenu = Menu(menubar, tearoff=0) menubar.add_cascade(label="Help", menu=helpmenu) helpmenu.add_command(label="About...", command=self.helpAbout) # Establish toolbar # frameToolbar = Frame(self.parent) # , relief=RAISED, borderwidth=1) frameToolbar.pack(side=TOP, fill=X) # Add buttons to toolbar # buffer = 2 buttonspaceing = 100 buttonwidth = 12 buttonheight = 30 bImportXML = Button(frameToolbar, text="Import XML", command=self.xmlImport, width=buttonwidth) bImportXML.pack(side=LEFT, padx=buffer, pady=buffer) bAddRecipe = Button(frameToolbar, text="Add Recipe", command=self.recipeAdd, width=buttonwidth) bAddRecipe.pack(side=LEFT, padx=buffer, pady=buffer) bDeleteRecipe = Button(frameToolbar, text="Delete Recipe", command=self.recipeDelete, width=buttonwidth) bDeleteRecipe.pack(side=LEFT, padx=buffer, pady=buffer) bEditRecipe = Button(frameToolbar, text="Load Recipe", command=self.recipeLoad, width=buttonwidth) bEditRecipe.pack(side=LEFT, padx=buffer, pady=buffer) bSaveRecipe = Button(frameToolbar, text="Save Recipe", command=self.recipeSave, width=buttonwidth) bSaveRecipe.pack(side=LEFT, padx=buffer, pady=buffer) # Recipe list section frameRecipeList = Frame(self, borderwidth=1, width=200) frameRecipeList.pack_propagate(0) frameRecipeList.pack(side=LEFT, fill=Y) Label(frameRecipeList, text="Recipe List").pack() # Category option menu default = StringVar(frameRecipeList) default.set("----") recipeCatagories = OptionMenu(frameRecipeList, default, "----", "None", "Cat 1", "Cat 2", "Cat 3") recipeCatagories.pack(side=TOP, fill=X) # Filter Frame frameFilter = Frame(frameRecipeList, relief=RAISED, borderwidth=1, width=200) frameFilter.pack(side=TOP, fill=X) Label(frameFilter, text="Filter...").pack() # Filter text filterText = Entry(frameFilter) filterText.pack_propagate(0) filterText.pack(side=LEFT, fill=X) # Filter Button filterButton = Button(frameFilter, text="Go", command=self.placeholder) filterButton.pack_propagate(0) filterButton.pack(side=RIGHT) # Recipe Box Frame frameRecipeBox = Frame(frameRecipeList, relief=RAISED, borderwidth=1) frameRecipeBox.pack(side=TOP, fill=BOTH, expand=1) # ==== Recipe List box ==== recipeListScroll = Scrollbar(frameRecipeBox, orient=VERTICAL) self.recipeList = Listbox(frameRecipeBox, selectmode=EXTENDED, yscrollcommand=recipeListScroll.set) self.recipeList.pack(side=LEFT, fill=BOTH, expand=1) recipeListScroll.config(command=self.recipeList.yview) recipeListScroll.pack(side=RIGHT, fill=Y) self.getReciepList() self.populateRecipeList(self.recipes) # Spacer frameSpacer1 = Frame(self, borderwidth=1, width=10) frameSpacer1.pack_propagate(0) frameSpacer1.pack(side=LEFT, fill=Y) # Recipe info section frameRecipeInfo = Frame(self, borderwidth=1, width=200) frameRecipeInfo.pack_propagate(0) frameRecipeInfo.pack(side=LEFT, fill=Y) # Recipe name Label(frameRecipeInfo, text="Recipe Name:", anchor=E, justify=LEFT).pack() self.recipeName = Entry(frameRecipeInfo) self.recipeName.pack(side=TOP, fill=X) # Prep Time framePrepTime = Frame(frameRecipeInfo) framePrepTime.pack(side=TOP, fill=X) Label(framePrepTime, text="Prep Time:", anchor=E, justify=LEFT).pack() self.prepTime = Entry(framePrepTime) self.prepTime.pack(side=LEFT, fill=X) default = StringVar(framePrepTime) default.set("----") self.prepTimeUnit = OptionMenu(framePrepTime, default, "----", "Min", "Hr") self.prepTimeUnit.pack(side=RIGHT, fill=X) # Cook Time frameCookTime = Frame(frameRecipeInfo) frameCookTime.pack(side=TOP, fill=X) Label(frameCookTime, text="Cook Time:", anchor=E, justify=LEFT).pack() self.cookTime = Entry(frameCookTime) self.cookTime.pack(side=LEFT, fill=X) default = StringVar(frameCookTime) default.set("----") self.cookTimeUnit = OptionMenu(frameCookTime, default, "----", "Min", "Hr") self.cookTimeUnit.pack(side=RIGHT, fill=X) # Spacer frameSpacer2 = Frame(self, borderwidth=1, width=10) frameSpacer2.pack_propagate(0) frameSpacer2.pack(side=LEFT, fill=Y) # Ingredient List frameIngredients = Frame(self, borderwidth=1, width=300) frameIngredients.pack_propagate(0) frameIngredients.pack(side=LEFT, fill=Y) Label(frameIngredients, text="Ingredients").pack() # Ingredient Name self.ingredientName = Entry(frameIngredients) self.ingredientName.pack(side=TOP, fill=X) # Ingredient info frameIngredientQuantity = Frame(frameIngredients) frameIngredientQuantity.pack(side=TOP, fill=X) Label(frameIngredientQuantity, text="Ingredient Quantity (value, unit):", anchor=E, justify=LEFT).pack() self.ingredientQuantity = Entry(frameIngredientQuantity) self.ingredientQuantity.pack(side=LEFT, fill=X, expand=1) self.ingredientUnit = Entry(frameIngredientQuantity, width=20) self.ingredientUnit.pack_propagate(0) self.ingredientUnit.pack(side=RIGHT, fill=X) # Spacer frameSpacer3 = Frame(frameIngredients, height=10) frameSpacer3.pack_propagate(0) frameSpacer3.pack(side=TOP, fill=X) # Ingredient List buttons frameIngredientButtons = Frame(frameIngredients) frameIngredientButtons.pack(side=TOP, fill=X) ingredientAdd = Button(frameIngredientButtons, text="+", command=self.ingredientAdd, width=3) ingredientAdd.pack(side=LEFT) ingredientDel = Button(frameIngredientButtons, text="-", command=self.ingredientDelete, width=3) ingredientDel.pack(side=LEFT) ingredientUp = Button(frameIngredientButtons, text=u"\u25B2", command=self.ingredientMoveUp, width=3) ingredientUp.pack(side=LEFT) ingredientDwn = Button(frameIngredientButtons, text=u"\u25BC", command=self.ingredientMoveDown, width=3) ingredientDwn.pack(side=LEFT) ingredientLoad = Button(frameIngredientButtons, text="Load", command=self.ingredientLoadInfo) ingredientLoad.pack(side=LEFT) ingredientSave = Button(frameIngredientButtons, text="Save", command=self.ingredientSaveInfo) ingredientSave.pack(side=LEFT) # Ingredient List Box Frame frameIngredientList = Frame(frameIngredients, relief=RAISED, borderwidth=1) frameIngredientList.pack(side=TOP, fill=BOTH, expand=1) # Ingredient List box ingredientListScroll = Scrollbar(frameIngredientList, orient=VERTICAL) self.ingredientList = Listbox( frameIngredientList, selectmode=SINGLE, yscrollcommand=ingredientListScroll.set ) # Set selectmode=SINGLE???? self.ingredientList.pack(side=LEFT, fill=BOTH, expand=1) ingredientListScroll.config(command=self.ingredientList.yview) ingredientListScroll.pack(side=RIGHT, fill=Y) # Spacer frameSpacer4 = Frame(self, borderwidth=1, width=10) frameSpacer4.pack_propagate(0) frameSpacer4.pack(side=LEFT, fill=Y) # Recipe Procedure frameProcedure = Frame(self, borderwidth=1) frameProcedure.pack(side=LEFT, fill=BOTH, expand=1) Label(frameProcedure, text="Procedure", anchor=E, justify=LEFT).pack(side=TOP) procedureScroll = Scrollbar(frameProcedure, orient=VERTICAL) self.procedure = Text(frameProcedure, maxundo=30, undo=1, wrap=WORD, yscrollcommand=procedureScroll.set) self.procedure.pack(side=LEFT, fill=BOTH, expand=1) procedureScroll.config(command=self.procedure.yview) procedureScroll.pack(side=LEFT, fill=Y) # placeholder function for unimplemented UI elements def placeholder(self): print("Coming soon!")
class ChatGUI(Frame): def __init__(self, parent, conn, title): #Frame.__init__(self, parent, background="grey") self.parent = parent self.conn = conn self.title = title self.centerWindow() self.initUI() def initUI(self): self.lineCounter = 0 # create a custom font self.customFontHeader = font.Font(family="Calibri", slant = "italic") #family="Helvetica", weight="bold", slant="italic") self.customFontMessage = font.Font(family="Calibri") self.parent.title(self.title) frame = Frame(self.parent) frame.pack(fill=BOTH, expand=1, side=LEFT) self.box = ScrolledText(frame, wrap=WORD, relief = GROOVE, width=30, height=18, font=self.customFontMessage) self.box.insert(END, 'Welcome to Python Chat!') self.box.config(state=DISABLED) self.box.pack(expand="yes", fill=BOTH, side=TOP) self.textarea = Text(frame, width=30, height=5) #self.textarea.insert(END, "") self.textarea.bind("<KeyRelease-Return>", self.gettext) #Se metto on press, rimane una newline in piu self.textarea.pack(expand="yes", fill=BOTH, side=TOP) okButton = Button(frame, text="Panic Button", activebackground="red", command=self.sendFile) okButton.pack(expand="no", fill=BOTH, side=TOP) self.usersFrame = Frame(self.parent) self.usersFrame.pack(fill=BOTH, expand=1, side=RIGHT) self.userListbox = Listbox(self.usersFrame, width=3) self.userListbox.bind("<Double-Button-1>", self.privateChat) self.userListbox.pack(fill=BOTH, expand=1) self.updateUsersFrame() def centerWindow(self): w = 600 h = 475 sw = self.parent.winfo_screenwidth() sh = self.parent.winfo_screenheight() x = (sw - w)/2 y = (sh - h)/2 self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y)) def gettext(self, e): #e sta per event, questo e' un listener text = self.textarea.get("1.0", END + " - 2c") # 1.0: row:columa - END-2c rimuove l'ultimo carattere, una newline \r\n self.textarea.delete("0.0", END) #NON VA: il problema e' che viene inviato il carattere di newline ma non incluso nell'area a causa della bind mi sa. Devo escluderlo io self.sendToServer(text) def printConversation(self, message): self.box.config(state=NORMAL) self.box.insert(END,"\n" + message) self.lineCounter = self.lineCounter + 2 #m = re.match("\[.*\] From .*\n", self.box.get("0.0", END)) m = re.search("\[.*\].*:", message, re.MULTILINE) if m is not None: #print("MATCH") #print(m.group(0)) #print(str(m.start(0)) + "_" + str(m.end(0))) #print("COUNTER") #print(str(self.lineCounter) + "." + str(m.start(0)+1) + "___" + str(self.lineCounter) + "." + str(m.end(0))) self.box.tag_add("header", str(self.lineCounter) + "." + str(m.start(0)), str(self.lineCounter) + "." + str(m.end(0))) self.box.tag_config("header", font=self.customFontHeader, foreground = "blue") self.box.config(state=DISABLED) #self.box.yview_scroll(10000,"units") self.box.see(END) def sendToServer(self, messageToSend): self.conn.send(messageToSend.encode(encoding='utf_8', errors='strict')) def sendFile(self): #aprire una dialog di quelle predefinite (Sfoglia...) #capire come fare la send di un file sul socket... pass def updateUsersFrame(self): global connectedClients self.userListbox.delete(0, END) self.userListbox.insert(END, "Connected users") for item in connectedClients: self.userListbox.insert(END, item) #self.userListbox.update() #self.usersFrame.update() def privateChat(self, e): global conversationBoxList userselected = self.userListbox.selection_get() if not userselected == "Connected users": print("EVVAI CHAT PRIVATA con "+userselected) newWindow = Toplevel(self.parent) newWindow.title("Python Chat with "+userselected) newWindow.minsize(400, 475) newWindow.focus() def disconnectPM(): del conversationBoxList[userselected] newWindow.destroy() newWindow.protocol('WM_DELETE_WINDOW', disconnectPM) #label = Label(newWindow, text="PROVA PROVA") #label.pack(side="top", fill="both", padx=10, pady=10) frame = Frame(newWindow) frame.pack(fill=BOTH, expand=1, side=LEFT) box = ScrolledText(frame, wrap=WORD, relief = GROOVE, width=30, height=18, font=self.customFontMessage) box.config(state=DISABLED) box.pack(expand="yes", fill=BOTH, side=TOP) textarea = Text(frame, width=30, height=5) textarea.bind("<KeyRelease-Return>", lambda event : self.getprivatetext(event, textarea, userselected)) textarea.pack(expand="yes", fill=BOTH, side=TOP) #aggiungo alla mappa globale il box di conversazione conversationBoxList[userselected] = box def receivePrivateChat(self, connectingUser): global conversationBoxList print("CHAT PRIVATA in arrivo con "+connectingUser) newWindow = Toplevel(self.parent) newWindow.title("Python Chat requested by "+connectingUser) newWindow.minsize(400, 475) newWindow.focus() def disconnectPM(): del conversationBoxList[connectingUser] newWindow.destroy() newWindow.protocol('WM_DELETE_WINDOW', disconnectPM) #label = Label(newWindow, text="PROVA PROVA") #label.pack(side="top", fill="both", padx=10, pady=10) frame = Frame(newWindow) frame.pack(fill=BOTH, expand=1, side=LEFT) box = ScrolledText(frame, wrap=WORD, relief = GROOVE, width=30, height=18, font=self.customFontMessage) box.config(state=DISABLED) box.pack(expand="yes", fill=BOTH, side=TOP) textarea = Text(frame, width=30, height=5) textarea.bind("<KeyRelease-Return>", lambda event : self.getprivatetext(event, textarea, connectingUser)) textarea.pack(expand="yes", fill=BOTH, side=TOP) #aggiungo alla mappa globale il box di conversazione conversationBoxList[connectingUser] = box def getprivatetext(self, e, textarea, nickname): text = textarea.get("1.0", END + " - 2c") textarea.delete("0.0", END) self.sendToServer("##" + nickname + "##" + text) def setprivatetext(self, nickname, message, isLocalMessage): #isLocalMessage identifica un messaggio che mando io e che devo ri-ricevere nella mia finestra if isLocalMessage: for i in conversationBoxList.keys(): box = conversationBoxList[i] box.config(state=NORMAL) box.insert(END,"\n" + message) box.config(state=DISABLED) box.see(END) else: conversationbox = conversationBoxList[nickname] conversationbox.config(state=NORMAL) conversationbox.insert(END,"\n" + message) #self.lineCounter = self.lineCounter + 2 #m = re.match("\[.*\] From .*\n", self.box.get("0.0", END)) #m = re.search("\[.*\].*:", message, re.MULTILINE) ''' if m is not None: #print("MATCH") #print(m.group(0)) #print(str(m.start(0)) + "_" + str(m.end(0))) #print("COUNTER") #print(str(self.lineCounter) + "." + str(m.start(0)+1) + "___" + str(self.lineCounter) + "." + str(m.end(0))) self.box.tag_add("header", str(self.lineCounter) + "." + str(m.start(0)), str(self.lineCounter) + "." + str(m.end(0))) self.box.tag_config("header", font=self.customFontHeader, foreground = "blue") ''' conversationbox.config(state=DISABLED) #self.box.yview_scroll(10000,"units") conversationbox.see(END)
class ChatGUI(Frame): def __init__(self, parent, conn): #Frame.__init__(self, parent, background="grey") self.parent = parent self.conn = conn self.centerWindow() self.initUI() def initUI(self): self.lineCounter = 0 # create a custom font self.customFontHeader = font.Font(family="Calibri", slant = "italic") #family="Helvetica", weight="bold", slant="italic") self.customFontMessage = font.Font(family="Calibri") self.parent.title("Python Chat") frame = Frame(self.parent) frame.pack(fill=BOTH, expand=1, side=LEFT) self.box = ScrolledText(frame, wrap=WORD, relief = GROOVE, width=30, height=18, font=self.customFontMessage) self.box.insert(END, 'Welcome to Python Chat!') self.box.config(state=DISABLED) self.box.pack(expand="yes", fill=BOTH, side=TOP) self.textarea = Text(frame, width=30, height=5) #self.textarea.insert(END, "") self.textarea.bind("<KeyRelease-Return>", self.gettext) #Se metto on press, rimane una newline in piu self.textarea.pack(expand="yes", fill=BOTH, side=TOP) okButton = Button(frame, text="Panic Button", activebackground="red", command=self.sendFile) okButton.pack(expand="no", fill=BOTH, side=TOP) self.usersFrame = Frame(self.parent) self.usersFrame.pack(fill=BOTH, expand=1, side=RIGHT) self.userListbox = Listbox(self.usersFrame, width=3) self.userListbox.pack(fill=BOTH, expand=1) self.updateUsersFrame() def centerWindow(self): w = 600 h = 475 sw = self.parent.winfo_screenwidth() sh = self.parent.winfo_screenheight() x = (sw - w)/2 y = (sh - h)/2 self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y)) def gettext(self, e): #e sta per event, questo e' un listener text = self.textarea.get("1.0", END) # 1.0: row:columa - END-2c rimuove l'ultimo carattere, una newline \r\n if "\n" in text: text = text.replace("\n", "") self.textarea.delete("0.0", END) #NON VA: il problema e' che viene inviato il carattere di newline ma non incluso nell'area a causa della bind mi sa. Devo escluderlo io self.sendToServer(text) def printConversation(self, message): self.box.config(state=NORMAL) self.box.insert(END,"\n" + message) self.lineCounter = self.lineCounter + 2 #m = re.match("\[.*\] From .*\n", self.box.get("0.0", END)) m = re.search("\[.*\].*:", message, re.MULTILINE) if m is not None: #print("MATCH") #print(m.group(0)) #print(str(m.start(0)) + "_" + str(m.end(0))) #print("COUNTER") #print(str(self.lineCounter) + "." + str(m.start(0)+1) + "___" + str(self.lineCounter) + "." + str(m.end(0))) self.box.tag_add("header", str(self.lineCounter) + "." + str(m.start(0)), str(self.lineCounter) + "." + str(m.end(0))) self.box.tag_config("header", font=self.customFontHeader, foreground = "blue") self.box.config(state=DISABLED) #self.box.yview_scroll(10000,"units") self.box.see(END) def sendToServer(self, messageToSend): self.conn.send(messageToSend.encode(encoding='utf_8', errors='strict')) def sendFile(self): #aprire una dialog di quelle predefinite (Sfoglia...) #capire come fare la send di un file sul socket... pass def updateUsersFrame(self): global connectedClients self.userListbox.delete(0, END) self.userListbox.insert(END, "Connected users") for item in connectedClients: self.userListbox.insert(END, item)
class Window2(Frame): def __init__(self, parent, context): super(Window2, self).__init__(parent.Frame) context.add_observer(self) self.parent = parent self.context = context self.controller = parent.controller self._initialize() self.build() def _initialize(self): self.id = 'task' #画面遷移の順番を示す指示物 self.unit_name_list = [] def update(self, msg): self._gid = msg['gid'] self.unit_name_list = _global_group[msg['gid'] - 1] self._update_unit_name_list() self.task_lbx.delete(0, END) def convert(self): units = self._task_box.get(0, END) if not units: self.context.notify('root', 'info', "처리할 작업이 없습니다.") return working_dir = self.context.get('directory') if not working_dir: self.context.directory() working_dir = self.context.get('directory') if not working_dir: messagebox.showwarning("경고", '작업디렉토리가 설정되어 있지 않습니다.') return # html변환여부 체크옵션 _html = self.context.get('html') _gid = self._gid try: self.controller.convert(working_dir, _html, units, _gid) self.context.notify('root', 'info', "작업완료") messagebox.showinfo("알림", message="작업이 완료되었습니다.") except Exception as e: print(e) messagebox.showerror('포맷오류', '잘못된 포맷을 적용하였습니다.') self.context.notify('root', 'info', "작업오류") def build(self): componets = self.component_list() tasks = self.task_list() componets.pack(side="left", fill='y') componets.config(bg='steel blue3') tasks.pack(side='right', fill='both', expand=True) tasks.config(bg='light grey', padx=3) def _update_unit_name_list(self): self._list.delete(0, END) for i, name in enumerate(self.unit_name_list): self._list.insert(i, name) def component_list(self): #sandy brown fr1 = Frame(self) scrollbar = Scrollbar(fr1) scrollbar.pack(side="right", fill="y") self._list = Listbox(fr1, bg="dim grey", fg="white", width=20, yscrollcommand=scrollbar.set) mb1 = Menubutton(fr1, text='선택메뉴', relief='flat', bg='steel blue3') mb1.menu = Menu(mb1, tearoff=0) mb1['menu'] = mb1.menu mb1.menu.add_command(label='등록', command=self.choose_all) mb1.pack(side='bottom') mb1.menu.add_command(label='선택', command=lambda: self._list.select_set(0, END)) mb1.menu.add_command( label='해제', command=lambda: self._list.selection_clear(0, 'end')) self._list.pack(anchor="center", fill="both", expand=True, padx=3, pady=3) scrollbar.config(command=self._list.yview) self._list.config(highlightcolor='green', font=('나눔고딕', 10), activestyle='none', selectmode='extended') self._list.bind('<<ListboxSelect>>', self.select_item) self._list.bind('<Button-3>', self.sub_menu1) self._list.exportselection = 0 return fr1 def select_item(self, event): self.clear_submenu() widget = event.widget #print("select item",widget.curselection()) # if isinstance(widget,Listbox): v = widget.curselection() t = [widget.get(i) for i in v] self.context.notify('root', 'info', t) def clear_submenu(self): if hasattr(self, 'sub_fr'): self.sub_fr.destroy() def _setActivate(self, obj, index): obj.selection_set(index) # obj.see(index) # obj.activate(index) # obj.selection_anchor(index) def sub_menu1(self, event): self.clear_submenu() x, y = event.x, event.y self._setActivate(self._list, self._list.nearest(y)) self.sub_fr = Frame(self, height=10) b1 = Button(self.sub_fr, text='reg', command=self.choose_task, relief='flat') b1.pack(side='top', fill='both') self.sub_fr.place(x=x + 15, y=y) def choose_all(self): self.clear_submenu() for el in self._list.get(0, END): if not self._isduplicate(el): self._task_box.insert(END, el) def choose_task(self): self.clear_submenu() ixs = self._list.curselection() for ix in ixs: el = self._list.get(ix) if not self._isduplicate(el): self._task_box.insert(END, el) def _isduplicate(self, txt): for v in list(self._task_box.get(0, 'end')): if v == txt: return True return False def task_list(self): fr = Frame(self) fr_top = Frame(fr) task_lbx = Listbox(fr_top) task_lbx.pack(anchor="center", fill="both", expand=True, padx=3, pady=3) self._task_box = task_lbx fr_bot = Frame(fr, height='2') b1 = Menubutton(fr_bot, text='실행메뉴') b1.menu = Menu(b1, tearoff=0) b1['menu'] = b1.menu b1.menu.add_command(label='실행', command=self.convert) b1.menu.add_command(label='비우기', command=self.delete_task_item) b1.pack() fr_top.pack(side='top', fill='both', expand=True) fr_bot.pack(side='bottom', fill='x') task_lbx.config(highlightcolor='green', font=('굴림체', 10), activestyle='none', selectmode='extended') self.task_lbx = task_lbx return fr def delete_task_item(self): v = self.task_lbx.curselection() #print(v) if not v: self.task_lbx.delete(0, END) elif len(v) == 1: self.task_lbx.delete(v) else: self.task_lbx.delete(v[0], v[-1])
def main(s): ######################### tkinter界面设定 ##################################### import tkinter as tk window = tk.Tk() window.title('RYB打印驱动') window.geometry('300x100') window.resizable(0, 0) # canvas = tk.Canvas(window, width=800, height=900) # canvas.pack() s.root = window # window.mainloop() sb = Scrollbar(s.root) lb = Listbox(s.root, yscrollcommand=sb.set, width=280) sb.pack(side=RIGHT, fill=Y) lb.pack(side=LEFT, fill=Y) def checkTheard(): lb.pack(side=LEFT, fill=Y) sb.pack(side=RIGHT, fill=Y) lb.insert(END, ("-" * 100)) lb.insert(END, " 驱动程序启动成功,欢迎使用") lb.insert(END, (" 请最小化到托盘执行。。。。")) lb.insert(END, ("-" * 100)) socket = MySocket() jss = 0 while True: try: jss += 1 print("运行中") if socket.isRunning() is True: time.sleep(2) else: socket.restart() # lb.insert(END, "成功1") time.sleep(1) except Exception as e: lb.insert(END, e) button = tk.Button(s.root, text='Hit_me', width=20) t = threading.Thread(target=checkTheard) # 创建线程,如果函数里面有参数,args=() t.start() # 开启线程 sb.config(command=lb.yview) ########################### 开始托盘程序嵌入 ##################################### icons = os.getcwd() + r'\print64.ico' print(icons) hover_text = "RYB打印驱动" # 悬浮于图标上方时的提示 menu_options = () s.sysTrayIcon = SysTrayIcon(icons, hover_text, menu_options, on_quit=s.exit, default_menu_index=1) s.root.bind( "<Unmap>", lambda event: s.Unmap() if s.root.state() == 'iconic' else False) s.root.protocol('WM_DELETE_WINDOW', s.exit) s.root.resizable(0, 0) s.root.mainloop()
class ChatGUI(Frame): def __init__(self, parent, conn): #Frame.__init__(self, parent, background="grey") self.parent = parent self.conn = conn self.centerWindow() self.initUI() def initUI(self): self.lineCounter = 0 # create a custom font self.customFontHeader = font.Font( family="Calibri", slant="italic" ) #family="Helvetica", weight="bold", slant="italic") self.customFontMessage = font.Font(family="Calibri") self.parent.title("Python Chat") frame = Frame(self.parent) frame.pack(fill=BOTH, expand=1, side=LEFT) self.box = ScrolledText(frame, wrap=WORD, relief=GROOVE, width=30, height=18, font=self.customFontMessage) self.box.insert(END, 'Welcome to Python Chat!') self.box.config(state=DISABLED) self.box.pack(expand="yes", fill=BOTH, side=TOP) self.textarea = Text(frame, width=30, height=5) #self.textarea.insert(END, "") self.textarea.bind( "<KeyRelease-Return>", self.gettext) #Se metto on press, rimane una newline in piu self.textarea.pack(expand="yes", fill=BOTH, side=TOP) okButton = Button(frame, text="Panic Button", activebackground="red", command=self.sendFile) okButton.pack(expand="no", fill=BOTH, side=TOP) self.usersFrame = Frame(self.parent) self.usersFrame.pack(fill=BOTH, expand=1, side=RIGHT) self.userListbox = Listbox(self.usersFrame, width=3) self.userListbox.pack(fill=BOTH, expand=1) self.updateUsersFrame() def centerWindow(self): w = 600 h = 475 sw = self.parent.winfo_screenwidth() sh = self.parent.winfo_screenheight() x = (sw - w) / 2 y = (sh - h) / 2 self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y)) def gettext(self, e): #e sta per event, questo e' un listener text = self.textarea.get( "1.0", END ) # 1.0: row:columa - END-2c rimuove l'ultimo carattere, una newline \r\n if "\n" in text: text = text.replace("\n", "") self.textarea.delete( "0.0", END ) #NON VA: il problema e' che viene inviato il carattere di newline ma non incluso nell'area a causa della bind mi sa. Devo escluderlo io self.sendToServer(text) def printConversation(self, message): self.box.config(state=NORMAL) self.box.insert(END, "\n" + message) self.lineCounter = self.lineCounter + 2 #m = re.match("\[.*\] From .*\n", self.box.get("0.0", END)) m = re.search("\[.*\].*:", message, re.MULTILINE) if m is not None: #print("MATCH") #print(m.group(0)) #print(str(m.start(0)) + "_" + str(m.end(0))) #print("COUNTER") #print(str(self.lineCounter) + "." + str(m.start(0)+1) + "___" + str(self.lineCounter) + "." + str(m.end(0))) self.box.tag_add("header", str(self.lineCounter) + "." + str(m.start(0)), str(self.lineCounter) + "." + str(m.end(0))) self.box.tag_config("header", font=self.customFontHeader, foreground="blue") self.box.config(state=DISABLED) #self.box.yview_scroll(10000,"units") self.box.see(END) def sendToServer(self, messageToSend): self.conn.send(messageToSend.encode(encoding='utf_8', errors='strict')) def sendFile(self): #aprire una dialog di quelle predefinite (Sfoglia...) #capire come fare la send di un file sul socket... pass def updateUsersFrame(self): global connectedClients self.userListbox.delete(0, END) self.userListbox.insert(END, "Connected users") for item in connectedClients: self.userListbox.insert(END, item)
class ListChooserDialog: def __init__(self, parent, listEntries, guiPrompt, allowManualFolderSelection, forceFolderOnlyChoosing=False): """ NOTE: do not call this constructor directly. Use the ListChooserDialog.showDialog function instead. """ self.forceFolderOnlyChoosing = forceFolderOnlyChoosing self.top = tkinter.Toplevel(parent) defaultPadding = {"padx":20, "pady":10} # Set a description for this dialog (eg "Please choose a game to mod" tkinter.Label(self.top, text=guiPrompt).pack() # Define the main listbox to hold the choices given by the 'listEntries' parameter listboxFrame = tkinter.Frame(self.top) # Define a scrollbar and a listbox. The yscrollcommand is so that the listbox can control the scrollbar scrollbar = tkinter.Scrollbar(listboxFrame, orient=tkinter.VERTICAL) self.listbox = Listbox(listboxFrame, selectmode=tkinter.BROWSE, yscrollcommand=scrollbar.set) # Also configure the scrollbar to control the listbox, and pack it scrollbar.config(command=self.listbox.yview) scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y) # Setting width to 0 forces auto-resize of listbox see: https://stackoverflow.com/a/26504193/848627 for item in listEntries: self.listbox.insert(tkinter.END, item) self.listbox.config(width=0) self.listbox.pack(side=tkinter.LEFT, fill=tkinter.BOTH, expand=1) # Finally, pack the Frame so its contents are displayed on the dialog listboxFrame.pack(**defaultPadding) # If the user is allowed to choose a directory manually, add directory chooser button if allowManualFolderSelection: b2 = tkinter.Button(self.top, text="Choose Folder Manually", command=self.showDirectoryChooser) b2.pack(**defaultPadding) # Add an 'OK' button. When pressed, the dialog is closed b = tkinter.Button(self.top, text="OK", command=self.ok) b.pack(**defaultPadding) # This variable stores the returned value from the dialog self.result = None def showDirectoryChooser(self): if IS_MAC and not self.forceFolderOnlyChoosing: self.result = filedialog.askopenfilename(filetypes=[(None, "com.apple.application")]) else: self.result = filedialog.askdirectory() self.top.destroy() def ok(self): """ This function is called when the 'OK' button is pressed. It retrieves the value of the currently selected item, then closes the dialog :return: """ selected_value = None if len(self.listbox.curselection()) > 0: selected_index = self.listbox.curselection()[0] selected_value = self.listbox.get(selected_index) self.result = selected_value self.top.destroy() @staticmethod def showDialog(rootGUIWindow, choiceList, guiPrompt, allowManualFolderSelection, forceFolderOnlyChoosing=False): """ Static helper function to show dialog and get a return value. Arguments are the same as constructor :param rootGUIWindow: the parent tkinter object of the dialog (can be root window) :param choiceList: a list of strings that the user is to choose from :param guiPrompt: the description that will be shown on the dialog :param allowManualFolderSelection: if true, user is allowed to select a folder manually. :return: returns the value the user selected (string), or None if none available """ d = ListChooserDialog(rootGUIWindow, choiceList, guiPrompt, allowManualFolderSelection, forceFolderOnlyChoosing) rootGUIWindow.wait_window(d.top) return d.result
class ItemList(object): def __init__(self, title, width=115, height=10, bg="white", fg="black", font=("Consolas", 10), icon=None, selection=False): # Cria janela. self.__root = Tk() # Configura a janela. self.__root.resizable(False, False) self.__root.title(title) self.__root.iconbitmap(icon) self.__root.focus_force() # Cria uma barra de rolagem. scrollbar = Scrollbar(self.__root) scrollbar.pack(side="right", fill="y") # Cria lista de itens. self.__listbox = Listbox(self.__root, width=width, height=height, font=font) self.__listbox.config(yscrollcommand=scrollbar.set) self.__listbox.pack() # Configura a barra de rolagem. scrollbar.config(command=self.__listbox.yview) # Desativa o mecanismo de seleção da lista caso "selection" seja False. if not selection: self.__listbox.bindtags((self.__listbox, self.__root, "all")) else: self.__listbox.config(selectmode="SINGLE") self.__selection = selection def __close(self, event): """ Método do evento para fechar janela. """ self.__root.destroy() def run(self, list_, stopFunction, spacing=30): """ Coloca as strings dentro da lista e a executa dentro de um mainloop. """ # Evento para fechar a janela. self.__stopFunction = stopFunction self.__root.bind("<Escape>", self.__close) # Coloca os itens dentro da lista. for item in list_: # Caso tenha sido definido um espaçamento, será separado o título da descrição. if spacing and not isinstance(item, str): if len(item[0]) < spacing: item[0] += " " * (spacing - len(item[0])) else: item[0] = item[0][:spacing - 3] + "..." self.__listbox.insert(0, item[0] + " " + item[1]) # Caso não tenha sido definido um espaçamento, será colocado simplesmente o item à lista. else: self.__listbox.insert(0, item) # Atualiza a janela. self.__item = None self.__updater() self.__root.mainloop() # Retorna um item selecionado. return self.__item def __updater(self): """ Método para obter um item selecionado e verificar se o usuário deseja fechar a janela. """ # Obtém um item selecionado. if self.__selection: item = self.__listbox.curselection() if item: self.__item = self.__listbox.get(item[0]).strip() self.__root.destroy() # Caso o retorno da função seja True, ele irá parar de atualizar a janela. if not self.__stopFunction(): return self.__root.after(1, self.__updater) else: self.__root.destroy()
class DrtGlueDemo(object): def __init__(self, examples): # Set up the main window. self._top = Tk() self._top.title('DRT Glue Demo') # Set up key bindings. self._init_bindings() # Initialize the fonts.self._error = None self._init_fonts(self._top) self._examples = examples self._readingCache = [None for example in examples] # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Set the data to None self._curExample = -1 self._readings = [] self._drs = None self._drsWidget = None self._error = None self._init_glue() # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_exampleListbox(self._top) self._init_readingListbox(self._top) self._init_canvas(self._top) # Resize callback self._canvas.bind('<Configure>', self._configure) ######################################### ## Initialization Helpers ######################################### def _init_glue(self): tagger = RegexpTagger( [('^(David|Mary|John)$', 'NNP'), ('^(walks|sees|eats|chases|believes|gives|sleeps|chases|persuades|tries|seems|leaves)$', 'VB'), ('^(go|order|vanish|find|approach)$', 'VB'), ('^(a)$', 'ex_quant'), ('^(every)$', 'univ_quant'), ('^(sandwich|man|dog|pizza|unicorn|cat|senator)$', 'NN'), ('^(big|gray|former)$', 'JJ'), ('^(him|himself)$', 'PRP') ]) depparser = MaltParser(tagger=tagger) self._glue = DrtGlue(depparser=depparser, remove_duplicates=False) def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget('size')) self._boldfont = Font(family='helvetica', weight='bold', size=self._size.get()) self._font = Font(family='helvetica', size=self._size.get()) if self._size.get() < 0: big = self._size.get()-2 else: big = self._size.get()+2 self._bigfont = Font(family='helvetica', weight='bold', size=big) def _init_exampleListbox(self, parent): self._exampleFrame = listframe = Frame(parent) self._exampleFrame.pack(fill='both', side='left', padx=2) self._exampleList_label = Label(self._exampleFrame, font=self._boldfont, text='Examples') self._exampleList_label.pack() self._exampleList = Listbox(self._exampleFrame, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._exampleList.pack(side='right', fill='both', expand=1) for example in self._examples: self._exampleList.insert('end', (' %s' % example)) self._exampleList.config(height=min(len(self._examples), 25), width=40) # Add a scrollbar if there are more than 25 examples. if len(self._examples) > 25: listscroll = Scrollbar(self._exampleFrame, orient='vertical') self._exampleList.config(yscrollcommand = listscroll.set) listscroll.config(command=self._exampleList.yview) listscroll.pack(side='left', fill='y') # If they select a example, apply it. self._exampleList.bind('<<ListboxSelect>>', self._exampleList_select) def _init_readingListbox(self, parent): self._readingFrame = listframe = Frame(parent) self._readingFrame.pack(fill='both', side='left', padx=2) self._readingList_label = Label(self._readingFrame, font=self._boldfont, text='Readings') self._readingList_label.pack() self._readingList = Listbox(self._readingFrame, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._readingList.pack(side='right', fill='both', expand=1) # Add a scrollbar if there are more than 25 examples. listscroll = Scrollbar(self._readingFrame, orient='vertical') self._readingList.config(yscrollcommand = listscroll.set) listscroll.config(command=self._readingList.yview) listscroll.pack(side='right', fill='y') self._populate_readingListbox() def _populate_readingListbox(self): # Populate the listbox with integers self._readingList.delete(0, 'end') for i in range(len(self._readings)): self._readingList.insert('end', (' %s' % (i+1))) self._readingList.config(height=min(len(self._readings), 25), width=5) # If they select a example, apply it. self._readingList.bind('<<ListboxSelect>>', self._readingList_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind('<Control-q>', self.destroy) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Escape>', self.destroy) self._top.bind('n', self.next) self._top.bind('<space>', self.next) self._top.bind('p', self.prev) self._top.bind('<BackSpace>', self.prev) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill='none', side='bottom', padx=3, pady=2) Button(buttonframe, text='Prev', background='#90c0d0', foreground='black', command=self.prev,).pack(side='left') Button(buttonframe, text='Next', background='#90c0d0', foreground='black', command=self.next,).pack(side='left') def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas['scrollregion'] = '%d %d %d %d' % (x1,y1,x2,y2) self._redraw() def _init_canvas(self, parent): self._cframe = CanvasFrame(parent, background='white', #width=525, height=250, closeenough=10, border=2, relief='sunken') self._cframe.pack(expand=1, fill='both', side='top', pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='q') menubar.add_cascade(label='File', underline=0, menu=filemenu) actionmenu = Menu(menubar, tearoff=0) actionmenu.add_command(label='Next', underline=0, command=self.next, accelerator='n, Space') actionmenu.add_command(label='Previous', underline=0, command=self.prev, accelerator='p, Backspace') menubar.add_cascade(label='Action', underline=0, menu=actionmenu) optionmenu = Menu(menubar, tearoff=0) optionmenu.add_checkbutton(label='Remove Duplicates', underline=0, variable=self._glue.remove_duplicates, command=self._toggle_remove_duplicates, accelerator='r') menubar.add_cascade(label='Options', underline=0, menu=optionmenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old DRS, widgets, etc. if self._drsWidget is not None: self._drsWidget.clear() if self._drs: self._drsWidget = DrsWidget( self._canvas, self._drs ) self._drsWidget.draw() if self._error: self._drsWidget = DrsWidget( self._canvas, self._error ) self._drsWidget.draw() ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def prev(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or before) the first item if index <= 0: self._select_previous_example() else: self._readingList_store_selection(index-1) else: #select its first reading self._readingList_store_selection(readingListSize-1) else: self._select_previous_example() def _select_previous_example(self): #if the current example is not the first example if self._curExample > 0: self._exampleList_store_selection(self._curExample-1) else: #go to the last example self._exampleList_store_selection(len(self._examples)-1) def next(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # if there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or past) the last item if index >= (readingListSize-1): self._select_next_example() else: self._readingList_store_selection(index+1) else: #select its first reading self._readingList_store_selection(0) else: self._select_next_example() def _select_next_example(self): #if the current example is not the last example if self._curExample < len(self._examples)-1: self._exampleList_store_selection(self._curExample+1) else: #go to the first example self._exampleList_store_selection(0) def about(self, *e): ABOUT = ("NLTK Discourse Representation Theory (DRT) Glue Semantics Demo\n"+ "Written by Daniel H. Garrette") TITLE = 'About: NLTK DRT Glue Demo' try: from tkMessageBox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size+2))) self._redraw() def _toggle_remove_duplicates(self): self._glue.remove_duplicates = not self._glue.remove_duplicates self._exampleList.selection_clear(0, 'end') self._readings = [] self._populate_readingListbox() self._readingCache = [None for ex in self._examples] self._curExample = -1 self._error = None self._drs = None self._redraw() def _exampleList_select(self, event): selection = self._exampleList.curselection() if len(selection) != 1: return self._exampleList_store_selection(int(selection[0])) def _exampleList_store_selection(self, index): self._curExample = index example = self._examples[index] self._exampleList.selection_clear(0, 'end') if example: cache = self._readingCache[index] if cache: if isinstance(cache, list): self._readings = cache self._error = None else: self._readings = [] self._error = cache else: try: self._readings = self._glue.parse_to_meaning(example) self._error = None self._readingCache[index] = self._readings except Exception as e: self._readings = [] self._error = DrtVariableExpression(Variable('Error: ' + str(e))) self._readingCache[index] = self._error #add a star to the end of the example self._exampleList.delete(index) self._exampleList.insert(index, (' %s *' % example)) self._exampleList.config(height=min(len(self._examples), 25), width=40) self._populate_readingListbox() self._exampleList.selection_set(index) self._drs = None self._redraw() def _readingList_select(self, event): selection = self._readingList.curselection() if len(selection) != 1: return self._readingList_store_selection(int(selection[0])) def _readingList_store_selection(self, index): reading = self._readings[index] self._readingList.selection_clear(0, 'end') if reading: self._readingList.selection_set(index) self._drs = reading.simplify().normalize().resolve_anaphora() self._redraw()
class App: #----------------------------------------------------------------------------------- def ShowListFrame(self): self.listFrame.pack(fill=BOTH, side=TOP, padx=10, pady=0, expand=1) self.frameBottom.pack(fill=X, side=TOP, padx=10, pady=5, expand=0) #----------------------------------------------------------------------------------- def HideListFrame(self): self.listFrame.pack_forget() self.frameBottom.pack_forget() #----------------------------------------------------------------------------------- def PopulateListWithLinks(self): self.links = self.PowerPointApp.GetLinksFromSlides( int(self.root.winfo_x()) + int(self.root.winfo_width() / 2), int(self.root.winfo_y()) + int(self.root.winfo_height() / 2)) #print('back to index') if len(self.links) != 0: for item in self.links: #print(dict(item)) self.listbox.insert(END, str(item['link'])) #print('filled list') self.frameTopLabelSrc.config(text=self.PowerPointApp.FileName, ) #print('changed name') self.frameTopButtonFileOpen.config(text='Close file', command=self.ClosePPT) self.ShowListFrame() #print('end populate') #----------------------------------------------------------------------------------- def ReplaceSelected(self): for item in self.listbox.curselection(): text = self.listbox.get(item) text = text.replace(self.frameBottomFromInput.get(), self.frameBottomToInput.get()) #print(self.listbox.get(item), text) self.listbox.delete(item) self.listbox.insert(item, text) self.links[item]['link'] = text self.listbox.update() self.PowerPointApp.SetLinksInSlides( self.links, int(self.root.winfo_x()) + int(self.root.winfo_width() / 2), int(self.root.winfo_y()) + int(self.root.winfo_height() / 2)) #----------------------------------------------------------------------------------- def ClosePPT(self): if self.PowerPointApp.FileName != "": self.PowerPointApp.Close() self.listbox.delete(0, END) #print("Deleted list") self.frameTopLabelSrc.config(text='No file have been choosen') self.frameTopButtonFileOpen.config(text='Choose File', command=self.PopulateListWithLinks) self.HideListFrame() #print("Reset File Name") #----------------------------------------------------------------------------------- def ExitApp(self): if messagebox.askokcancel( title="Quit", message= "This action will close the powerpoint file and exit the program. Do you want to quit now?", parent=self.root): if self.PowerPointApp.FileName != "": self.PowerPointApp.Close() #print("Closed powerpoint") del self.frameBottomButton del self.frameBottomFromInput del self.frameBottomFromLabel del self.frameBottomToInput del self.frameBottomToLabel del self.frameBottom del self.frameTopLabelSrc del self.frameTopButtonFileOpen del self.frameTop del self.scrollbar del self.listbox del self.listFrame self.root.destroy() del self.root #print('Exiting now') return True #print('Didn\'t exit') #----------------------------------------------------------------------------------- def monitor_changes(self): registry = ConnectRegistry(None, HKEY_CURRENT_USER) key = OpenKey( registry, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize') mode = QueryValueEx(key, "AppsUseLightTheme") cnf = { 'mainWindow': { 'light': { 'bg': '#ddd' }, 'dark': { 'bg': '#0A2342' } }, 'frame': { 'light': { 'bg': '#ddd', 'fg': '#006ADF' }, 'dark': { 'bg': '#0A2342', 'fg': '#E8E6E1' } }, 'scrollbar': { 'light': { 'width': 12, 'elementborderwidth': 5 }, 'dark': { 'width': 12, 'elementborderwidth': 5 } }, 'label': { 'light': { 'bg': '#ddd', 'fg': '#000' }, 'dark': { 'bg': '#0A2342', 'fg': '#fff' } }, 'input': { 'light': { 'bg': '#EEEEEE', 'fg': '#212121' }, 'dark': { 'bg': '#798797', 'fg': '#FAFAFA' } }, 'button': { 'light': { 'bg': '#006ADF', 'fg': '#fff' }, 'dark': { 'bg': '#006ADF', 'fg': '#fff' } }, 'list': { 'light': { 'bg': '#ccc', 'fg': '#000', 'selectbackground': '#FF0056', 'selectforeground': '#FFFFFF' }, 'dark': { 'bg': '#07172A', 'fg': '#E8E6E1', 'selectbackground': '#A30037', 'selectforeground': '#FFFFFF' } } } if (self.root['bg'] != '#ddd' and mode[0]) or (self.root['bg'] != '#0A2342' and mode[0] == False): theme = 'light' if mode[0] else 'dark' color = cnf['mainWindow']['light'] if mode[0] else cnf[ 'mainWindow']['dark'] self.root.config(color) self.mainWindow.config(color) self.frameBottomGet.config(color) color = cnf['frame'][theme] self.frameBottom.config(color) self.frameTop.config(color) color = cnf['list'][theme] self.listbox.config(color) color = cnf['scrollbar'][theme] self.scrollbar.config(color) color = cnf['label'][theme] self.frameBottomToLabel.config(color) self.frameBottomFromLabel.config(color) self.frameTopLabelSrc.config(color) color = cnf['input'][theme] self.frameBottomFromInput.config(color) self.frameBottomToInput.config(color) color = cnf['button'][theme] self.frameTopButtonFileOpen.config(color) self.frameBottomButton.config(color) if len(self.listbox.curselection()) >= 1 and len( self.frameBottomFromInput.get()) > 0: self.frameBottomButton.config(state='normal') else: self.frameBottomButton.config(state=DISABLED) self.root.after(1000, self.monitor_changes) #----------------------------------------------------------------------------------- def __init__(self): # Initialize app container self.cnf = { 'font': { 'font': ('Inter', '9', 'bold') }, } self.root = Tk() self.root.title("Powerpoint Presentations Link Updater") self.root.geometry('650x350') self.root.minsize(650, 325) self.root.iconbitmap(r'.\trendence_black.ico') self.PowerPointApp = OfficeApp("PowerPoint.Application") self.FileName = 'No file have been choosen yet' # Create Main Window self.mainWindow = Frame(self.root) self.mainWindow.pack_propagate(0) self.mainWindow.pack(fill=BOTH, expand=1, side=LEFT, pady=5) self.mainWindow.grid_rowconfigure(0, weight=1) self.mainWindow.grid_columnconfigure(0, weight=1) # Links listbox self.listFrame = Frame(self.mainWindow) self.listbox = Listbox(self.listFrame) self.listbox.pack(expand=1, fill=BOTH, side=LEFT) self.scrollbar = Scrollbar(self.listFrame) self.scrollbar.pack(fill=Y, side=LEFT) self.scrollbar.config(command=self.listbox.yview) self.listbox.config(selectmode=EXTENDED, exportselection=False, highlightthickness=0, yscrollcommand=self.scrollbar.set) self.listbox.config(self.cnf['font']) # File Frame self.frameTop = LabelFrame(self.mainWindow, text='Choose File') self.frameTopButtonFileOpen = Button(self.frameTop) self.frameTopButtonFileOpen.grid(in_=self.frameTop, column=0, row=0, padx=10, pady=5) self.frameTopLabelSrc = Label(self.frameTop) self.frameTopLabelSrc.grid(column=1, row=0, padx=10, pady=5) self.frameTopLabelSrc.config({'text': self.FileName}) self.frameTopLabelSrc.config(self.cnf['font']) # Find and Replace Frame self.frameBottom = LabelFrame(self.mainWindow, text='Selected Links') self.frameBottomGet = Frame(self.frameBottom) self.frameBottomGet.pack(fill=X, side=TOP, padx=10, pady=0, expand=1) self.frameBottomFromLabel = Label(self.frameBottomGet, text='Replace') self.frameBottomFromLabel.pack(side=LEFT, padx=0, pady=0) self.frameBottomFromLabel.config(self.cnf['font']) self.frameBottomFromInput = Entry(self.frameBottomGet) self.frameBottomFromInput.pack(side=LEFT, fill=X, padx=0, pady=0, expand=1) self.frameBottomFromInput.config(self.cnf['font']) self.frameBottomToLabel = Label(self.frameBottomGet, text='With ') self.frameBottomToLabel.pack(side=LEFT, padx=0, pady=0) self.frameBottomToLabel.config(self.cnf['font']) self.frameBottomToInput = Entry(self.frameBottomGet) self.frameBottomToInput.pack(side=LEFT, fill=X, padx=0, pady=0, expand=1) self.frameBottomToInput.config(self.cnf['font']) self.frameBottomButton = Button(self.frameBottom) self.frameBottomButton.pack(fill=X, side=TOP, padx=10, pady=5, expand=1) self.frameBottomButton.config(text='Replace Selected', command=self.ReplaceSelected, height=1) self.frameBottomButton.config(self.cnf['font']) self.frameTop.pack(fill=X, side=TOP, padx=10, pady=5) self.frameTop.config(height=50) self.frameTop.config(self.cnf['font']) self.frameBottom.config(self.cnf['font']) self.frameTopButtonFileOpen.config(text='Choose a PowerPoint file', command=self.PopulateListWithLinks) self.frameTopButtonFileOpen.config(self.cnf['font']) self.root.protocol("WM_DELETE_WINDOW", self.ExitApp) self.monitor_changes() self.root.mainloop()
class Searcher(Frame): """ Keyword Searcher This is a very simple python program, which is designed for finding specified key-word in files. Just for fun! """ def __init__(self, master=None, cnf={}, **kwargs): super(Searcher, self).__init__(master, cnf, **kwargs) self._root_path_var = StringVar() self._keyword_var = StringVar(self) self._listbox = None self._result_queue = None self.pack(fill=BOTH, expand=YES, padx=5, pady=5) self.make_widgets() self._consumer() # config for main window self.master.title('Keyword Searcher') def make_widgets(self): frm1 = Frame(self) frm1.pack(side=TOP, fill=X) Entry(frm1, textvariable=self._root_path_var, font=DEFAULT_FONT).pack(side=LEFT, fill=X, expand=YES) Button(frm1, text='Add directory', font=DEFAULT_FONT, command=lambda: self._root_path_var.set(askdirectory(title='Add directory'))).pack(side=RIGHT) frm2 = Frame(self) frm2.pack(side=TOP, fill=X) keyword_ent = Entry(frm2, textvariable=self._keyword_var, font=DEFAULT_FONT) keyword_ent.pack(side=LEFT, fill=X, expand=YES) Button(frm2, text='Find', font=DEFAULT_FONT, command=self.find).pack(side=RIGHT) vs = Scrollbar(self) hs = Scrollbar(self) self._listbox = Listbox(self) vs.pack(side=RIGHT, fill=Y) vs.config(command=self._listbox.yview) hs.pack(side=BOTTOM, fill=X) hs.config(command=self._listbox.xview, orient='horizontal') self._listbox.config(yscrollcommand=vs.set, xscrollcommand=hs.set, font=DEFAULT_FONT) self._listbox.pack(fill=BOTH, expand=YES) self._listbox.bind('<Double-1>', self._navigate_to) def find(self): self._result_queue = queue.Queue() self._listbox.delete('0', 'end') Thread(target=self._find, args=(self._root_path_var.get(), self._keyword_var.get()), daemon=True).start() def _find(self, path, keyword): if not os.path.exists(path): return None for this_dir, sub_dirs, files in os.walk(path): for file in files: file_type = guess_type(file)[0] if file_type and 'text' in file_type: fp = os.path.join(this_dir, file) self._result_queue.put(fp) if keyword in open(fp).read() else None def _consumer(self): if self._result_queue: try: fp = self._result_queue.get(block=False) except queue.Empty: pass else: self._listbox.insert('end', fp) # auto scroll. self._listbox.yview('end') self.after(100, self._consumer) def _navigate_to(self, event): """ Only works on Ubuntu platform currently. Double click to navigate to selected path. It's a very convenient function. :return: None """ print(event) # get active item from listbox path = self._listbox.get('active') print(path) # open nautilus with param path, before that, check your platform. if 'ubuntu' in (os.popen('uname -a').read()).lower(): os.system('/usr/bin/nautilus {}'.format(path)) else: pass
from tkinter import Tk, Listbox, Label, END, simpledialog, Button import threading import boto3 root = Tk() root.title("Amazon Web Services") label = Label(root) label.pack() listbox = Listbox(root, width=85) listbox.pack() def main(): listbox.delete(0, END) ec2 = boto3.client('ec2') # Examples # print(ec2.describe_instances()['Reservations'][0]['Instances'][0]['InstanceId']) # print(ec2.describe_instances()['Reservations'][0]['Instances'][0]['SecurityGroups'][0]['GroupId']) # print(ec2.describe_instances()['Reservations'][0]['Instances'][0]['State']['Name']) label.config(text=( "| Instance ID | Public IP | State | Public DNS |" )) for a in ec2.describe_instances()['Reservations']: # pprint.pprint(a) for b in a['Instances']: # pprint.pprint(b)
class ShiftReduceApp(object): """ A graphical tool for exploring the shift-reduce parser. The tool displays the parser's stack and the remaining text, and allows the user to control the parser's operation. In particular, the user can shift tokens onto the stack, and can perform reductions on the top elements of the stack. A "step" button simply steps through the parsing process, performing the operations that ``nltk.parse.ShiftReduceParser`` would use. """ def __init__(self, grammar, sent, trace=0): self._sent = sent self._parser = SteppingShiftReduceParser(grammar, trace) # Set up the main window. self._top = Tk() self._top.title('Shift Reduce Parser Application') # Animations. animating_lock is a lock to prevent the demo # from performing new operations while it's animating. self._animating_lock = 0 self._animate = IntVar(self._top) self._animate.set(10) # = medium # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Initialize fonts. self._init_fonts(self._top) # Set up key bindings. self._init_bindings() # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_feedback(self._top) self._init_grammar(self._top) self._init_canvas(self._top) # A popup menu for reducing. self._reduce_menu = Menu(self._canvas, tearoff=0) # Reset the demo, and set the feedback frame to empty. self.reset() self._lastoper1['text'] = '' ######################################### ## Initialization Helpers ######################################### def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = tkinter.font.Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget('size')) self._boldfont = tkinter.font.Font(family='helvetica', weight='bold', size=self._size.get()) self._font = tkinter.font.Font(family='helvetica', size=self._size.get()) def _init_grammar(self, parent): # Grammar view. self._prodframe = listframe = Frame(parent) self._prodframe.pack(fill='both', side='left', padx=2) self._prodlist_label = Label(self._prodframe, font=self._boldfont, text='Available Reductions') self._prodlist_label.pack() self._prodlist = Listbox(self._prodframe, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._prodlist.pack(side='right', fill='both', expand=1) self._productions = list(self._parser.grammar().productions()) for production in self._productions: self._prodlist.insert('end', (' %s' % production)) self._prodlist.config(height=min(len(self._productions), 25)) # Add a scrollbar if there are more than 25 productions. if 1:#len(self._productions) > 25: listscroll = Scrollbar(self._prodframe, orient='vertical') self._prodlist.config(yscrollcommand = listscroll.set) listscroll.config(command=self._prodlist.yview) listscroll.pack(side='left', fill='y') # If they select a production, apply it. self._prodlist.bind('<<ListboxSelect>>', self._prodlist_select) # When they hover over a production, highlight it. self._hover = -1 self._prodlist.bind('<Motion>', self._highlight_hover) self._prodlist.bind('<Leave>', self._clear_hover) def _init_bindings(self): # Quit self._top.bind('<Control-q>', self.destroy) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Alt-q>', self.destroy) self._top.bind('<Alt-x>', self.destroy) # Ops (step, shift, reduce, undo) self._top.bind('<space>', self.step) self._top.bind('<s>', self.shift) self._top.bind('<Alt-s>', self.shift) self._top.bind('<Control-s>', self.shift) self._top.bind('<r>', self.reduce) self._top.bind('<Alt-r>', self.reduce) self._top.bind('<Control-r>', self.reduce) self._top.bind('<Delete>', self.reset) self._top.bind('<u>', self.undo) self._top.bind('<Alt-u>', self.undo) self._top.bind('<Control-u>', self.undo) self._top.bind('<Control-z>', self.undo) self._top.bind('<BackSpace>', self.undo) # Misc self._top.bind('<Control-p>', self.postscript) self._top.bind('<Control-h>', self.help) self._top.bind('<F1>', self.help) self._top.bind('<Control-g>', self.edit_grammar) self._top.bind('<Control-t>', self.edit_sentence) # Animation speed control self._top.bind('-', lambda e,a=self._animate:a.set(20)) self._top.bind('=', lambda e,a=self._animate:a.set(10)) self._top.bind('+', lambda e,a=self._animate:a.set(4)) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill='none', side='bottom') Button(buttonframe, text='Step', background='#90c0d0', foreground='black', command=self.step,).pack(side='left') Button(buttonframe, text='Shift', underline=0, background='#90f090', foreground='black', command=self.shift).pack(side='left') Button(buttonframe, text='Reduce', underline=0, background='#90f090', foreground='black', command=self.reduce).pack(side='left') Button(buttonframe, text='Undo', underline=0, background='#f0a0a0', foreground='black', command=self.undo).pack(side='left') def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Reset Parser', underline=0, command=self.reset, accelerator='Del') filemenu.add_command(label='Print to Postscript', underline=0, command=self.postscript, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label='Edit Grammar', underline=5, command=self.edit_grammar, accelerator='Ctrl-g') editmenu.add_command(label='Edit Text', underline=5, command=self.edit_sentence, accelerator='Ctrl-t') menubar.add_cascade(label='Edit', underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label='Step', underline=1, command=self.step, accelerator='Space') rulemenu.add_separator() rulemenu.add_command(label='Shift', underline=0, command=self.shift, accelerator='Ctrl-s') rulemenu.add_command(label='Reduce', underline=0, command=self.reduce, accelerator='Ctrl-r') rulemenu.add_separator() rulemenu.add_command(label='Undo', underline=0, command=self.undo, accelerator='Ctrl-u') menubar.add_cascade(label='Apply', underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton(label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar) viewmenu.add_separator() viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animate, value=0) animatemenu.add_radiobutton(label="Slow Animation", underline=0, variable=self._animate, value=20, accelerator='-') animatemenu.add_radiobutton(label="Normal Animation", underline=0, variable=self._animate, value=10, accelerator='=') animatemenu.add_radiobutton(label="Fast Animation", underline=0, variable=self._animate, value=4, accelerator='+') menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) helpmenu.add_command(label='Instructions', underline=0, command=self.help, accelerator='F1') menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar) def _init_feedback(self, parent): self._feedbackframe = feedbackframe = Frame(parent) feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3) self._lastoper_label = Label(feedbackframe, text='Last Operation:', font=self._font) self._lastoper_label.pack(side='left') lastoperframe = Frame(feedbackframe, relief='sunken', border=1) lastoperframe.pack(fill='x', side='right', expand=1, padx=5) self._lastoper1 = Label(lastoperframe, foreground='#007070', background='#f0f0f0', font=self._font) self._lastoper2 = Label(lastoperframe, anchor='w', width=30, foreground='#004040', background='#f0f0f0', font=self._font) self._lastoper1.pack(side='left') self._lastoper2.pack(side='left', fill='x', expand=1) def _init_canvas(self, parent): self._cframe = CanvasFrame(parent, background='white', width=525, closeenough=10, border=2, relief='sunken') self._cframe.pack(expand=1, fill='both', side='top', pady=2) canvas = self._canvas = self._cframe.canvas() self._stackwidgets = [] self._rtextwidgets = [] self._titlebar = canvas.create_rectangle(0,0,0,0, fill='#c0f0f0', outline='black') self._exprline = canvas.create_line(0,0,0,0, dash='.') self._stacktop = canvas.create_line(0,0,0,0, fill='#408080') size = self._size.get()+4 self._stacklabel = TextWidget(canvas, 'Stack', color='#004040', font=self._boldfont) self._rtextlabel = TextWidget(canvas, 'Remaining Text', color='#004040', font=self._boldfont) self._cframe.add_widget(self._stacklabel) self._cframe.add_widget(self._rtextlabel) ######################################### ## Main draw procedure ######################################### def _redraw(self): scrollregion = self._canvas['scrollregion'].split() (cx1, cy1, cx2, cy2) = [int(c) for c in scrollregion] # Delete the old stack & rtext widgets. for stackwidget in self._stackwidgets: self._cframe.destroy_widget(stackwidget) self._stackwidgets = [] for rtextwidget in self._rtextwidgets: self._cframe.destroy_widget(rtextwidget) self._rtextwidgets = [] # Position the titlebar & exprline (x1, y1, x2, y2) = self._stacklabel.bbox() y = y2-y1+10 self._canvas.coords(self._titlebar, -5000, 0, 5000, y-4) self._canvas.coords(self._exprline, 0, y*2-10, 5000, y*2-10) # Position the titlebar labels.. (x1, y1, x2, y2) = self._stacklabel.bbox() self._stacklabel.move(5-x1, 3-y1) (x1, y1, x2, y2) = self._rtextlabel.bbox() self._rtextlabel.move(cx2-x2-5, 3-y1) # Draw the stack. stackx = 5 for tok in self._parser.stack(): if isinstance(tok, Tree): attribs = {'tree_color': '#4080a0', 'tree_width': 2, 'node_font': self._boldfont, 'node_color': '#006060', 'leaf_color': '#006060', 'leaf_font':self._font} widget = tree_to_treesegment(self._canvas, tok, **attribs) widget.node()['color'] = '#000000' else: widget = TextWidget(self._canvas, tok, color='#000000', font=self._font) widget.bind_click(self._popup_reduce) self._stackwidgets.append(widget) self._cframe.add_widget(widget, stackx, y) stackx = widget.bbox()[2] + 10 # Draw the remaining text. rtextwidth = 0 for tok in self._parser.remaining_text(): widget = TextWidget(self._canvas, tok, color='#000000', font=self._font) self._rtextwidgets.append(widget) self._cframe.add_widget(widget, rtextwidth, y) rtextwidth = widget.bbox()[2] + 4 # Allow enough room to shift the next token (for animations) if len(self._rtextwidgets) > 0: stackx += self._rtextwidgets[0].width() # Move the remaining text to the correct location (keep it # right-justified, when possible); and move the remaining text # label, if necessary. stackx = max(stackx, self._stacklabel.width()+25) rlabelwidth = self._rtextlabel.width()+10 if stackx >= cx2-max(rtextwidth, rlabelwidth): cx2 = stackx + max(rtextwidth, rlabelwidth) for rtextwidget in self._rtextwidgets: rtextwidget.move(4+cx2-rtextwidth, 0) self._rtextlabel.move(cx2-self._rtextlabel.bbox()[2]-5, 0) midx = (stackx + cx2-max(rtextwidth, rlabelwidth))/2 self._canvas.coords(self._stacktop, midx, 0, midx, 5000) (x1, y1, x2, y2) = self._stacklabel.bbox() # Set up binding to allow them to shift a token by dragging it. if len(self._rtextwidgets) > 0: def drag_shift(widget, midx=midx, self=self): if widget.bbox()[0] < midx: self.shift() else: self._redraw() self._rtextwidgets[0].bind_drag(drag_shift) self._rtextwidgets[0].bind_click(self.shift) # Draw the stack top. self._highlight_productions() def _draw_stack_top(self, widget): # hack.. midx = widget.bbox()[2]+50 self._canvas.coords(self._stacktop, midx, 0, midx, 5000) def _highlight_productions(self): # Highlight the productions that can be reduced. self._prodlist.selection_clear(0, 'end') for prod in self._parser.reducible_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) ######################################### ## Button Callbacks ######################################### def destroy(self, *e): if self._top is None: return self._top.destroy() self._top = None def reset(self, *e): self._parser.initialize(self._sent) self._lastoper1['text'] = 'Reset App' self._lastoper2['text'] = '' self._redraw() def step(self, *e): if self.reduce(): return 1 elif self.shift(): return 1 else: if len(self._parser.parses()) > 0: self._lastoper1['text'] = 'Finished:' self._lastoper2['text'] = 'Success' else: self._lastoper1['text'] = 'Finished:' self._lastoper2['text'] = 'Failure' def shift(self, *e): if self._animating_lock: return if self._parser.shift(): tok = self._parser.stack()[-1] self._lastoper1['text'] = 'Shift:' self._lastoper2['text'] = '%r' % tok if self._animate.get(): self._animate_shift() else: self._redraw() return 1 return 0 def reduce(self, *e): if self._animating_lock: return production = self._parser.reduce() if production: self._lastoper1['text'] = 'Reduce:' self._lastoper2['text'] = '%s' % production if self._animate.get(): self._animate_reduce() else: self._redraw() return production def undo(self, *e): if self._animating_lock: return if self._parser.undo(): self._redraw() def postscript(self, *e): self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) ######################################### ## Menubar callbacks ######################################### def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) #self._stacklabel['font'] = ('helvetica', -size-4, 'bold') #self._rtextlabel['font'] = ('helvetica', -size-4, 'bold') #self._lastoper_label['font'] = ('helvetica', -size) #self._lastoper1['font'] = ('helvetica', -size) #self._lastoper2['font'] = ('helvetica', -size) #self._prodlist['font'] = ('helvetica', -size) #self._prodlist_label['font'] = ('helvetica', -size-2, 'bold') self._redraw() def help(self, *e): # The default font's not very legible; try using 'fixed' instead. try: ShowText(self._top, 'Help: Shift-Reduce Parser Application', (__doc__ or '').strip(), width=75, font='fixed') except: ShowText(self._top, 'Help: Shift-Reduce Parser Application', (__doc__ or '').strip(), width=75) def about(self, *e): ABOUT = ("NLTK Shift-Reduce Parser Application\n"+ "Written by Edward Loper") TITLE = 'About: Shift-Reduce Parser Application' try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def edit_grammar(self, *e): CFGEditor(self._top, self._parser.grammar(), self.set_grammar) def set_grammar(self, grammar): self._parser.set_grammar(grammar) self._productions = list(grammar.productions()) self._prodlist.delete(0, 'end') for production in self._productions: self._prodlist.insert('end', (' %s' % production)) def edit_sentence(self, *e): sentence = " ".join(self._sent) title = 'Edit Text' instr = 'Enter a new sentence to parse.' EntryDialog(self._top, sentence, instr, self.set_sentence, title) def set_sentence(self, sent): self._sent = sent.split() #[XX] use tagged? self.reset() ######################################### ## Reduce Production Selection ######################################### def _toggle_grammar(self, *e): if self._show_grammar.get(): self._prodframe.pack(fill='both', side='left', padx=2, after=self._feedbackframe) self._lastoper1['text'] = 'Show Grammar' else: self._prodframe.pack_forget() self._lastoper1['text'] = 'Hide Grammar' self._lastoper2['text'] = '' def _prodlist_select(self, event): selection = self._prodlist.curselection() if len(selection) != 1: return index = int(selection[0]) production = self._parser.reduce(self._productions[index]) if production: self._lastoper1['text'] = 'Reduce:' self._lastoper2['text'] = '%s' % production if self._animate.get(): self._animate_reduce() else: self._redraw() else: # Reset the production selections. self._prodlist.selection_clear(0, 'end') for prod in self._parser.reducible_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) def _popup_reduce(self, widget): # Remove old commands. productions = self._parser.reducible_productions() if len(productions) == 0: return self._reduce_menu.delete(0, 'end') for production in productions: self._reduce_menu.add_command(label=str(production), command=self.reduce) self._reduce_menu.post(self._canvas.winfo_pointerx(), self._canvas.winfo_pointery()) ######################################### ## Animations ######################################### def _animate_shift(self): # What widget are we shifting? widget = self._rtextwidgets[0] # Where are we shifting from & to? right = widget.bbox()[0] if len(self._stackwidgets) == 0: left = 5 else: left = self._stackwidgets[-1].bbox()[2]+10 # Start animating. dt = self._animate.get() dx = (left-right)*1.0/dt self._animate_shift_frame(dt, widget, dx) def _animate_shift_frame(self, frame, widget, dx): if frame > 0: self._animating_lock = 1 widget.move(dx, 0) self._top.after(10, self._animate_shift_frame, frame-1, widget, dx) else: # but: stacktop?? # Shift the widget to the stack. del self._rtextwidgets[0] self._stackwidgets.append(widget) self._animating_lock = 0 # Display the available productions. self._draw_stack_top(widget) self._highlight_productions() def _animate_reduce(self): # What widgets are we shifting? numwidgets = len(self._parser.stack()[-1]) # number of children widgets = self._stackwidgets[-numwidgets:] # How far are we moving? if isinstance(widgets[0], TreeSegmentWidget): ydist = 15 + widgets[0].node().height() else: ydist = 15 + widgets[0].height() # Start animating. dt = self._animate.get() dy = ydist*2.0/dt self._animate_reduce_frame(dt/2, widgets, dy) def _animate_reduce_frame(self, frame, widgets, dy): if frame > 0: self._animating_lock = 1 for widget in widgets: widget.move(0, dy) self._top.after(10, self._animate_reduce_frame, frame-1, widgets, dy) else: del self._stackwidgets[-len(widgets):] for widget in widgets: self._cframe.remove_widget(widget) tok = self._parser.stack()[-1] if not isinstance(tok, Tree): raise ValueError() label = TextWidget(self._canvas, str(tok.node), color='#006060', font=self._boldfont) widget = TreeSegmentWidget(self._canvas, label, widgets, width=2) (x1, y1, x2, y2) = self._stacklabel.bbox() y = y2-y1+10 if not self._stackwidgets: x = 5 else: x = self._stackwidgets[-1].bbox()[2] + 10 self._cframe.add_widget(widget, x, y) self._stackwidgets.append(widget) # Display the available productions. self._draw_stack_top(widget) self._highlight_productions() # # Delete the old widgets.. # del self._stackwidgets[-len(widgets):] # for widget in widgets: # self._cframe.destroy_widget(widget) # # # Make a new one. # tok = self._parser.stack()[-1] # if isinstance(tok, Tree): # attribs = {'tree_color': '#4080a0', 'tree_width': 2, # 'node_font': bold, 'node_color': '#006060', # 'leaf_color': '#006060', 'leaf_font':self._font} # widget = tree_to_treesegment(self._canvas, tok.type(), # **attribs) # widget.node()['color'] = '#000000' # else: # widget = TextWidget(self._canvas, tok.type(), # color='#000000', font=self._font) # widget.bind_click(self._popup_reduce) # (x1, y1, x2, y2) = self._stacklabel.bbox() # y = y2-y1+10 # if not self._stackwidgets: x = 5 # else: x = self._stackwidgets[-1].bbox()[2] + 10 # self._cframe.add_widget(widget, x, y) # self._stackwidgets.append(widget) #self._redraw() self._animating_lock = 0 ######################################### ## Hovering. ######################################### def _highlight_hover(self, event): # What production are we hovering over? index = self._prodlist.nearest(event.y) if self._hover == index: return # Clear any previous hover highlighting. self._clear_hover() # If the production corresponds to an available reduction, # highlight the stack. selection = [int(s) for s in self._prodlist.curselection()] if index in selection: rhslen = len(self._productions[index].rhs()) for stackwidget in self._stackwidgets[-rhslen:]: if isinstance(stackwidget, TreeSegmentWidget): stackwidget.node()['color'] = '#00a000' else: stackwidget['color'] = '#00a000' # Remember what production we're hovering over. self._hover = index def _clear_hover(self, *event): # Clear any previous hover highlighting. if self._hover == -1: return self._hover = -1 for stackwidget in self._stackwidgets: if isinstance(stackwidget, TreeSegmentWidget): stackwidget.node()['color'] = 'black' else: stackwidget['color'] = 'black'
class Window(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("PyWave") self.style = Style() self.style.theme_use("default") self.user_waves, self.user_labels = [], [] self.save_wave = True self.RF = None self.columnconfigure(1, weight=1) self.columnconfigure(3, pad=7) self.rowconfigure(3, weight=1) self.rowconfigure(5, pad=7) self.RFparams = { 'n_estimators' : 100, 'random_state' : 1, 'n_jobs' : -1, 'max_depth' : 7, 'oob_score' : True, 'warm_start' : True } #### Geometry #### abtn = Button(self.parent, text='Capture', command=self.capture_and_store) abtn.pack(side=BOTTOM, expand=1, fill='x') tbtn = Button(self.parent, text='Train', command=self.train_model) tbtn.pack(side=BOTTOM, expand=1, fill='x') cbtn = Button(self.parent, text='Close', command=self.quit) cbtn.pack(side=BOTTOM, expand=1, fill='x') hbtn = Button(self.parent, text='Predict on Capture', command=self.capture_and_plot) hbtn.pack(side=BOTTOM, expand=1, fill='x') p = Panedwindow(self.parent, orient=VERTICAL) p.pack(side=LEFT) f1 = Labelframe(p, text='Models', width=200, height=1000) p.add(f1) self.mdlist = Listbox(self.parent, height = 900, width=400) self.mdlist.pack(side=LEFT) #### Creating top menu bars and callbacks #### menubar = Menu(self.parent) self.parent.config(menu=menubar) modelMenu = Menu(menubar, tearoff=0) menubar.add_cascade(label="Model", menu=modelMenu) modelMenu.add_command(label='Import Dataset', command=self.import_dataset) modelMenu.add_command(label='Import Model', command=self.import_model) modelMenu.add_command(label='Train Random Forest', command=self.rf) modelMenu.add_command(label='Train Gradient Boosted Classifier', command=self.gbc) modelMenu.add_command(label='Train K-Nearest Neighbors', command=self.knn) modelMenu.add_command(label='Save', command=self.saveas) modelMenu.add_command(label='Save as', command=self.saveas) waveMenu = Menu(menubar, tearoff=0) menubar.add_cascade(label="Waveform", menu=waveMenu) waveMenu.add_command(label="Import Waveform", command=self.import_waveform) waveMenu.add_command(label="Features", command=self.get_features) ############################################### def onClick(self): if self.var.get() == 1: self.master.title("") else: self.master.title("_") def quit(self): sys.exit(0) def saveas(self): f = asksaveasfile(mode='wb', defaultextension='.pkl') if f is None: return else: return def train_model(self): if len(self.user_waves) < 3: box.showinfo('PyWave', 'Capture At Least 3 Waveforms To Train Model') self.save_wave = True else: self.add_to_model() print(len(self.user_waves[0]), self.user_waves) print(len(self.user_labels), self.user_labels) self.user_waves = [] self.user_labels = [] def add_to_model(self): if not self.RF: self.import_model() assert len(self.user_waves) >= 3, "not enough wavedata {}".format(self.user_waves) self.user_waves = np.array(self.user_waves) self.user_waves = [arr[self.feature_mask] for arr in self.user_waves] self.user_labels = get_bus_indices(self.user_labels) self.RF_new = RF(n_estimators=100).fit(self.user_waves, self.user_labels) self.combine_rfs() self.mdlist.insert(END, "added data to model") print("RF_combined", self.RF, "\nestimators:", len(self.RF.steps[1][1].estimators_)) def combine_rfs(self): self.RF.steps[1][1].estimators_ += self.RF_new.estimators_ self.RF.steps[1][1].n_estimators = len(self.RF.steps[1][1].estimators_) def import_dataset(self): ftypes = [ ('CSV files', '*.csv'), ('All files', '*')] path = askopenfilename(filetypes=ftypes) self.wavedata = get_wave_data(path) self.testdata = get_test_data(testpath) self.X = self.wavedata.as_matrix().astype(np.float) self.y = np.array(self.testdata).flatten() def error_code(self): return "0x"+str(np.random.randint(1, 100000)) def error_box(self, error): box.showerror('Error', 'Error Code : ' + self.error_code() + '\n\n' + error) def rf(self): try: self.rf = build_rf(self.X, self.y, self.wavedata) self.mdlist.insert(END, "Random Forest") except AttributeError: self.error_box("Import dataset to train model") def gbc(self, X, y, wavedata): try: self.gbc = build_gbc(self.X, self.y, self.wavedata) self.mdlist.insert(END, "Boosted Classifier") except AttributeError: self.error_box("Import dataset to train model") def knn(self): try: self.kmc = build_clf(self.X, self.y, self.wavedata) self.mdlist.insert(END, "K Nearest Neighbors") except AttributeError: self.error_box("Import dataset to train model") def import_model(self): ftypes = [ ('Pickled files', '*.pkl'), ('All files', '*') ] path = askopenfilename(filetypes=ftypes) print ( path ) self.RF = load_model(path) def capture_and_store(self): pass """dsclient.register() try: while(dsclient.wait_for_sequence()): rf_guess = None rf_greatest_prob = -np.inf channel1 = dsclient.Waveform("CH1") channel1.vertical = ((channel1.vertical - channel1.offset)* channel1.increment) + channel1.position self.feature_mask = [1, 2, 3, 5, 6] bus = tkd.askstring('PyWave', 'Bus Name') if bus is None: break bus = bus.upper() wavedata = set_data(channel1) if wavedata is -1: box.infobox('PyWave', 'Zoom Out To Capture Sample') self.user_waves.append(wavedata) self.user_labels.append(bus) self.mdlist.insert(END, "Captured {} sample".format(bus)) break except KeyboardInterrupt : dsclient.finished_with_sequence() dsclient.unregister() finally : dsclient.finished_with_sequence() dsclient.unregister()""" def capture_and_plot(self): pass """dsclient.register() try: while(dsclient.wait_for_sequence()): rf_guess = None rf_greatest_prob = -np.inf channel1 = dsclient.Waveform("CH1") channel1.vertical = ((channel1.vertical - channel1.offset) *channel1.increment) + channel1.position self.feature_mask = [1, 2, 3, 5, 6] wavedata = np.array(set_data(channel1)) wavedata = wavedata[self.feature_mask] print ("wavedata", len(wavedata), wavedata) if not self.RF: self.import_model() if len(wavedata) < 1: continue print("RF before pred", self.RF) rf_pred, rf_prob = make_prediction(self.RF, wavedata) print('\nRF Probability Space\t\t\tGBC Probability Space') for idx, rf_proba in enumerate(rf_prob[0]): print (idx) print (bus_classes[idx], '--', rf_proba*100, '%') if rf_proba > rf_greatest_prob: rf_greatest_prob = rf_proba rf_guess = bus_classes[idx] guesses = [(idx, x) for idx, x in enumerate(rf_prob[0]) if abs((x*100) - (rf_greatest_prob*100)) <= 10] self.mdlist.insert(END, "\n\n") for guess in guesses: self.mdlist.insert( END, "{} with {} % certainty".format( bus_classes[guess[0]], round((guess[1] * 100), 3))) print ("continuing to next capture") break except KeyboardInterrupt : dsclient.finished_with_sequence() dsclient.unregister() finally : dsclient.finished_with_sequence() dsclient.unregister()""" def import_waveform(self): path = askopenfile() self.wave = scope_process(path) def get_features(self): self.features = print_feature_importance(self.clf, self.wavedata)
# Create a text area to display the user's choices shopping_list = Text(window, width=30, height=10, font=('Arial', 20), borderwidth=2, relief='groove') # Create a listbox widget which displays the grocery list # in alphabetical order choices = Listbox(window, font=('Arial', 20), height=len(groceries)) for item in sorted(groceries): choices.insert(END, item) # Create a button to push when the user is happy with their choice add_to_list = Button(window, text=' Add to list ', font=('Arial', 20), command=display_choice) # Use the geometry manager to "pack" the widgets onto # the window (with a margin around the widgets for neatness) margin_size = 5 shopping_list.pack(padx=margin_size, pady=margin_size) choices.pack(pady=margin_size) add_to_list.pack(pady=margin_size) # Start the event loop to react to user inputs window.mainloop()
class LintGui: """Build and control a window to interact with pylint""" def __init__(self, root=None): """init""" self.root = root or Tk() self.root.title("Pylint") # reporter self.reporter = None # message queue for output from reporter self.msg_queue = queue.Queue() self.msgs = [] self.filenames = [] self.rating = StringVar() self.tabs = {} self.report_stream = BasicStream(self) # gui objects self.lbMessages = None self.showhistory = None self.results = None self.btnRun = None self.information_box = None self.convention_box = None self.refactor_box = None self.warning_box = None self.error_box = None self.fatal_box = None self.txtModule = None self.status = None self.msg_type_dict = None self.init_gui() def init_gui(self): """init helper""" # setting up frames top_frame = Frame(self.root) mid_frame = Frame(self.root) radio_frame = Frame(self.root) res_frame = Frame(self.root) msg_frame = Frame(self.root) check_frame = Frame(self.root) history_frame = Frame(self.root) btn_frame = Frame(self.root) rating_frame = Frame(self.root) top_frame.pack(side=TOP, fill=X) mid_frame.pack(side=TOP, fill=X) history_frame.pack(side=TOP, fill=BOTH, expand=True) radio_frame.pack(side=TOP, fill=BOTH, expand=True) rating_frame.pack(side=TOP, fill=BOTH, expand=True) res_frame.pack(side=TOP, fill=BOTH, expand=True) check_frame.pack(side=TOP, fill=BOTH, expand=True) msg_frame.pack(side=TOP, fill=BOTH, expand=True) btn_frame.pack(side=TOP, fill=X) # Message ListBox rightscrollbar = Scrollbar(msg_frame) rightscrollbar.pack(side=RIGHT, fill=Y) bottomscrollbar = Scrollbar(msg_frame, orient=HORIZONTAL) bottomscrollbar.pack(side=BOTTOM, fill=X) self.lbMessages = Listbox( msg_frame, yscrollcommand=rightscrollbar.set, xscrollcommand=bottomscrollbar.set, bg="white" ) self.lbMessages.pack(expand=True, fill=BOTH) rightscrollbar.config(command=self.lbMessages.yview) bottomscrollbar.config(command=self.lbMessages.xview) # History ListBoxes rightscrollbar2 = Scrollbar(history_frame) rightscrollbar2.pack(side=RIGHT, fill=Y) bottomscrollbar2 = Scrollbar(history_frame, orient=HORIZONTAL) bottomscrollbar2.pack(side=BOTTOM, fill=X) self.showhistory = Listbox( history_frame, yscrollcommand=rightscrollbar2.set, xscrollcommand=bottomscrollbar2.set, bg="white" ) self.showhistory.pack(expand=True, fill=BOTH) rightscrollbar2.config(command=self.showhistory.yview) bottomscrollbar2.config(command=self.showhistory.xview) self.showhistory.bind("<Double-Button-1>", self.select_recent_file) self.set_history_window() # status bar self.status = Label(self.root, text="", bd=1, relief=SUNKEN, anchor=W) self.status.pack(side=BOTTOM, fill=X) # labels self.lblRatingLabel = Label(rating_frame, text="Rating:") self.lblRatingLabel.pack(side=LEFT) self.lblRating = Label(rating_frame, textvariable=self.rating) self.lblRating.pack(side=LEFT) Label(mid_frame, text="Recently Used:").pack(side=LEFT) Label(top_frame, text="Module or package").pack(side=LEFT) # file textbox self.txtModule = Entry(top_frame, background="white") self.txtModule.bind("<Return>", self.run_lint) self.txtModule.pack(side=LEFT, expand=True, fill=X) # results box rightscrollbar = Scrollbar(res_frame) rightscrollbar.pack(side=RIGHT, fill=Y) bottomscrollbar = Scrollbar(res_frame, orient=HORIZONTAL) bottomscrollbar.pack(side=BOTTOM, fill=X) self.results = Listbox( res_frame, yscrollcommand=rightscrollbar.set, xscrollcommand=bottomscrollbar.set, bg="white", font="Courier" ) self.results.pack(expand=True, fill=BOTH, side=BOTTOM) rightscrollbar.config(command=self.results.yview) bottomscrollbar.config(command=self.results.xview) # buttons Button(top_frame, text="Open", command=self.file_open).pack(side=LEFT) Button(top_frame, text="Open Package", command=(lambda: self.file_open(package=True))).pack(side=LEFT) self.btnRun = Button(top_frame, text="Run", command=self.run_lint) self.btnRun.pack(side=LEFT) Button(btn_frame, text="Quit", command=self.quit).pack(side=BOTTOM) # radio buttons self.information_box = IntVar() self.convention_box = IntVar() self.refactor_box = IntVar() self.warning_box = IntVar() self.error_box = IntVar() self.fatal_box = IntVar() i = Checkbutton( check_frame, text="Information", fg=COLORS["(I)"], variable=self.information_box, command=self.refresh_msg_window, ) c = Checkbutton( check_frame, text="Convention", fg=COLORS["(C)"], variable=self.convention_box, command=self.refresh_msg_window, ) r = Checkbutton( check_frame, text="Refactor", fg=COLORS["(R)"], variable=self.refactor_box, command=self.refresh_msg_window ) w = Checkbutton( check_frame, text="Warning", fg=COLORS["(W)"], variable=self.warning_box, command=self.refresh_msg_window ) e = Checkbutton( check_frame, text="Error", fg=COLORS["(E)"], variable=self.error_box, command=self.refresh_msg_window ) f = Checkbutton( check_frame, text="Fatal", fg=COLORS["(F)"], variable=self.fatal_box, command=self.refresh_msg_window ) i.select() c.select() r.select() w.select() e.select() f.select() i.pack(side=LEFT) c.pack(side=LEFT) r.pack(side=LEFT) w.pack(side=LEFT) e.pack(side=LEFT) f.pack(side=LEFT) # check boxes self.box = StringVar() # XXX should be generated report = Radiobutton( radio_frame, text="Report", variable=self.box, value="Report", command=self.refresh_results_window ) rawMet = Radiobutton( radio_frame, text="Raw metrics", variable=self.box, value="Raw metrics", command=self.refresh_results_window ) dup = Radiobutton( radio_frame, text="Duplication", variable=self.box, value="Duplication", command=self.refresh_results_window ) ext = Radiobutton( radio_frame, text="External dependencies", variable=self.box, value="External dependencies", command=self.refresh_results_window, ) stat = Radiobutton( radio_frame, text="Statistics by type", variable=self.box, value="Statistics by type", command=self.refresh_results_window, ) msgCat = Radiobutton( radio_frame, text="Messages by category", variable=self.box, value="Messages by category", command=self.refresh_results_window, ) msg = Radiobutton( radio_frame, text="Messages", variable=self.box, value="Messages", command=self.refresh_results_window ) report.select() report.grid(column=0, row=0, sticky=W) rawMet.grid(column=1, row=0, sticky=W) dup.grid(column=2, row=0, sticky=W) msg.grid(column=3, row=0, sticky=E) stat.grid(column=0, row=1, sticky=W) msgCat.grid(column=1, row=1, sticky=W) ext.grid(column=2, row=1, columnspan=2, sticky=W) # dictionary for check boxes and associated error term self.msg_type_dict = { "I": lambda: self.information_box.get() == 1, "C": lambda: self.convention_box.get() == 1, "R": lambda: self.refactor_box.get() == 1, "E": lambda: self.error_box.get() == 1, "W": lambda: self.warning_box.get() == 1, "F": lambda: self.fatal_box.get() == 1, } self.txtModule.focus_set() def select_recent_file(self, event): """adds the selected file in the history listbox to the Module box""" if not self.showhistory.size(): return selected = self.showhistory.curselection() item = self.showhistory.get(selected) # update module self.txtModule.delete(0, END) self.txtModule.insert(0, item) def refresh_msg_window(self): """refresh the message window with current output""" # clear the window self.lbMessages.delete(0, END) for msg in self.msgs: if self.msg_type_dict.get(msg[0])(): msg_str = self.convert_to_string(msg) self.lbMessages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], "black") self.lbMessages.itemconfigure(END, fg=fg_color) def refresh_results_window(self): """refresh the results window with current output""" # clear the window self.results.delete(0, END) try: for res in self.tabs[self.box.get()]: self.results.insert(END, res) except: pass def convert_to_string(self, msg): """make a string representation of a message""" if msg[2] != "": return "(" + msg[0] + ") " + msg[1] + "." + msg[2] + " [" + msg[3] + "]: " + msg[4] else: return "(" + msg[0] + ") " + msg[1] + " [" + msg[3] + "]: " + msg[4] def process_incoming(self): """process the incoming messages from running pylint""" while self.msg_queue.qsize(): try: msg = self.msg_queue.get(0) if msg == "DONE": self.report_stream.output_contents() return False # adding message to list of msgs self.msgs.append(msg) # displaying msg if message type is selected in check box if self.msg_type_dict.get(msg[0])(): msg_str = self.convert_to_string(msg) self.lbMessages.insert(END, msg_str) fg_color = COLORS.get(msg_str[:3], "black") self.lbMessages.itemconfigure(END, fg=fg_color) except queue.Empty: pass return True def periodic_call(self): """determine when to unlock the run button""" if self.process_incoming(): self.root.after(100, self.periodic_call) else: # enabling button so it can be run again self.btnRun.config(state=NORMAL) def mainloop(self): """launch the mainloop of the application""" self.root.mainloop() def quit(self, _=None): """quit the application""" self.root.quit() def halt(self): """program halt placeholder""" return def file_open(self, package=False, _=None): """launch a file browser""" if not package: filename = askopenfilename( parent=self.root, filetypes=[("pythonfiles", "*.py"), ("allfiles", "*")], title="Select Module" ) else: filename = askdirectory(title="Select A Folder", mustexist=1) if filename == (): return self.txtModule.delete(0, END) self.txtModule.insert(0, filename) def update_filenames(self): """update the list of recent filenames""" filename = self.txtModule.get() if not filename: filename = os.getcwd() if filename + "\n" in self.filenames: index = self.filenames.index(filename + "\n") self.filenames.pop(index) # ensure only 10 most recent are stored if len(self.filenames) == 10: self.filenames.pop() self.filenames.insert(0, filename + "\n") def set_history_window(self): """update the history window with info from the history file""" # clear the window self.showhistory.delete(0, END) # keep the last 10 most recent files try: view_history = open(HOME + HISTORY, "r") for hist in view_history.readlines(): if not hist in self.filenames: self.filenames.append(hist) self.showhistory.insert(END, hist.split("\n")[0]) view_history.close() except IOError: # do nothing since history file will be created later return def run_lint(self, _=None): """launches pylint""" self.update_filenames() self.root.configure(cursor="watch") self.reporter = GUIReporter(self, output=self.report_stream) module = self.txtModule.get() if not module: module = os.getcwd() # cleaning up msgs and windows self.msgs = [] self.lbMessages.delete(0, END) self.tabs = {} self.results.delete(0, END) self.btnRun.config(state=DISABLED) # setting up a worker thread to run pylint worker = Thread(target=lint_thread, args=(module, self.reporter, self)) self.periodic_call() worker.start() # Overwrite the .pylint-gui-history file with all the new recently added files # in order from filenames but only save last 10 files write_history = open(HOME + HISTORY, "w") write_history.writelines(self.filenames) write_history.close() self.set_history_window() self.root.configure(cursor="")
class ProductDisplay(Frame): """Interface for product display""" def __init__(self, parent=None): """Create, pack, and bind entry boxes and buttons for product display""" Frame.__init__(self) self.pack() self.frameHeading = Frame(self) self.frameHeading.pack() self.frameHeadingTitle = Label(self.frameHeading, text="Current inventory", font=("Arial", "12", "bold")) self.frameHeadingTitle.pack() # ---Database output self.showInventoryFrame = Frame(self).pack() ##Imported table-like multilist box self.listBox = Listbox(self.showInventoryFrame) self.listBox.pack(expand=YES, fill=BOTH) Listbox(self.showInventoryFrame) # ---Inventory display buttons self.inventoryBtnFrame = Frame(self).pack() self.fetchInven = Button(self.inventoryBtnFrame, text="Get inventory", command=self.getInven) self.fetchInven.pack(side=LEFT) self.modifyInven = Button(self.inventoryBtnFrame, text="Update listing", command=self.changeInven) self.modifyInven.pack(side=LEFT) self.deleteInven = Button(self.inventoryBtnFrame, text="Delete entry", command=self.clearEntry) self.deleteInven.pack(side=LEFT) self.clearInven = Button(self.inventoryBtnFrame, text="Clear inventory", command=self.delInven) self.clearInven.pack(side=LEFT) def getInven(self): """Gets products from DB and displays them. Opens the shelve, loops through each entry, prints the unpacked tuple for each record, then closes the shelve.""" self.listBox.delete(0, END) c.execute("SELECT * FROM items") self.productList = c.fetchall() for row in self.productList: self.listBox.insert(END, row) def clearEntry(self): """Deletes an entry from the database. Gets the highlighted selection, makes a list of the the separate words, 'pops' the product number entry, finds the product number in the shelve, deletes the product, then updates the inventory screen.""" ans = messagebox.askokcancel("Verify delete", "Really remove item?") # popup window if ans: c.execute("SELECT * FROM items") self.productList = c.fetchall() self.getSelection = self.listBox.curselection( ) # get index of selection self.selectedEntry = self.listBox.get( self.getSelection) # get tuple from selection (self.productNum, self.descrip, self.cost, self.price, self.quan) = self.selectedEntry # unpack tuple self.entry = self.selectedEntry[0] c.execute("DELETE FROM items WHEN item_name=?", (self.entry)) messagebox.showinfo( title="Product removed", message="The product has been removed from inventory.") self.getInven() def changeInven(self): """Allows modification of a database entry. Called by modifyInven Button""" try: # see if a selection was made self.getSelection = self.listBox.curselection( ) # get index of selection self.selectedEntry = self.listBox.get( self.getSelection) # get tuple from selection (self.prodnum, self.descrip, self.colors, self.cost, self.price, self.quan) = self.selectedEntry # unpack tuple # ---New 'edit product' window self.editWindow = Toplevel() self.editWindow.title("Edit selected entry") # ---Edit product window widgets Label(self.editWindow, text="Product Number").grid(row=0, column=0) Label(self.editWindow, text="Description").grid(row=0, column=1) Label(self.editWindow, text="Sell price").grid(row=0, column=2) Label(self.editWindow, text="Quantity").grid(row=0, column=3) self.oldNum = Entry(self.editWindow, name="prodNum") self.oldNum.grid(row=1, column=0) self.oldDescrip = Entry(self.editWindow, name="descrip") self.oldDescrip.grid(row=1, column=1) self.oldColor = Entry(self.editWindow, name="color") self.oldColor.grid(row=1, column=2) self.oldCost = Entry(self.editWindow, name="cost") self.oldCost.grid(row=1, column=3) self.oldPrice = Entry(self.editWindow, name="price") self.oldPrice.grid(row=1, column=4) self.oldQuan = Entry(self.editWindow, name="quan") self.oldQuan.grid(row=1, column=5) self.update = Button(self.editWindow, text="Update product", command=self.updateProduct).grid(row=2, column=2) self.cancel = Button(self.editWindow, text="Cancel", command=self.cancelProduct).grid(row=2, column=3) # ---Edit product data self.oldNum.insert(END, self.prodnum) self.oldDescrip.insert(END, self.descrip) self.oldColor.insert(END, self.colors) self.oldCost.insert(END, self.cost) self.oldPrice.insert(END, self.price) self.oldQuan.insert(END, self.quan) except TclError: # tell user to make a selection first messagebox.showerror(title="Error!", message="You must make a selection first!") def updateProduct(self): """Change the values of a database entry. Called by changeInven Button.""" c.execute("INSERT INTO items") self.oldEntry = self.oldNum.get() self.newQuan = self.oldQuan.get() self.newCost = self.oldCost.get() self.newPrice = self.oldPrice.get() self.newRecord = [ self.descrip, self.newCost, self.newPrice, self.newQuan ] c.execute("INSERT INTO items ") self.productList[self.oldEntry] = self.newRecord self.productList.close() self.editWindow.destroy() def cancelProduct(self): """Verify canceling of product update.""" self.editWindow.destroy() def delInven(self): """Deletes all entries in database.""" ans = messagebox.askokcancel("Verify delete", "Really clear inventory?") # popup window if ans: c.execute("DELETE * FROM items") conn.commit() c.close() conn.close() messagebox.showinfo( title="Inventory cleared", message="Your inventory database has been deleted.")
class GUI(Frame): # pylint: disable=too-many-ancestors """class for GUI""" static_logger = logging.getLogger(__name__) static_queue = queue.Queue() def __init__(self, parent, db, pab, alg): """init""" Frame.__init__(self, parent) self.right_list = Listbox(parent) self.left_list = Listbox(parent) self.parent = parent self.db_creator = db self.path_and_bag = pab self.alg_do = alg self.menu_bar = Menu(self.parent) self.init_ui() def init_ui(self): """getting all things started""" self.parent.title("PyMeno") self.left_list.bind("<Double-Button-1>", self.on_double_click) self.parent.config(menu=self.menu_bar) file_menu = Menu(self.menu_bar, tearoff=False) menu2_parse = Menu(self.menu_bar, tearoff=False) # menu3_parse = Menu(menu_bar, tearoff=False) # sub_menu = Menu(file_menu, tearoff=False) self.left_list.pack(side=LEFT, fill=BOTH, expand=2) self.right_list.pack(side=RIGHT, fill=BOTH, expand=2) # add something to menu file_menu.add_command(label="Choose folder with music ALG 1", underline=0, command=self.new_thread_2) file_menu.add_command(label="Choose folder with music ALG 2", underline=0, command=self.new_thread_1) file_menu.add_command(label="Choose folder with music ALG 3", underline=0, command=self.new_thread_2) file_menu.add_command(label="Exit", underline=0, command=self.on_exit) menu2_parse.add_command(label="Download artists list", underline=0, command=self.db_creator.download_list_of_artists) menu2_parse.\ add_command(label="Parse artists information to database", underline=0, command=self.go_to_lilis_parsing) self.menu_bar.add_cascade(label="File", underline=0, menu=file_menu) self.menu_bar.add_cascade(label="Data", underline=0, menu=menu2_parse) def on_exit(self): """quit""" GUI.static_queue.put("endino-tarantino") self.quit() def disable_menu(self): """disable menu while program is working""" self.menu_bar.entryconfig("File", state="disabled") self.menu_bar.entryconfig("Data", state="disabled") def enable_menu(self): """enable menu after work""" self.menu_bar.entryconfig("File", state="normal") self.menu_bar.entryconfig("Data", state="normal") def new_thread_1(self): """thread for the first algorythm""" dir_name = filedialog.askdirectory(parent=self, initialdir="/", title='Please select a directory') if dir_name != "": self.disable_menu() self.path_and_bag.check_if_refresh(dir_name) self.config(cursor="wait") self.update() self.clean_queue() GUI.static_queue.put("Finding files in chosen folder:\n\n") num_files = len([val for sub_list in [[os.path.join(i[0], j)for j in i[2]] for i in os.walk(dir_name)] for val in sub_list]) rott = tk.Tk() app = App(rott, GUI.static_queue, num_files) rott.protocol("WM_DELETE_WINDOW", app.on_closing) thread = threading.Thread(target=self.open_menu, args=(dir_name,)) thread.setDaemon(True) thread.start() app.mainloop() else: print("Action aborted") def open_menu(self, dir_name): """select directory with music, alg 1""" list_of_songs = [] self.path_and_bag.clear_bag_of_words() for data in os.walk(dir_name): for filename in data[2]: list_of_songs = self.path_and_bag.change_title(os.path.join(data[0], filename)) GUI.static_queue.put(filename) if not list_of_songs: print("action aborted") else: GUI.static_queue.put("\nAnd what we have here?:\n") self.config(cursor="") shared_items_add = self.alg_do.search_for_simmilar_ver_2(False, GUI.static_queue) if not shared_items_add: shared_items_add = self.alg_do.search_for_simmilar_ver_2(True, GUI.static_queue) if shared_items_add: self.left_list.delete(0, END) self.right_list.delete(0, END) for song in list_of_songs: temp = song.split(',', 1) self.insert_to_right_list_box(temp[0], temp[1]) for key, value in shared_items_add.items(): temp = key.split(',', 1) GUI.static_queue.put(temp[0] + " : " + value) self.insert_to_left_list_box(temp[0] + " : " + value) GUI.static_queue.put("endino-tarantino") self.enable_menu() def new_thread_2(self): """thread for the second algorythm""" dir_name = filedialog.askdirectory(parent=self, initialdir="/", title='Please select a directory') if dir_name != "": self.disable_menu() self.path_and_bag.check_if_refresh(dir_name) self.config(cursor="wait") self.update() self.clean_queue() GUI.static_queue.put("Finding files in chosen folder:\n\n") num_files = len([val for sub_list in [[os.path.join(i[0], j)for j in i[2]] for i in os.walk(dir_name)] for val in sub_list]) rott = tk.Tk() app = App(rott, GUI.static_queue, num_files) rott.protocol("WM_DELETE_WINDOW", app.on_closing) thread = threading.Thread(target=self.open_menu_ver_2, args=(dir_name,)) thread.setDaemon(True) thread.start() app.mainloop() else: print("Action aborted") @staticmethod def clean_queue(): """cleaning queue if user exit manualy""" if not GUI.static_queue.empty(): while not GUI.static_queue.empty(): GUI.static_queue.get() def open_menu_ver_2(self, dir_name): """select directory with music, alg 2""" list_of_songs = [] self.path_and_bag.clear_bag_of_words() for data in os.walk(dir_name): for filename in data[2]: list_of_songs = self.path_and_bag.change_title(os.path.join(data[0], filename)) GUI.static_queue.put(filename) if not list_of_songs: print("action aborted") else: GUI.static_queue.put("\nAnd what we have here?:\n") self.config(cursor="") shared_items_add = self.alg_do.search_for_simmilar_ver_1(False, GUI.static_queue) if not shared_items_add: shared_items_add = self.alg_do.search_for_simmilar_ver_1(True, GUI.static_queue) if shared_items_add: self.left_list.delete(0, END) self.right_list.delete(0, END) for song in list_of_songs: temp = song.split(',', 1) self.insert_to_right_list_box(temp[0], temp[1]) for key, value in shared_items_add.items(): temp = key.split(',', 1) self.insert_to_left_list_box(temp[0] + " : " + value) GUI.static_queue.put("endino-tarantino") self.enable_menu() def new_thread_3(self): """thread for the third algorythm""" dir_name = filedialog.askdirectory(parent=self, initialdir="/", title='Please select a directory') if dir_name != "": self.disable_menu() self.path_and_bag.check_if_refresh(dir_name) self.config(cursor="wait") self.update() self.clean_queue() GUI.static_queue.put("Finding files in chosen folder:\n\n") num_files = len([val for sub_list in [[os.path.join(i[0], j) for j in i[2]] for i in os.walk(dir_name)] for val in sub_list]) rott = tk.Tk() app = App(rott, GUI.static_queue, num_files) rott.protocol("WM_DELETE_WINDOW", app.on_closing) thread = threading.Thread(target=self.open_menu_ver_3, args=(dir_name,)) thread.setDaemon(True) thread.start() app.mainloop() else: print("Action aborted") def open_menu_ver_3(self, dir_name): """select directory with music, alg 3""" list_of_songs = [] self.path_and_bag.clear_bag_of_words() for data in os.walk(dir_name): for filename in data[2]: list_of_songs = self.path_and_bag.change_title(os.path.join(data[0], filename)) GUI.static_queue.put(filename) print(list_of_songs) if not list_of_songs: print("action aborted") else: GUI.static_queue.put("\nAnd what we have here?:\n") self.config(cursor="") shared_items_add = self.alg_do.search_for_simmilar_ver_3(False, GUI.static_queue) if not shared_items_add: shared_items_add = self.alg_do.search_for_simmilar_ver_3(True, GUI.static_queue) if shared_items_add: self.left_list.delete(0, END) self.right_list.delete(0, END) for song in list_of_songs: temp = song.split(',', 1) self.insert_to_right_list_box(temp[0], temp[1]) for key, value in shared_items_add.items(): temp = key.split(',', 1) self.insert_to_left_list_box(temp[0] + " : " + value) GUI.static_queue.put("endino-tarantino") self.enable_menu() def insert_to_right_list_box(self, artist, song): """insert to right listbox for other methods""" self.right_list.insert(END, artist + " - " + song) def insert_to_left_list_box(self, artist): """insert to left listbox for other methods""" self.left_list.insert(END, artist) def go_to_lilis_parsing(self): """how many artist do you want to parse""" number_from = simpledialog.askstring('Number', 'How many artists?/FROM') if number_from is not None: number_from = int(number_from) print(number_from) number_to = int(simpledialog.askstring('Number', 'How many artists?/TO')) if number_to is not None: number_to = int(number_to) print(number_to) self.db_creator.parse_file(number_to, number_from) def on_double_click(self, event): """open youtube on double click""" new = 2 # open in a new tab, if possible widget = event.widget selection = widget.curselection() value = widget.get(selection[0]) url = self.youtube_search(value) webbrowser.open(url, new=new) @staticmethod def youtube_search(to_search): """ This function finds url to our songs throw Youtube API """ developer_key = "AIzaSyCn9Pk4vWC8LjjIKqol5gkku20DI0IRurU" youtube_api_service_name = "youtube" youtube_api_version = "v3" parse = argparse.ArgumentParser() parse.add_argument("--q", help="Search term", default=to_search) parse.add_argument("--max-results", help="Max results", default=25) args = parse.parse_args() youtube = build(youtube_api_service_name, youtube_api_version, developerKey=developer_key) # Call the search.list method to retrieve results matching the specified # query term. search_response = youtube.search().list(q=args.q, # pylint: disable=no-member part="id,snippet", maxResults=args.max_results, order="viewCount").execute() videos = [] channels = [] play_lists = [] # Add each result to the appropriate list, and then display the lists of # matching videos, channels, and play lists. for search_result in search_response.get("items", []): if search_result["id"]["kind"] == "youtube#video": videos.append(search_result["id"]["videoId"]) elif search_result["id"]["kind"] == "youtube#channel": channels.append("%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["channelId"])) elif search_result["id"]["kind"] == "youtube#playlist": play_lists.append("%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["playlistId"])) try: return "https://www.youtube.com/watch?v=" + videos[0] except (UnicodeEncodeError, IndexError): GUI.static_logger.error('ERROR', exc_info=True) return "https://www.youtube.com/watch?v=" + "_NXrTujMP50"
shuffle(tasklist) for i in range(len(tasklist)): tasklist[i] = str(i+1)+'.'+tasklist[i]+++++++++++++++ var.set(tasklist) #window_list= Toplevel(window) #window_list.geometry('500x600') #window_list.title('任务列表') #list_var = StringVar() #list_str = "".join(tasklist) #list_var.set(list_str) #Label(window_list,image=photo,textvariable=list_var).pack() #字符串会被Label挡住 b1= Button(window,text="生成",width=10,height=2,command=hit_b1) var = StringVar() lb = Listbox(window,listvariable=var) L1 = Label(window,text="让我们来加点任务吧") b1.pack() lb.pack() window.mainloop()
class PdfGui: def __init__(self, master): self.master = master master.title("PDF-App GUI") master.resizable(False, False) main_frame = Frame(master) top_frame = Frame(main_frame) bottom_frame = Frame(main_frame) label_input_path = Label(top_frame, text="Input file(s)") self.input_path = StringVar() input_path_field = Entry(top_frame, textvariable=self.input_path) input_browse_button = Button( top_frame, text="Browse", command=lambda: self.browse_multiple(self.input_path)) self.add_bookmarks = IntVar() bookmarks_checkbox = Checkbutton(top_frame, text="Add bookmarks", variable=self.add_bookmarks) label_watermark_path = Label(top_frame, text="Watermark") self.watermark_path = StringVar() watermark_path_field = Entry(top_frame, textvariable=self.watermark_path) watermark_browse_button = Button( top_frame, text="Browse", command=lambda: self.browse_single(self.watermark_path, [( "PDF files", "*.pdf")])) label_js_path = Label(top_frame, text="Javascript file") self.js_path = StringVar() js_path_field = Entry(top_frame, textvariable=self.js_path) js_browse_button = Button( top_frame, text="Browse", command=lambda: self.browse_single(self.js_path, [( "Javascript files", "*.js"), ("Any files", "*.*")])) label_js = Label(top_frame, text="Javascript") js_frame = Frame(top_frame) scrollbar = Scrollbar(js_frame) self.js_field = Text(js_frame, height=4, width=30) scrollbar.pack(side=RIGHT, fill=Y) self.js_field.pack(side=LEFT, fill=Y) scrollbar.config(command=self.js_field.yview) self.js_field.config(yscrollcommand=scrollbar.set) self.encrypt = StringVar() label_encrypt = Label(top_frame, text="Encrypt") encrypt_field = Entry(top_frame, textvariable=self.encrypt) self.encryption = StringVar() encryptions = ["128bit", "40bit"] self.encryption.set(encryptions[0]) encryption_dropdown = OptionMenu(top_frame, self.encryption, *encryptions) self.decrypt = StringVar() label_decrypt = Label(top_frame, text="Decrypt") decrypt_field = Entry(top_frame, textvariable=self.decrypt) label_rotation = Label(top_frame, text="Rotation") self.rotation = StringVar() rotations = [0, 90, 180, 270] self.rotation.set(rotations[0]) rotation_dropdown = OptionMenu(top_frame, self.rotation, *rotations) self.start_button = Button(top_frame, text="Start", command=self.start) # self.progress_listbox = Listbox(bottomFrame) progress_listbox_frame = Frame(root, bd=0, relief=SUNKEN) xscrollbar = Scrollbar(progress_listbox_frame, orient=HORIZONTAL) yscrollbar = Scrollbar(progress_listbox_frame) xscrollbar.pack(side=BOTTOM, fill=X) yscrollbar.pack(side=RIGHT, fill=Y) self.progress_listbox = Listbox(progress_listbox_frame, xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set) self.progress_listbox.pack(fill=X) xscrollbar.config(command=self.progress_listbox.xview) yscrollbar.config(command=self.progress_listbox.yview) main_frame.pack(fill=BOTH, expand=True) top_frame.pack(fill=X, side=TOP, expand=False) label_input_path.grid(row=0, column=0, sticky=W + E) input_path_field.grid(row=0, column=1, sticky=W + E) input_browse_button.grid(row=0, column=2, sticky=W + E) bookmarks_checkbox.grid(row=1, column=0, columnspan=3, sticky=W + E) label_rotation.grid(row=2, column=0, sticky=W + E) rotation_dropdown.grid(row=2, column=1, columnspan=2, sticky=W + E) label_encrypt.grid(row=3, column=0, sticky=W + E) encrypt_field.grid(row=3, column=1, sticky=W + E) encryption_dropdown.grid(row=3, column=2, sticky=W + E) label_decrypt.grid(row=4, column=0, sticky=W + E) decrypt_field.grid(row=4, column=1, columnspan=2, sticky=W + E) label_watermark_path.grid(row=5, column=0, sticky=W + E) watermark_path_field.grid(row=5, column=1, sticky=W + E) watermark_browse_button.grid(row=5, column=2, sticky=W + E) label_js_path.grid(row=6, column=0, sticky=W + E) js_path_field.grid(row=6, column=1, sticky=W + E) js_browse_button.grid(row=6, column=2, sticky=W + E) label_js.grid(row=7, column=0, sticky=W + E) js_frame.grid(row=7, column=1, columnspan=2, sticky=W + E) self.start_button.grid(row=8, column=0, columnspan=3, sticky=W + E) bottom_frame.pack(fill=X, side=BOTTOM, expand=False) progress_listbox_frame.pack(fill=X) def browse_single(self, field, types): field.set(askopenfilename(filetypes=types)) def browse_multiple(self, field): fnames = askopenfilenames(filetypes=[("PDF files", "*.pdf")]) splitted = self.master.tk.splitlist(fnames) paths = "" for file in splitted: paths += "%s;" % file field.set(paths[:-1]) def start(self): if not self.input_path.get(): messagebox.showerror("An error occurred", "No input files") return fname = asksaveasfile(defaultextension=".pdf", filetypes=[("PDF file", "*.pdf"), ("All Files", "*.*")]) inputs = self.input_path.get().split(';') rotation = None if int(self.rotation.get()) != 0: rotation = int(self.rotation.get()) use_40bit = False if self.encryption.get() == "40bit": use_40bit = True js = self.js_field.get("1.0", END) if len(js) <= 1: js = None self.progress_listbox.delete(0, END) self.start_button.configure(state=DISABLED) work_thread = threading.Thread(target=do_work, args=[ inputs, fname.name, self.encrypt.get(), use_40bit, self.decrypt.get(), rotation, self.watermark_path.get(), js, self.js_path.get(), self.add_bookmarks.get(), self.update_progress ]) work_thread.start() def update_progress(self, message, exit_code=None): print(message) self.progress_listbox.insert(END, message) if exit_code is not None: if exit_code == 0: messagebox.showinfo("Progress update", "Done") else: messagebox.showerror("Progress update", "Error occurred during processing") self.start_button.configure(state=NORMAL)
class ListWindow(Frame): def __init__(self, showSelected, parent=None): Frame.__init__(self, parent) self.parent = parent self.showSelected = showSelected self.listBox = None self.initUI() def initUI(self): frame_lbl = Frame(self.parent, bd=5, relief=RIDGE) frame_lbl.pack(side=TOP, expand=True, fill=X) lbl_name = Label(frame_lbl, text='Созданные решетки') lbl_name.pack() frame_listbox = Frame(self.parent) frame_listbox.pack(side=TOP, expand=True, fill=BOTH) self.listBox = Listbox(frame_listbox, width=65, height=4, selectmode=SINGLE, bd=5, relief=RIDGE) self.listBox.bind('<<ListboxSelect>>', self.showSelect) scrbary = Scrollbar(frame_listbox, orient='vertical') scrbarx = Scrollbar(frame_listbox, orient='horizontal') scrbary.config(command=self.listBox.yview, relief=SUNKEN) scrbarx.config(command=self.listBox.xview, relief=SUNKEN) self.listBox.config(yscrollcommand=scrbary.set, xscrollcommand=scrbarx.set) scrbary.pack(side=RIGHT, fill=Y) scrbarx.pack(side='bottom', fill=X) self.listBox.pack(side=TOP, expand=True, fill=BOTH) def showSelect(self, event): item = self.getSelectedItem() self.showSelected(item) def getSelectedItem(self): items = self.listBox.curselection() item = self.listBox.get(items[0]) return item def insertData(self, item): count = self.listBox.size() for i in range(count): s = self.listBox.get(i) if s == item: messagebox.showerror( 'Ошибка', 'Окно с таким заголовком уже есть в списке') return False self.listBox.insert(END, item) return True def removeData(self, title): count = self.listBox.size() for i in range(count): string = self.listBox.get(i) if string == title: self.listBox.delete(i) break def clear(self): count = self.listBox.size() self.listBox.delete(0, count - 1)
class ChooseFiles(tk.Frame): '''The main frame for adding/removing files, accessing setttings and parsing.''' from seebeck.parse import GUIParse opts = SimpleNamespace(in_files=[], out_dir=os.path.join(os.getcwd(), 'parsed'), out_file='', plot=True, write=True, truetemp=False, col_to_parse=1, dTn=[], cuttoff_to_toss=100) # TODO: Make this a user option raw_data = {} gothreads = [] plots = [] outdir = '' boolmap = {1: True, 0: False} colmap = {1:'Raw Voltage (uV)', 2:'Corrected Voltage (uV)', 3:'Top T', 4:'Bottom T', 5:'Delta-T (°C)', 6:'Seebeck (uV/K)'} FileListBoxFrameLabelVar = None FileListBoxFrameLabel = None filelist = None FileListBox = None checks = [] OutputFileName = None DeltaTn = None OptionsColString = None OptionCol = None def __init__(self, master=None): if master is None: master = Tk() super().__init__(master) bgimg = PhotoImage(file=os.path.join(absdir, 'gui', 'RCCLabFluidic.png')) limg = Label(self.master, i=bgimg, background=GREY) limg.pack(side=TOP) try: self.last_input_path = os.getcwd() except KeyError: self.last_input_path = os.path.expanduser('~') master.tk_setPalette(background=GREY, activeBackground=GREY) master.title("RCCLab Rick-9000 Parser") master.geometry('800x850+250+250') self.pack(fill=BOTH) if len(sys.argv) > 1: self.opts.in_files = sys.argv[1:] self.__createWidgets() self.ToFront() def __createWidgets(self): self.ButtonFrame = tk.Frame(self) self.LoggingFrame = tk.Frame(self) self.RightOptionsFrame = tk.Frame(self) self.FileListBoxFrame = tk.Frame(self) # ScrolledText widget to display logging output stlogger = ScrolledText.ScrolledText(self.LoggingFrame, state='disabled') stlogger.configure(font='TkFixedFont') stlogger.pack(side=LEFT, fill=BOTH, expand=True) # Create textLogger text_handler = TextHandler(stlogger) # Logging configuration logging.basicConfig(filename='Rick-9000.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # Add the handler to logger logger = logging.getLogger(__package__) logger.addHandler(text_handler) self.__createButtons() self.__createFileListBox() self.__createOptions() self.ButtonFrame.pack(side=BOTTOM, fill=None) self.FileListBoxFrame.pack(side=TOP, fill=BOTH, expand=True) self.RightOptionsFrame.pack(side=RIGHT, fill=Y) self.LoggingFrame.pack(side=BOTTOM, fill=BOTH) # self.logger.setLevel(getattr(logging, self.opts.loglevel.upper())) self.updateFileListBox() self.checkOptions() logging.info('Select some files to get started.') def __createButtons(self): buttons = [{'name': 'Quit', 'text': 'QUIT', 'command': 'Quit', 'side': BOTTOM}, {'name': 'SpawnInputDialog', 'text': 'Add Input Files', 'side': LEFT}, {'name': 'RemoveFile', 'text': 'Remove Files', 'side': LEFT}, {'name': 'SpawnOutputDialog', 'text': 'Choose Output Directory', 'side': LEFT}, {'name': 'Parse', 'text': 'Parse!', 'side': LEFT} ] for b in buttons: button = tk.Button(self.ButtonFrame) button.config(text=b['text'], command=getattr(self, b['name']+'Click')) button.pack(side=b['side']) setattr(self, 'Button'+b['name'], button) def __createFileListBox(self): self.FileListBoxFrameLabelVar = StringVar() self.FileListBoxFrameLabel = tk.Label(self.FileListBoxFrame, textvariable=self.FileListBoxFrameLabelVar, font=Font(size=10, weight="bold")) self.FileListBoxFrameLabel.pack(side=TOP, fill=X) yScroll = tk.Scrollbar(self.FileListBoxFrame, orient=VERTICAL) yScroll.pack(side=RIGHT, fill=Y) xScroll = tk.Scrollbar(self.FileListBoxFrame, orient=HORIZONTAL) xScroll.pack(side=BOTTOM, fill=X) self.filelist = StringVar() self.FileListBox = Listbox(self.FileListBoxFrame, listvariable=self.filelist, selectmode=EXTENDED, height=20, width=0, relief=RAISED, bd=1, bg=WHITE, # font=Font(size=10), xscrollcommand=xScroll.set, yscrollcommand=yScroll.set) xScroll['command'] = self.FileListBox.xview yScroll['command'] = self.FileListBox.yview self.FileListBox.pack(side=LEFT, fill=BOTH, expand=True) self.UpdateFileListBoxFrameLabel() def __createOptions(self): '''Create the widgets for options and use setattr to assign them to self.''' self.checks = [{'name': 'plot', 'text': 'Plot', 'row': 1, 'tooltip': "Show summary plots after parsing."}, {'name': 'write', 'text': 'Write', 'row': 2, 'tooltip': "Write results to text files after parsing."}, {'name': 'truetemp', 'text': 'Use Real T', 'row': 3, 'tooltip': "Use the measured ΔT instead the ΔT field values."} ] for _c in self.checks: setattr(self, _c['name'], IntVar()) check = tk.Checkbutton(self.RightOptionsFrame, text=_c['text'], variable=getattr(self, _c['name']), command=self.checkOptions) check.grid(column=0, row=_c['row'], sticky=W) createToolTip(check, _c['tooltip']) setattr(self, 'Check_'+_c['name'], check) if getattr(self.opts, _c['name']): getattr(self, _c['name']).set(1) rowidx = len(self.checks)+1 tk.Label(self.RightOptionsFrame, text="Output file base name:").grid( column=0, row=rowidx) self.OutputFileName = tk.Entry(self.RightOptionsFrame, width=20, font=Font(size=10, slant='italic')) for n in ('<Return>', '<Leave>', '<Enter>'): self.OutputFileName.bind(n, self.checkOutputFileName) self.OutputFileName.grid(column=0, row=rowidx+1) if self.opts.out_file: self.OutputFileName.insert(0, self.opts.out_file) tk.Label(self.RightOptionsFrame, text="ΔT values:").grid( column=0, row=rowidx+2, sticky=W) self.DeltaTn = tk.Entry(self.RightOptionsFrame, width=20, font=Font(size=10)) self.DeltaTn.insert(0, '4,8,12') for n in ('<Return>', '<Leave>', '<Enter>'): self.DeltaTn.bind(None, self.checkOptions) self.DeltaTn.grid(column=0, row=rowidx+3, sticky=W) tk.Label(self.RightOptionsFrame, text="Column to plot:").grid( column=0, row=rowidx+4, sticky=W) self.OptionsColString = StringVar() self.OptionsColString.set(self.opts.col_to_parse) self.OptionCol = tk.OptionMenu(self.RightOptionsFrame, self.OptionsColString, self.colmap[self.opts.col_to_parse], command=self.checkOptions, *list(self.colmap.values())) # __menu = self.nametowidget(self.OptionCol) # __menu.config(font=Font(size=10)) # Set the dropdown menu's font self.OptionCol.grid(column=0, row=rowidx+5, sticky=W) # tk.Label(self.RightOptionsFrame, text="ΔT values:").grid( # column=0, row=rowidx+2, sticky=W) # self.OptionsdTnString = StringVar() # self.OptionsdTnString.set('.'.join(self.opts.dTn)) # self.OptionPlots = tk.OptionMenu(self.RightOptionsFrame, # self.OptionsdTnString, self.opts.dTn, 'J', 'R', # command=self.checkOptions) # self.OptionPlots.grid(column=0, row=rowidx+3, sticky=W) def RemoveFileClick(self): self.checkOptions() selected = [self.FileListBox.get(x) for x in self.FileListBox.curselection()] todel = [] filelist = [] for i in range(0, len(self.opts.in_files)): for _s in selected: if self.opts.in_files[i].replace(" ", "_") == _s: todel.append(i) for i in range(0, len(self.opts.in_files)): if i not in todel: filelist.append(self.opts.in_files[i]) self.opts.in_files = filelist self.updateFileListBox() self.FileListBox.selection_clear(0, END) def SpawnInputDialogClick(self): # self.checkOptions() self.opts.in_files += filedialog.askopenfilename( title="Files to parse", multiple=True, initialdir=self.last_input_path, filetypes=[('LabView Files', '*.lvm'), ('Data files', '*_data.txt'), ('Text files', '*.txt'), ('All files', '*')]) if self.opts.in_files: self.last_input_path = os.path.split(self.opts.in_files[0])[0] if not self.outdir: self.opts.out_dir = self.last_input_path self.updateFileListBox() if not self.opts.out_file: self.OutputFileName.delete(0, END) self.OutputFileName.insert(0, os.path.basename( self.opts.in_files[-1]).lower().replace('.lvm', '')) self.checkOutputFileName() self.updateFileListBox() def ParseClick(self): self.checkOptions() self.GUIParse() def checkOptions(self, m=None): for c in self.checks: setattr(self.opts, c['name'], self.boolmap[getattr(self, c['name']).get()]) if self.opts.truetemp: self.DeltaTn['state'] = DISABLED else: self.DeltaTn['state'] = NORMAL self.opts.dTn = self.DeltaTn.get().split(',') for __key in self.colmap: if self.colmap[__key] == self.OptionsColString.get(): self.opts.col_to_parse = __key def updateFileListBox(self): self.filelist.set(" ".join([x.replace(" ", "_") for x in self.opts.in_files])) def SpawnOutputDialogClick(self): outdir = filedialog.askdirectory(title="Select Output File(s)", initialdir=self.opts.out_dir) if not outdir: return if os.path.exists(outdir): self.opts.out_dir = outdir self.outdir = self.opts.out_dir # So we know the user set the output dir self.UpdateFileListBoxFrameLabel() def UpdateFileListBoxFrameLabel(self): self.FileListBoxFrameLabelVar.set( f"Output to: {self.opts.out_dir}/{self.opts.out_file}_*.txt") def checkOutputFileName(self, event=None): self.opts.out_file = self.OutputFileName.get() self.UpdateFileListBoxFrameLabel() def QuitClick(self): self.Quit() def Quit(self): self.master.destroy() def ToFront(self): '''Try to bring the main window to the front on different platforms''' if platform.system() == "Darwin": os.system( '''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''') else: self.master.attributes('-topmost', 1) self.master.attributes('-topmost', 0) self.master.lift()
class AddressBookView(Tk): """The view of an address book using Tkinter""" def __init__(self): """Initialize and configure the address book view components""" super(AddressBookView, self).__init__() # Initializing components self.frame = Frame(self) self.scroll = Scrollbar(self.frame, orient=VERTICAL) self.select = Listbox(self.frame, yscrollcommand=self.scroll.set, height=12) self.name = StringVar() self.number = StringVar() # Configure componenets self.configure_parent() self.frame.pack(side=RIGHT) self.scroll.config(command=self.select.yview) self.scroll.pack(side=RIGHT, fill=Y) self.select.pack(side=LEFT, fill=BOTH, expand=1) # Create content self.create_input_lines() self.create_buttons() self.update_contactlist() def configure_parent(self): """Configure field properties of the parent tk window""" self.geometry('400x400') self.config(bg='SlateGray3') self.resizable(0, 0) self.title('labesoft address book') def create_input_lines(self): """Create phone entry lines""" self.create_input_line(('NAME', 30, 20), (self.name, 100, 20)) self.create_input_line(('PHONE NO.', 30, 70), (self.number, 130, 70)) def create_input_line(self, lbl_info, entry_info): """Create an address book input line :param lbl_info: information used to create and place the label (text, x, y) :param entry_info: information used to create and place the entry (textvariable, x, y) """ # Create the label placed to the left Label(self, text=lbl_info[0], font='arial 12 bold', bg='SlateGray3').place(x=lbl_info[1], y=lbl_info[2]) # Create the text field placed to the right Entry(self, textvariable=entry_info[0]).place(x=entry_info[1], y=entry_info[2]) def create_buttons(self): """Create and place action buttons""" self.create_button("ADD", self.add_contact) self.create_button("EDIT", self.edit, y=260) self.create_button("DELETE", self.delete, y=210) self.create_button("VIEW", self.view, y=160) self.create_button("EXIT", self.exit_book, bg='tomato', x=300, y=320) self.create_button("RESET", self.reset, y=310) def create_button(self, text, command, bg="SlateGray4", x=50, y=110): """Create an address book button :param text: text displayed on a button :param command: command trigger by the button :param bg: background color of the button :param x: x position of the button in the view :param y: y position of the button in the view """ Button(self, text=text, font='arial 12 bold', bg=bg, command=command).place(x=x, y=y) def update_contactlist(self): """Sort and fill the managed contactlist""" contactlist.sort() self.select.delete(0, END) for current_name, phone in contactlist: self.select.insert(END, current_name) def add_contact(self): """Defines function used to add new contact""" contactlist.append([self.name.get(), self.number.get()]) self.update_contactlist() def delete(self): """Defines function will delete selected contact""" del contactlist[self.get_selection_index()] self.update_contactlist() def edit(self): """Defines function will edit existing contact""" contactlist[self.get_selection_index()] = [ self.name.get(), self.number.get() ] self.update_contactlist() def exit_book(self): """Destroy the mainloop""" self.destroy() def reset(self): """Set the name and number field to empty string""" self.name.set('') self.number.set('') def get_selection_index(self): """Defines function used to return selected value""" return int(self.select.curselection()[0]) def view(self): """Defines function will view selected contact""" current_name, phone = contactlist[self.get_selection_index()] self.name.set(current_name) self.number.set(phone)
class MainWindow(Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack() self.create_widgets() def create_widgets(self): self.imp = Button(self, command=self.new_window0) self.imp["text"] = "Импортировать" self.imp.pack() self.ex = Button(self, command=self.new_window01) self.ex["text"] = "Экспортировать" self.ex.pack() self.join = Button(self, command=self.new_window1) self.join["text"] = "Склеить" self.join.pack() self.crop = Button(self, command=self.new_window2) self.crop["text"] = "Обрезать" self.crop.pack() self.reverse = Button(self, command=self.new_window3) self.reverse["text"] = "Перевернуть" self.reverse.pack() self.speed_up = Button(self, command=self.new_window4) self.speed_up["text"] = "Ускорить" self.speed_up.pack() self.slow_down = Button(self, command=self.new_window5) self.slow_down["text"] = "Замедлить" self.slow_down.pack() self.listbox = Listbox(self, width=50) self.listbox.pack() self.update_listbox() on_workspace_update(self.update_listbox) def update_listbox(self): self.listbox.delete(0, END) for file_name in workspace.keys(): self.listbox.insert(END, file_name) def new_window0(self): self.newWindow = Toplevel(self.master) self.app1 = ImportWindow(self.newWindow) def new_window01(self): self.newWindow = Toplevel(self.master) self.app1 = ExportWindow(self.newWindow) def new_window1(self): self.newWindow = Toplevel(self.master) self.app1 = JoinWindow(self.newWindow) def new_window2(self): self.newWindow = Toplevel(self.master) self.app2 = FragmentWindow(self.newWindow) def new_window3(self): self.newWindow = Toplevel(self.master) self.app3 = ReverseWindow(self.newWindow) def new_window4(self): self.newWindow = Toplevel(self.master) self.app4 = SpeedUpWindow(self.newWindow) def new_window5(self): self.newWindow = Toplevel(self.master) self.app4 = SlowDownWindow(self.newWindow)
def get_tools(): scroll_y_listbox = Frame(window) scrollbar = Scrollbar(scroll_y_listbox, orient=VERTICAL) listbox = Listbox(scroll_y_listbox, yscrollcommand=scrollbar.set, borderwidth=0) def open_selected_tool(e=None): tool_file = listbox.get(ACTIVE) for x in self.opened_tools: if tool_file in x: raise InterfaceError( f"Only One worksheet per workbook can be opened at a time, please close {x}" ) window_date = self.deploy_window("Select Date...", 300, 280, resizable=False) ltitle = Label(window_date, text="Select the day you are capturing for:", pady=10) ltitle.pack() cal = Calendar(window_date) cal.pack() f = Frame(window_date, height=10) f.pack() def forward_with_date(): window_wait = self.deploy_window("Please Wait...", 500, 250, resizable=False) lbl = Label( window_wait, text= "Loading Data... Don't close the program, this may take a minute." ) lbl.pack() open_tool = Tool(tool_file) date = cal.selection_get() if tool_file in self.opened_tools: InterfaceError( f"'{tool_file}' has already been added to the capture area." ) else: canvas = Canvas(self.root.notebook) frame = Frame(canvas) scroll_y = Scrollbar(canvas, orient="vertical", command=canvas.yview) scroll_x = Scrollbar(canvas, orient="horizontal", command=canvas.xview) def gen_table(sheet=None): rf = open_tool.wb["DATASET"] _sheet = sheet _inc = False if _sheet is not None and _sheet['A2'].value == rf[ 'A2'].value: data = _sheet print("STANDARD IMPORT") elif _sheet is not None and _sheet[ 'A2'].value != rf['A2'].value: ws = open_tool.wb.get_sheet_by_name( f"CAP={date}") open_tool.wb.remove_sheet(ws) open_tool.save() open_tool.wb.create_sheet(f"CAP={date}") open_tool.save() data = rf _sheet = None _inc = True print("INCORRECt IMPORT") else: data = rf row = [] for xc, x in enumerate(data.rows): col = [] for yc, y in enumerate(x): rown = xc + 1 letter = excel_alpha() if _sheet is None: open_tool.wb[f"CAP={date}"][ f"{letter[yc]}{rown}"] = y.value if rown == 1 or letter[yc] == "A": val = { "type": "label", "value": y.value } else: val = { "type": "input", "value": y.value } col.append(val) row.append(col) open_tool.save() # if _inc: # messagebox.showerror("Bad CAPTURE WORKSHEET", f"Worksheet CAP={date} was broken, it has been replaced.") Table(frame, row, open_tool.file_name, f"CAP={date}") try: sheet = open_tool.wb.get_sheet_by_name( f"CAP={date}") gen_table(sheet) except KeyError: open_tool.wb.create_sheet(f"CAP={date}") open_tool.save() gen_table() canvas.create_window(0, 0, anchor='nw', window=frame) canvas.update_idletasks() canvas.configure(scrollregion=canvas.bbox('all'), yscrollcommand=scroll_y.set, xscrollcommand=scroll_x.set) canvas.pack(fill='both', expand=True, side='left') scroll_y.pack(fill='y', side='right') scroll_x.pack(fill='x', side='bottom') self.root.notebook.add( canvas, text=f"{open_tool.name} [{date}]") self.root.notebook.pack(expand=1, fill=BOTH) window_wait.destroy() window_date.destroy() button = Button(window_date, text="Process...", command=forward_with_date) button.pack() scrollbar.config(command=listbox.yview) listbox.pack(side=LEFT, fill=BOTH, expand=1) listbox.bind("<Double-1>", open_selected_tool) listbox.bind("<Return>", open_selected_tool) listbox.focus() scrollbar.pack(side=RIGHT, fill=Y) scroll_y_listbox.pack(fill=BOTH, expand=1) options = Frame(window, bg="grey", pady=7, padx=7) select = Button(options, text="Open...", pady=5, padx=25, command=open_selected_tool) select.pack(side=LEFT) close = Button(options, text="Close", pady=5, padx=25, command=lambda: window.destroy()) close.pack(side=RIGHT) options.pack(fill=X) for file in listdir("."): if file.endswith(".xlsx"): tool = Tool(file) if tool.manifest: listbox.insert(END, tool.file_name) wait.pack_forget()
class FPLGUI: SPLASH_WIDTH = 350 SPLASH_HEIGHT = 250 def __init__(self): # Get database folder. self.srcDir = os.path.dirname(os.path.abspath(__file__)) self.databaseDir = os.path.join(os.path.dirname(self.srcDir),'database') self.supportFilesDir = os.path.join(os.path.dirname(self.srcDir),'supportFiles') # Create Database folder. if not os.path.isdir(self.databaseDir): os.makedirs(self.databaseDir) # Show splash splashWindow = Tk() splashWindow.title('FPLGUI') self.screenWidth = splashWindow.winfo_screenwidth() # width of the screen self.screenHeight = splashWindow.winfo_screenheight() # height of the screen x = round((self.screenWidth/2) - (self.SPLASH_WIDTH/2)) y = round((self.screenHeight/2) - (self.SPLASH_HEIGHT/2)) splashWindow.geometry('{}x{}+{}+{}'.format(self.SPLASH_WIDTH,self.SPLASH_HEIGHT,x,y)) splashWindow.resizable(0, 0) splashWindow.iconbitmap(os.path.join(self.supportFilesDir,'FPLGUI.ico')) Label(splashWindow,text="Loading Navdata, Please wait.",justify='left',font=("Helvetica", 14)).place(relx=0.1,rely=0.1,anchor='nw') with open(os.path.join(self.supportFilesDir,'startupMessage.txt')) as startupFile: Label(splashWindow, text=startupFile.read(),justify='left',font=("Helvetica", 8)).place(relx=0.1, rely=0.4, anchor='nw') splashWindow.update() # check options for X-Plane directory self.getOptions() # Let user select X-Plane dir and write options. if self.xPlaneDir is None: OptionsWindow(splashWindow,self.databaseDir,'FPLGUI: Set inital options') self.getOptions() while self.xPlaneDir is None: showwarning('XplaneDir not specified', 'XplaneDir is mandatory. Specify it first!') OptionsWindow(splashWindow,self.databaseDir,'FPLGUI: Set inital options') self.getOptions() # Get navdata folder. if os.path.exists(os.path.join(self.xPlaneDir,'Custom Data','earth_fix.dat')) and \ os.path.exists(os.path.join(self.xPlaneDir,'Custom Data','earth_nav.dat')) and \ os.path.exists(os.path.join(self.xPlaneDir,'Custom Data','earth_awy.dat')) and \ os.path.exists(os.path.join(self.xPlaneDir,'Custom Data','apt.csv')): self.navdataDir = os.path.join(self.xPlaneDir,'Custom Data') else: self.navdataDir = os.path.join(self.xPlaneDir,'Resources','default data') #inititalize Fpl-object self.fplPath = os.path.join(self.xPlaneDir,'Resources\\plugins\\X-IvAp Resources\\Flightplans') self.fpl = Fpl(self.fplPath) # Load Fixes # self.fpl.getFixes(os.path.join(self.navdataDir,'earth_fix.dat')) # self.fpl.getNavaids(os.path.join(self.navdataDir,'earth_nav.dat')) # self.fpl.getAirports(os.path.join(self.navdataDir,'apt.csv')) # self.fpl.getAirways(os.path.join(self.navdataDir,'earth_awy.dat')) # Remove Splash. splashWindow.destroy() # Create main window self.master = Tk() self.master.title('FPLGUI') self.master.resizable(0, 0) ## menu ## menubar = Menu(self.master) filemenu = Menu(menubar,tearoff=0) filemenu.add_command(label="Clear",command=self.clear) filemenu.add_command(label="Send to XP",command=self.send) filemenu.add_separator() filemenu.add_command(label="Load",command=self.load) filemenu.add_command(label="Save",command=self.save) filemenu.add_separator() filemenu.add_command(label="Exit",command=self.master.quit) menubar.add_cascade(label="File", menu=filemenu) acmenu = Menu(menubar,tearoff=0) acmenu.add_command(label="Load Template",command=self.acLoad) acmenu.add_command(label="Save Template",command=self.acSave) menubar.add_cascade(label="Aircraft", menu=acmenu) utilmenu = Menu(menubar,tearoff=0) utilmenu.add_command(label="Import Route",command=self.importRoute) utilmenu.add_separator() utilmenu.add_command(label="Open Simbrief",command=self.simbrief) utilmenu.add_command(label="Simbrief process",command= lambda: self.simbrief(True)) utilmenu.add_command(label="Flightaware",command=self.flightaware) utilmenu.add_separator() utilmenu.add_command(label="Show at Skyvector",command=self.showSkyvector) utilmenu.add_command(label="Export to X-Plane",command=self.export2xp) utilmenu.add_command(label="Export to FF A320",command=self.export2FFA320) utilmenu.add_separator() utilmenu.add_command(label="Show FPL text",command=self.showFplText) utilmenu.add_separator() utilmenu.add_command(label="Options",command=lambda: OptionsWindow(self.master,self.databaseDir)) menubar.add_cascade(label="Extras",menu=utilmenu) self.master.config(menu=menubar) ## row 0-1 ## ## send button self.b_send = Button(self.master, text = "Send", command=self.send) self.b_send.grid(row=0, column=0, rowspan = 2) ## callsign self.l_callsign = Label(self.master, text="7 a/c ident") self.l_callsign.grid(row=0, column=1) self.callsign = StringVar(self.master) self.e_callsign = Entry(self.master, textvariable=self.callsign) self.e_callsign.grid(row=1, column=1) self.callsign.trace_add('write', self.e_callsignCB) ## rules self.l_rules = Label(self.master, text="8 flight rules") self.l_rules.grid(row=0, column=2) self.rules = StringVar(self.master) self.rules.set("V") self.o_rules = OptionMenu(self.master, self.rules, "V", "I", "Y", "Z") self.o_rules.grid(row=1, column=2) ## flighttype self.l_flighttype = Label(self.master, text=" type of flight") self.l_flighttype.grid(row=0, column=3) self.flighttype = StringVar(self.master) self.flighttype.set("S") self.o_flighttype = OptionMenu(self.master, self.flighttype, "S", "N", "G", "M", "X") self.o_flighttype.grid(row=1, column=3) ## row 2-3 ## ## number self.l_number = Label(self.master, text="9 number") self.l_number.grid(row=2, column=0) self.number = StringVar(self.master) self.e_number = Entry(self.master, textvariable=self.number) self.e_number.grid(row=3, column=0) self.number.trace_add('write', self.e_numberCB) ## type of aircraft self.l_actype = Label(self.master, text="type of aircraft") self.l_actype.grid(row=2, column=1) self.actype = StringVar(self.master) self.e_actype = Entry(self.master, textvariable=self.actype) self.e_actype.grid(row=3, column=1) self.actype.trace_add('write', self.e_actypeCB) ## wakecat self.l_wakecat = Label(self.master, text="wake turb cat") self.l_wakecat.grid(row=2, column=2) self.wakecat = StringVar(self.master) self.wakecat.set("L") self.o_wakecat = OptionMenu(self.master, self.wakecat, "L", "M", "H", "J") self.o_wakecat.grid(row=3, column=2) ## equipment self.l_equipment = Label(self.master, text="10 equipment") self.l_equipment.grid(row=2, column=3) self.equipment = StringVar(self.master) self.e_equipment = Entry(self.master, textvariable=self.equipment) self.e_equipment.grid(row=3, column=3) self.equipment.trace_add('write', self.e_equipmentCB) ## equipment self.l_transponder = Label(self.master, text="transponder") self.l_transponder.grid(row=2, column=4) self.transponder = StringVar(self.master) self.e_transponder = Entry(self.master, textvariable=self.transponder) self.e_transponder.grid(row=3, column=4) self.transponder.trace_add('write', self.e_transponderCB) ## row 4-5 ## ## depicao self.l_depicao = Label(self.master, text="13 departure aerodrome") self.l_depicao.grid(row=4, column=0) self.depicao = StringVar(self.master) self.e_depicao = Entry(self.master, textvariable=self.depicao) self.e_depicao.grid(row=5, column=0) self.depicao.trace_add('write', self.e_depicaoCB) ## deptime self.l_deptime = Label(self.master, text="departure time") self.l_deptime.grid(row=4, column=1) self.deptime = StringVar(self.master) self.e_deptime = Entry(self.master, textvariable=self.deptime) self.e_deptime.grid(row=5, column=1) self.deptime.trace_add('write', self.e_deptimeCB) ## row 6-7 ## ## speed self.l_speed = Label(self.master, text="15 cruising speed") self.l_speed.grid(row=6, column=0, columnspan=2) self.speedtype = StringVar(self.master) self.speedtype.set("N") self.o_speedtype = OptionMenu(self.master, self.speedtype, "N", "M") self.o_speedtype.grid(row=7, column=0) self.speed = StringVar(self.master) self.e_speed = Entry(self.master, textvariable=self.speed) self.e_speed.grid(row=7, column=1) self.speed.trace_add('write', self.e_speedCB) ## level self.l_level = Label(self.master, text="flight altutude/level") self.l_level.grid(row=6, column=2, columnspan=2) self.leveltype = StringVar(self.master) self.leveltype.set("F") self.o_level = OptionMenu(self.master, self.leveltype, "F", "A", "VFR") self.o_level.grid(row=7, column=2) self.level = StringVar(self.master) self.e_level = Entry(self.master, textvariable=self.level) self.e_level.grid(row=7, column=3) self.level.trace_add('write', self.e_levelCB) ## row 8-9 ## ##route self.l_route = Label(self.master, text=" route") self.l_route.grid(row=8, column=0, sticky=W) self.route = StringVar(self.master) self.e_route = Entry(self.master, width=105, textvariable=self.route) self.e_route.grid(row=9, column=0, columnspan=5) self.route.trace_add('write', self.e_routeCB) ## row 10-11 ## ## destinationAP self.l_desticao = Label(self.master, text="13 destination aerodrome") self.l_desticao.grid(row=10, column=0) self.desticao = StringVar(self.master) self.e_desticao = Entry(self.master, textvariable=self.desticao) self.e_desticao.grid(row=11, column=0) self.desticao.trace_add('write', self.e_desticaoCB) ## duration self.l_eet = Label(self.master, text="EET") self.l_eet.grid(row=10, column=1) self.eet = StringVar(self.master) self.e_eet = Entry(self.master, textvariable=self.eet) self.e_eet.grid(row=11, column=1) self.eet.trace_add('write', self.e_eetCB) ## alternates self.l_alticao = Label(self.master, text="alternate") self.l_alticao.grid(row=10, column=2) self.alticao = StringVar(self.master) self.e_alticao = Entry(self.master, textvariable=self.alticao) self.e_alticao.grid(row=11, column=2) self.alticao.trace_add('write', self.e_alticaoCB) self.l_alt2icao = Label(self.master, text="2nd alternate") self.l_alt2icao.grid(row=10, column=3) self.alt2icao = StringVar(self.master) self.e_alt2icao = Entry(self.master, textvariable=self.alt2icao) self.e_alt2icao.grid(row=11, column=3) self.alt2icao.trace_add('write', self.e_alt2icaoCB) ## row 12-13 ## ##other self.l_other = Label(self.master, text="other") self.l_other.grid(row=12, column=0, sticky=W) self.other = StringVar(self.master) self.e_other = Entry(self.master, width=105, textvariable=self.other) self.e_other.grid(row=13, column=0, columnspan=5) self.other.trace_add('write', self.e_otherCB) ## row 14-15 ## ##endurance self.l_endurance = Label(self.master, text="19 endurance") self.l_endurance.grid(row=14, column=0) self.endurance = StringVar(self.master) self.e_endurance = Entry(self.master, textvariable=self.endurance) self.e_endurance.grid(row=15, column=0) self.endurance.trace_add('write', self.e_enduranceCB) ##persons self.l_pob = Label(self.master, text="persons on board") self.l_pob.grid(row=14, column=1) self.pob = StringVar(self.master) self.e_pob = Entry(self.master, textvariable=self.pob) self.e_pob.grid(row=15, column=1) self.pob.trace_add('write', self.e_pobCB) ##pic self.l_pic = Label(self.master, text="pilot in command") self.l_pic.grid(row=14, column=2) self.pic = StringVar(self.master) self.e_pic = Entry(self.master, width=40, textvariable=self.pic) self.e_pic.grid(row=15, column=2, columnspan=2) self.pic.trace_add('write', self.e_picCB) ## row 16 ## ##empty empty = Label(self.master, text="") empty.grid(row=16, column=0) self.updateContent() # Set master window options self.master.update() masterWidth = self.master.winfo_width() masterHeight = self.master.winfo_height() x = round((self.screenWidth/2) - (masterWidth/2)) y = round((self.screenHeight/2) - (masterHeight/2)) self.master.geometry('{}x{}+{}+{}'.format(masterWidth,masterHeight,x,y)) self.master.title('FPLGUI') self.master.resizable(0, 0) self.master.iconbitmap(os.path.join(self.supportFilesDir,'FPLGUI.ico')) # Start master mainloop. self.master.mainloop() def updateContent(self): ## row 0-1 ## ## callsign self.e_callsign.delete(0, END) self.e_callsign.insert(0,self.fpl.callsign) ## rules if self.fpl.rules: self.rules.set(self.fpl.rules) else: self.rules.set("V") ## flightType if self.fpl.flighttype: self.flighttype.set(self.fpl.flighttype) else: self.flighttype.set("S") ## row 2-3 ## ## number self.e_number.delete(0, END) self.e_number.insert(0,self.fpl.number) ## type of aircraft self.e_actype.delete(0, END) self.e_actype.insert(0,self.fpl.actype) ## wakecat if self.fpl.wakecat: self.wakecat.set(self.fpl.wakecat) else: self.wakecat.set("L") ## equipment self.e_equipment.delete(0, END) self.e_equipment.insert(0,self.fpl.equipment) ## equipment self.e_transponder.delete(0, END) self.e_transponder.insert(0,self.fpl.transponder) ## row 4-5 ## ## depicao self.e_depicao.delete(0, END) self.e_depicao.insert(0,self.fpl.depicao) ## deptime self.e_deptime.delete(0, END) self.e_deptime.insert(0,self.fpl.deptime) ## row 6-7 ## ## speed if self.fpl.speedtype: self.speedtype.set(self.fpl.speedtype) else: self.speedtype.set("N") self.e_speed.delete(0, END) self.e_speed.insert(0,self.fpl.speed) ## level if self.fpl.leveltype: self.leveltype.set(self.fpl.leveltype) else: self.leveltype.set("N") self.e_level.delete(0, END) self.e_level.insert(0,self.fpl.level) ## row 8-9 ## ##route self.e_route.delete(0, END) self.e_route.insert(0,self.fpl.route) ## row 10-11 ## ## destinationAP self.e_desticao.delete(0, END) self.e_desticao.insert(0,self.fpl.desticao) ## eet self.e_eet.delete(0, END) self.e_eet.insert(0,self.fpl.eet) ## alternates self.e_alticao.delete(0, END) self.e_alticao.insert(0,self.fpl.alticao) self.e_alt2icao.delete(0, END) self.e_alt2icao.insert(0,self.fpl.alt2icao) ## row 12-13 ## ##other self.e_other.delete(0, END) self.e_other.insert(0,self.fpl.other) ## row 14-15 ## ##endurance self.e_endurance.delete(0, END) self.e_endurance.insert(0,self.fpl.endurance) ##persons self.e_pob.delete(0, END) self.e_pob.insert(0,self.fpl.pob) ##pic self.e_pic.delete(0, END) self.e_pic.insert(0,self.fpl.pic) def updateFpl(self): self.fpl.callsign = self.e_callsign.get() self.fpl.pic = self.e_pic.get() self.fpl.speedtype = self.speedtype.get() self.fpl.pob = self.e_pob.get() self.fpl.endurance = self.e_endurance.get() self.fpl.other = self.e_other.get() self.fpl.alt2icao = self.e_alt2icao.get() self.fpl.alticao = self.e_alticao.get() self.fpl.eet = self.e_eet.get() self.fpl.desticao = self.e_desticao.get() self.fpl.route = self.e_route.get() self.fpl.level = self.e_level.get() self.fpl.leveltype = self.leveltype.get() self.fpl.speed = self.e_speed.get() self.fpl.deptime = self.e_deptime.get() self.fpl.depicao = self.e_depicao.get() self.fpl.transponder = self.e_transponder.get() self.fpl.equipment = self.e_equipment.get() self.fpl.wakecat = self.wakecat.get() self.fpl.actype = self.e_actype.get() self.fpl.number = self.e_number.get() self.fpl.flighttype = self.flighttype.get() self.fpl.rules = self.rules.get() def load(self): filepath = askopenfilename(filetypes=[("X-Plane Flightplan","*.fpl"),("All","*")],initialdir=self.fpl.path) self.fpl.load(filepath) self.updateContent() def save(self): self.updateFpl() filepath = asksaveasfilename(filetypes=[("X-Plane Flightplan","*.fpl"),("All","*")],initialdir=self.fpl.path) if filepath[-4:] != ".fpl": filepath += ".fpl" self.fpl.save(filepath) print("saved!") def send(self): self.updateFpl() self.fpl.save(self.fpl.path + "\\Default.fpl") if (len(self.fpl.route) + len(self.fpl.other)) > 255: showwarning("Too long entries",'"Route" and "Other" entries are too long ({}/255 characters combined)!\nThis will lead to disconnection in flight.\nTry to shorten these fields.'.format(len(self.fpl.route) + len(self.fpl.other))) print("generated!") def clear(self): self.e_callsign.delete(0, END) self.e_number.delete(0, END) self.e_actype.delete(0, END) self.e_equipment.delete(0, END) self.e_transponder.delete(0, END) self.e_depicao.delete(0, END) self.e_deptime.delete(0, END) self.e_speed.delete(0, END) self.e_level.delete(0, END) self.e_route.delete(0, END) self.e_desticao.delete(0, END) self.e_eet.delete(0, END) self.e_alticao.delete(0, END) self.e_alt2icao.delete(0, END) self.e_other.delete(0, END) self.e_endurance.delete(0, END) self.e_pob.delete(0, END) self.e_pic.delete(0, END) def getOptions(self): # Init options with None self.xPlaneDir = None # Get options if os.path.isfile(os.path.join(self.databaseDir,'FPLGUI.cfg')): self.config = ConfigParser.RawConfigParser() self.config.read(os.path.join(self.databaseDir,'FPLGUI.cfg')) # xPlaneDir try: self.xPlaneDir = self.config.get('FPLGUI','XPLANEDIR') except ConfigParser.NoSectionError: return except ConfigParser.NoOptionError: pass if self.xPlaneDir is not None and not re.match(r'[A-Za-z]:\\',self.xPlaneDir): self.xPlaneDir = None def updateRouteDbButtonCB(self): # dbUpdated = False downloadUrl = "https://www.ivao.de/scripts/php/cms/pfpx" # curDate = int(time.time()) # lastUpdate = 0 #TODO: replace, when options implemented # timeDiff = curDate - lastUpdate timeDiff = 0 if timeDiff > 864000: ivaoDatabase = urlopen(downloadUrl) database = ivaoDatabase.read() # lastUpdate = int(time.time()) # dbUpdated = True DataFile = open(self.srcDir + r"\routeDatabase.txt",'w') DataFile.write(database) DataFile.close() def optionsButtonOkCB(self): self.top.destroy() def optionsButtonCancelCB(self): self.top.destroy() def simbrief(self,*args): self.updateFpl() url = 'https://www.simbrief.com/system/dispatch.php?' options = '' # Airports. if self.fpl.depicao and self.fpl.desticao: url = '{}&orig={}&dest={}'.format(url,self.fpl.depicao,self.fpl.desticao) else: showwarning('Airport missing','Departure and destination airport is mandatory for Simbrief.\nSpecify them first!') # Times if self.fpl.deptime: deph = self.fpl.deptime[0:1] depm = self.fpl.deptime[2:3] options = '{}&deph={}&depm={}'.format(options,deph,depm) else: showwarning('Time missing','Departure time is mandatory for Simbrief.\nSpecify it first!') return # Aircraft. if self.fpl.actype: url = '{}&type={}'.format(url,self.fpl.actype) else: showwarning('Aircraft type missing','Aircraft type is mandatory for Simbrief.\nSpecify it first!') # Route. if self.fpl.route: url = '{}&route={}'.format(url,self.fpl.route) else: showinfo('Route missing','The route is missing and will be created by Simbrief.\nNote: These routes are often not CFMU valid!') # Flightlevel. if self.fpl.level: url = '{}&fl={}00'.format(url,self.fpl.level) # Date. reFind = re.search('(?<=DOF/)\d{6}',self.fpl.other) if reFind: date = reFind.group() date = datetime.datetime(int(date[0:2])+2000,int(date[2:4]),int(date[4:6])) else: date = datetime.datetime.today() url = '{}&date={}'.format(url,date.strftime('%d%b%y')) # Airline, fltnum, registration, selcal. airline = '' fltnum = '' registration = '' selcal = '' # Airline, fltnum, registration from Callsign field. reFind = re.search('[A-Z]{5}',self.fpl.callsign) if reFind: registration = reFind.group() else: reFindAirline = re.search('[A-Z]{3}(?=\w+)',self.fpl.callsign) reFindFltnum = re.search('(?<=[A-Z]{3})\w+',self.fpl.callsign) if reFindAirline and reFindFltnum: airline = reFindAirline.group() fltnum = reFindFltnum.group() else: print('invalid Callsign!') # Registration (REG/) from other field. if not registration: reFind = re.search('(?<=REG/)[A-Z]{5}',self.fpl.other) if reFind: registration = reFind.group() # Airline (OPR/) from other field. if not airline: reFind = re.search('(?<=OPR/)[A-Z]{3}',self.fpl.other) if reFind: airline = reFind.group() # Selcal (SEL) from other field. reFind = re.search('(?<=SEL/)[A-S]{4}',self.fpl.other) if reFind: selcal = reFind.group() # Add the found values if airline: url = '{}&airline={}'.format(url,airline) if fltnum: url = '{}&fltnum={}'.format(url,fltnum) if registration: url = '{}®={}'.format(url,registration) if selcal: url = '{}&selcal={}'.format(url,selcal) # ----FPL---- # Alternates. # ----ADD---- # Extra Fuel. # Cont fuel # Reserve Fuel. # Taxi out. # Taxi in. # Cargo. # Pax. # Dep rwy. # Arr rwy. # CI # ETOPS. # Specify options. # For Simbrief process. if len(args) and args[0]: url = '{}&planformat=LIDO&units=KGS&navlog=0&etops=0&stepclimbs=0&tlr=0¬ams=0&firnot=0&maps=none'.format(url) # For show Simbiref. else: url = '{}&planformat=LIDO&units=KGS&navlog=1&etops=1&stepclimbs=0&tlr=0¬ams=1&firnot=1&maps=detail'.format(url) # print(url) # pass # Open simbrief. webbrowser.open(url,new=2) def simbriefOpen(self): pass def simbriefProcess(self): pass ## Display flights for departure and destination airport on flightaware. def flightaware(self): self.updateFpl() url = 'https://de.flightaware.com/live/findflight?origin={}&destination={}'.format(self.fpl.depicao,self.fpl.desticao) webbrowser.open(url,new=2) def importRoute(self): self.updateFpl() with open(self.databaseDir + r"\routeDatabase.txt") as dataFile: database = dataFile.read() self.fpl.desticao = self.fpl.desticao.upper() self.fpl.depicao = self.fpl.depicao.upper() patRte = re.compile(self.fpl.depicao + self.fpl.desticao + r"\d{2};.+\n") routes = patRte.findall(database) ## parse routes self.routing = [] self.comment = [] self.fl = [] maxLenCom = 0 for k in range(len(routes)): parts = re.split(";",routes[k]) self.routing.append(parts[1]) curComment = parts[2] #curComment = curComment[1:-2] curComment = re.split(",",curComment) curFL = curComment[0] curCommentList = curComment[1:] curComment = "" for l in curCommentList: curComment += l self.comment.append(curComment[1:-2]) if len(curComment[1:-2]) > maxLenCom: maxLenCom = len(curComment[1:-2]) self.fl.append(curFL) ## show window self.importRouteTop = Toplevel(self.master) if len(self.routing) > 0: Label(self.importRouteTop, text="Choose a Route").pack() self.importRouteListboxTl = Listbox(self.importRouteTop,width=180) self.importRouteListboxTl.pack() for k in range(len(self.routing)): self.importRouteListboxTl.insert(END, "{:11} {:50} {}".format(self.fl[k],self.comment[k],self.routing[k])) self.importRouteListboxTl.selection_set(0) self.tlOkButton = Button(self.importRouteTop,text="OK",command=self.routeListCB,width=80) self.tlOkButton.pack() self.master.wait_window(self.importRouteTop) else: Label(self.importRouteTop, text="No Routes found!").pack() self.tlOkButton = Button(self.importRouteTop,text="OK",command=self.importRouteTop.destroy,width=10) self.tlOkButton.pack() def export2FFA320(self): """ Write the route to Flight Factor A320 Company Routes Database. Import to aircraft via the MCDU """ self.updateFpl() #self.fpl.actype,self.fpl.depicao,self.fpl.desticao,deph,depm,reg,selcal,self.fpl.route,self.fpl.level fpl = self.fpl # check if ac type is A320 if fpl.actype != 'A320': warn('A/C type is not A320!') # remove SID/STAR from route route = re.sub('[A-Z]{5}\d[A-Z]','',fpl.route).strip() # write route string routeString = 'RTE {}{} {} {} {} CI30 FL{}'.format(fpl.depicao, fpl.desticao, fpl.depicao, route, fpl.desticao, fpl.level ) # find and open route database # check for duplicate and overwrite or append route coRoutePath = os.path.join(self.xPlaneDir,r'Aircraft\FlightFactorA320\data\corte.in') with open(coRoutePath,'r') as coRouteFile: lines = coRouteFile.readlines() written = False for k in range(len(lines)): if 'RTE {}{}'.format(fpl.depicao,fpl.desticao) in lines[k]: lines[k] = '{}\n'.format(routeString) written = True break if not written: if lines[-1][-1] == '\n': lines.append(routeString) else: lines.append('\n{}'.format(routeString)) # write new file with open(coRoutePath,'w') as coRouteFile: for k in lines: coRouteFile.write(k) # print success message print('exported (FF A320)!') def export2xp(self): self.updateFpl() # Get file path for export. fileCount = 0 fmsFilePath = os.path.abspath(__file__) while os.path.isfile(fmsFilePath): fileCount += 1 fmsFilePath = os.path.join(self.xPlaneDir,'Output','FMS plans','{}{}{:02}.fms'.format(self.fpl.depicao,self.fpl.desticao,fileCount)) # Get coordinates of dep. curCoordinates = self.fpl.airports[self.fpl.depicao] # Get start altitude. curAltitude = int(self.fpl.level) * 100 newAltitude = curAltitude # Remove SID/STAR from route and split in parts route = re.sub('[A-Z]{5}\d[A-Z]','',self.fpl.route).strip() route = route.split() # with open(fmsFilePath,'w') as fmsFile: # Write header and departure. fmsStr = '' # Process route. nWaypoints = 1 curWaypoint = None curWaypointName = None lastWaypointName = None curAirway = None for rpId,rp in enumerate(route): if not(rpId % 2): # Waypoint # Split altitude from wp if '/' in rp: wpSplit = rp.split('/') curWaypointName = wpSplit[0] altMatch = re.search('F\d+', wpSplit[1]) if altMatch is not None: newAltitude = int(wpSplit[1][altMatch.start()+1:altMatch.end()]) * 100 else: curWaypointName = rp if curAirway is None: # After DCT curAltitude = newAltitude curWaypoint = self.fpl.waypoints[curWaypointName] minDistance = 3.2 # slightly greater than pi for wp in curWaypoint: distance = avFormula.gcDistance(curCoordinates[0],curCoordinates[1],wp[0],wp[1]) if distance < minDistance: minDistance = distance nearWp = wp fmsStr = '{}{} {} DRCT {} {} {}\n'.format(fmsStr,nearWp[2],curWaypointName,curAltitude,nearWp[0],nearWp[1]) nWaypoints += 1 else: # After Airway curAirwayParts = self.fpl.airways[curAirway].parts curAirwayName = curAirway curAirway = None # Get part with both waypoints. for pa in curAirwayParts: if lastWaypointName in [k for m in pa for k in m] and curWaypointName in [n for o in pa for n in o]: curAirway = pa break if curAirway is None: print('One or both waypoints are no part of airway {}!'.format(curAirwayName)) raise(Exception,'Airway Error!') curWaypointId = None lastWaypointId = None for wpId,wp in enumerate(curAirway): if curWaypointName in wp: curWaypointId = wpId elif lastWaypointName in wp: lastWaypointId = wpId if curWaypointId is not None and lastWaypointId is not None: step = int(copysign(1,curWaypointId - lastWaypointId)) break for wp in range(lastWaypointId+step,curWaypointId+step,step): if curAirway[wp][0] == curWaypointName: curAltitude = newAltitude fmsStr = '{}{} {} {} {} {} {}\n'.format(fmsStr,curAirway[wp][3],curAirway[wp][0],curAirwayName,curAltitude,curAirway[wp][1],curAirway[wp][2]) nWaypoints += 1 curAirway = None elif rp != 'DCT': # Airway curAirway = rp lastWaypointName = curWaypointName curCoordinates = self.fpl.airports[self.fpl.desticao] fmsStr = '{}1 {} ADES 0.000000 {} {}'.format(fmsStr,self.fpl.desticao,curCoordinates[0],curCoordinates[1]) nWaypoints += 1 curCoordinates = self.fpl.airports[self.fpl.depicao] fmsStr = 'I\n1100 Version\nCYCLE {}\nADEP {}\nADES {}\nNUMENR {}\n1 {} ADEP 0.000000 {} {}\n{}'.format(self.fpl.cycleNumber, self.fpl.depicao, self.fpl.desticao, nWaypoints, self.fpl.depicao, curCoordinates[0],curCoordinates[1], fmsStr) # print(fmsStr) with open(fmsFilePath,'w') as fmsFile: fmsFile.write(fmsStr) print('fms file exported to XP!') def acLoad(self): self.updateFpl() self.getAcTemplates() # get the right template. if self.fpl.actype in self.acTemplates: template = self.acTemplates[self.fpl.actype] # Assign values to FPL. self.fpl.equipment = template[0] self.fpl.transponder = template[1] matchObj = re.search(r'PBN/\w+', self.fpl.other,flags=re.A) # @UndefinedVariable if matchObj is not None: self.fpl.other = self.fpl.other.replace(self.fpl.other[matchObj.start():matchObj.end()], '') self.fpl.other = re.sub(' +',' ',self.fpl.other) self.fpl.other = self.fpl.other.strip() self.fpl.other = 'PBN/{} {}'.format(template[2],self.fpl.other) self.fpl.other = self.fpl.other.strip() self.fpl.wakecat = template[3] self.fpl.speed = template[4] self.fpl.pob = template[5] # Update Fields. self.updateContent() else: messagebox.showinfo("FPL", "No templates found for\naircraft {}!".format(self.fpl.actype)) def acSave(self): # Preparations. self.updateFpl() self.getAcTemplates() # Check if template already exists and ask what to do. if self.fpl.actype in self.acTemplates: if messagebox.askyesno("Overwrite?","A template for the aircraft {} already exists.\nOverwrite?".format(self.fpl.actype)): self.acTemplates.pop(self.fpl.actype) else: return # Update Aircraft templates. self.acTemplates[self.fpl.actype] = [] self.acTemplates[self.fpl.actype].append(self.fpl.equipment) self.acTemplates[self.fpl.actype].append(self.fpl.transponder) matchObj = re.search(r'PBN/\w+', self.fpl.other,flags=re.A) # @UndefinedVariable if matchObj is not None: self.acTemplates[self.fpl.actype].append(self.fpl.other[matchObj.start():matchObj.end()].replace('PBN/','')) else: self.acTemplates[self.fpl.actype].append('') self.acTemplates[self.fpl.actype].append(self.fpl.wakecat) self.acTemplates[self.fpl.actype].append(self.fpl.speed) self.acTemplates[self.fpl.actype].append(self.fpl.pob) # Write the new list with open(os.path.join(self.databaseDir,'aircraft.csv'),'w') as acFile: acFile.write('ac;equip;transponder;PBN;wakeCat;speed;x;POB\n') for te in self.acTemplates: curTemplate = self.acTemplates[te] acFile.write('{};{};{};{};{};{};{}\n'.format(te,curTemplate[0],curTemplate[1],curTemplate[2],curTemplate[3],curTemplate[4],curTemplate[5])) def getAcTemplates(self): self.acTemplates = {} if not os.path.exists(os.path.join(self.databaseDir,'aircraft.csv')): open(os.path.join(self.databaseDir,'aircraft.csv'),'w').close() with open(os.path.join(self.databaseDir,'aircraft.csv')) as acFile: for lineNr,line in enumerate(acFile): if lineNr: lineSplit = line.rstrip('\n').split(';') self.acTemplates[lineSplit[0]] = [lineSplit[1],lineSplit[2],lineSplit[3],lineSplit[4],lineSplit[5],lineSplit[6]] def showSkyvector(self): # Calculate middle point. depCoordinates = self.fpl.airports[self.fpl.depicao] destCoordinates = self.fpl.airports[self.fpl.desticao] intermediatePoint = avFormula.gcIntermediatePoint(depCoordinates[0], depCoordinates[1], destCoordinates[0], destCoordinates[1]) skyvectorUrl = 'http://skyvector.com/?ll={:9.6f},{:9.6f}&chart=304&zoom=6&fpl=%20{}%20{}%20{}'.format(intermediatePoint[0], intermediatePoint[1], self.fpl.depicao, self.fpl.route.replace(' ','%20'), self.fpl.desticao) webbrowser.open(skyvectorUrl,new=2) def showFplText(self): # Get Field contents. self.updateFpl() # Init string. fplString = '(FPL\n' # Complete string. fplString = '{}-{}-{}{}\n'.format(fplString, self.fpl.callsign, self.fpl.rules, self.fpl.flighttype) fplString = '{}-{}{}/{}-{}/{}\n'.format(fplString, self.fpl.number, self.fpl.actype, self.fpl.wakecat, self.fpl.equipment, self.fpl.transponder) fplString = '{}-{}{}\n'.format(fplString, self.fpl.depicao, self.fpl.deptime) fplString = '{}-N{:04}F{:03} {}\n'.format(fplString, int(self.fpl.speed), int(self.fpl.level), self.fpl.route) fplString = '{}-{}{} {} {}\n'.format(fplString, self.fpl.desticao, self.fpl.eet, self.fpl.alticao, self.fpl.alt2icao) fplString = '{}-{})'.format(fplString,self.fpl.other) # Print string. print(fplString) # Copy to clipboard. r = Tk() r.withdraw() r.clipboard_clear() r.clipboard_append(str(fplString)) r.update() r.destroy() # Show in window. showinfo("Flightplan text", '{}\n\n(Copied to clipboard.)'.format(fplString)) # Callbacks def routeListCB(self): selectedRoute = self.importRouteListboxTl.curselection() selectedRoute = selectedRoute[0] self.fpl.route = self.routing[selectedRoute] self.fpl.route = self.fpl.route[5:-5] self.importRouteTop.destroy() self.updateContent() def e_callsignCB(self,*args): #@UnusedVariable string = self.callsign.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum(): self.callsign.set(string[0:-1]) else: self.callsign.set(self.callsign.get().upper()) def e_numberCB(self,*args): #@UnusedVariable string = self.number.get() if len(string): enteredChar = string[-1] if not enteredChar.isdigit(): self.number.set(string[0:-1]) def e_actypeCB(self,*args): #@UnusedVariable string = self.actype.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum() or len(string) > 4: self.actype.set(string[0:-1]) else: self.actype.set(self.actype.get().upper()) def e_equipmentCB(self,*args): #@UnusedVariable string = self.equipment.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum(): self.equipment.set(string[0:-1]) else: self.equipment.set(self.equipment.get().upper()) def e_transponderCB(self,*args): #@UnusedVariable string = self.transponder.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum(): self.transponder.set(string[0:-1]) else: self.transponder.set(self.transponder.get().upper()) def e_depicaoCB(self,*args): #@UnusedVariable string = self.depicao.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum() or len(string) > 4: self.depicao.set(string[0:-1]) else: self.depicao.set(self.depicao.get().upper()) def e_deptimeCB(self,*args): #@UnusedVariable string = self.deptime.get() if len(string): enteredChar = string[-1] if not enteredChar.isdigit() or len(string) > 4: self.deptime.set(string[0:-1]) def e_speedCB(self,*args): #@UnusedVariable string = self.speed.get() if len(string): enteredChar = string[-1] if not enteredChar.isdigit() or len(string) > 4: self.speed.set(string[0:-1]) def e_levelCB(self,*args): #@UnusedVariable string = self.level.get() if len(string): enteredChar = string[-1] if not enteredChar.isdigit() or len(string) > 3: self.level.set(string[0:-1]) def e_routeCB(self,*args): #@UnusedVariable string = self.route.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum() and enteredChar != '/' and enteredChar != ' ': self.route.set(string[0:-1]) else: self.route.set(self.route.get().upper()) def e_desticaoCB(self,*args): #@UnusedVariable string = self.desticao.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum() or len(string) > 4: self.desticao.set(string[0:-1]) else: self.desticao.set(self.desticao.get().upper()) def e_eetCB(self,*args): #@UnusedVariable string = self.eet.get() if len(string): enteredChar = string[-1] if not enteredChar.isdigit() or len(string) > 4: self.eet.set(string[0:-1]) def e_alticaoCB(self,*args): #@UnusedVariable string = self.alticao.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum() or len(string) > 4: self.alticao.set(string[0:-1]) else: self.alticao.set(self.alticao.get().upper()) def e_alt2icaoCB(self,*args): #@UnusedVariable string = self.alt2icao.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum() or len(string) > 4: self.alt2icao.set(string[0:-1]) else: self.alt2icao.set(self.alt2icao.get().upper()) def e_otherCB(self,*args): #@UnusedVariable string = self.other.get() if len(string): enteredChar = string[-1] if not enteredChar.isalnum() and enteredChar != '/' and enteredChar != ' ': self.other.set(string[0:-1]) else: self.other.set(self.other.get().upper()) def e_enduranceCB(self,*args): #@UnusedVariable string = self.endurance.get() if len(string): enteredChar = string[-1] if not enteredChar.isdigit() or len(string) > 4: self.endurance.set(string[0:-1]) def e_pobCB(self,*args): #@UnusedVariable string = self.pob.get() if len(string): enteredChar = string[-1] if not enteredChar.isdigit(): self.pob.set(string[0:-1]) def e_picCB(self,*args): #@UnusedVariable string = self.pic.get() if len(string): enteredChar = string[-1] if not enteredChar.isalpha() and enteredChar != ' ' and enteredChar != "'" and enteredChar != '-': self.pic.set(string[0:-1])
class LucteriosMainForm(Tk): def __init__(self): Tk.__init__(self) try: img = Image("photo", file=join( dirname(import_module('lucterios.install').__file__), "lucterios.png")) self.tk.call('wm', 'iconphoto', self._w, img) except: pass self.has_checked = False self.title(ugettext("Lucterios installer")) self.minsize(475, 260) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.running_instance = {} self.resizable(True, True) self.protocol("WM_DELETE_WINDOW", self.on_closing) self.ntbk = ttk.Notebook(self) self.ntbk.grid(row=0, column=0, columnspan=1, sticky=(N, S, E, W)) self.create_instance_panel() self.create_module_panel() stl = ttk.Style() stl.theme_use("default") stl.configure("TProgressbar", thickness=5) self.progress = ttk.Progressbar( self, style="TProgressbar", orient='horizontal', mode='indeterminate') self.progress.grid(row=1, column=0, sticky=(E, W)) self.btnframe = Frame(self, bd=1) self.btnframe.grid(row=2, column=0, columnspan=1) Button(self.btnframe, text=ugettext("Refresh"), width=20, command=self.refresh).grid( row=0, column=0, padx=3, pady=3, sticky=(N, S)) self.btnupgrade = Button( self.btnframe, text=ugettext("Search upgrade"), width=20, command=self.upgrade) self.btnupgrade.config(state=DISABLED) self.btnupgrade.grid(row=0, column=1, padx=3, pady=3, sticky=(N, S)) Button(self.btnframe, text=ugettext("Close"), width=20, command=self.on_closing).grid( row=0, column=2, padx=3, pady=3, sticky=(N, S)) def on_closing(self): all_stop = True instance_names = list(self.running_instance.keys()) for old_item in instance_names: if (self.running_instance[old_item] is not None) and self.running_instance[old_item].is_running(): all_stop = False if all_stop or askokcancel(None, ugettext("An instance is always running.\nDo you want to close?")): self.destroy() else: self.refresh() def destroy(self): instance_names = list(self.running_instance.keys()) for old_item in instance_names: if self.running_instance[old_item] is not None: self.running_instance[old_item].stop() del self.running_instance[old_item] Tk.destroy(self) def create_instance_panel(self): frm_inst = Frame(self.ntbk) frm_inst.grid_columnconfigure(0, weight=1) frm_inst.grid_rowconfigure(0, weight=1) frm_inst.grid_columnconfigure(1, weight=3) frm_inst.grid_rowconfigure(1, weight=0) self.instance_list = Listbox(frm_inst, width=20) self.instance_list.bind('<<ListboxSelect>>', self.select_instance) self.instance_list.pack() self.instance_list.grid(row=0, column=0, sticky=(N, S, W, E)) self.instance_txt = Text(frm_inst, width=75) self.instance_txt.grid(row=0, column=1, rowspan=2, sticky=(N, S, W, E)) self.instance_txt.config(state=DISABLED) self.btninstframe = Frame(frm_inst, bd=1) self.btninstframe.grid(row=1, column=0, columnspan=1) self.btninstframe.grid_columnconfigure(0, weight=1) Button(self.btninstframe, text=ugettext("Launch"), width=25, command=self.open_inst).grid( row=0, column=0, columnspan=2, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Modify"), width=10, command=self.modify_inst).grid(row=1, column=0, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Delete"), width=10, command=self.delete_inst).grid(row=1, column=1, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Save"), width=10, command=self.save_inst).grid(row=2, column=0, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Restore"), width=10, command=self.restore_inst).grid(row=2, column=1, sticky=(N, S)) Button(self.btninstframe, text=ugettext("Add"), width=25, command=self.add_inst).grid( row=3, column=0, columnspan=2, sticky=(N, S)) self.ntbk.add(frm_inst, text=ugettext('Instances')) def create_module_panel(self): frm_mod = Frame(self.ntbk) frm_mod.grid_columnconfigure(0, weight=1) frm_mod.grid_rowconfigure(0, weight=1) self.module_txt = Text(frm_mod) self.module_txt.grid(row=0, column=0, sticky=(N, S, W, E)) self.module_txt.config(state=DISABLED) self.ntbk.add(frm_mod, text=ugettext('Modules')) def do_progress(self, progressing): if not progressing: self.progress.stop() self.progress.grid_remove() else: self.progress.start(25) self.progress.grid(row=1, column=0, sticky=(E, W)) def enabled(self, is_enabled, widget=None): if widget is None: widget = self self.do_progress(not is_enabled) if is_enabled: widget.config(cursor="") else: widget.config(cursor="watch") if isinstance(widget, Button) and (widget != self.btnupgrade): if is_enabled and (not hasattr(widget, 'disabled') or not widget.disabled): widget.config(state=NORMAL) else: widget.config(state=DISABLED) else: for child_cmp in widget.winfo_children(): self.enabled(is_enabled, child_cmp) @ThreadRun def refresh(self, instance_name=None): if instance_name is None: instance_name = self.get_selected_instance_name() self.instance_txt.delete("1.0", END) self._refresh_instance_list() self.set_select_instance_name(instance_name) if not self.has_checked: self._refresh_modules() if self.instance_list.size() == 0: sleep(.3) self._refresh_modules() sleep(.3) self.after_idle(self.add_inst) def _refresh_modules(self): self.btnupgrade.config(state=DISABLED) self.module_txt.config(state=NORMAL) self.module_txt.delete("1.0", END) lct_glob = LucteriosGlobal() mod_lucterios, mod_applis, mod_modules = lct_glob.installed() self.module_txt.insert( END, ugettext("Lucterios core\t\t%s\n") % mod_lucterios[1]) self.module_txt.insert(END, '\n') self.module_txt.insert(END, ugettext("Application\n")) for appli_item in mod_applis: self.module_txt.insert( END, "\t%s\t%s\n" % (appli_item[0].ljust(30), appli_item[1])) self.module_txt.insert(END, ugettext("Modules\n")) for module_item in mod_modules: self.module_txt.insert( END, "\t%s\t%s\n" % (module_item[0].ljust(30), module_item[1])) extra_urls = lct_glob.get_extra_urls() if len(extra_urls) > 0: self.module_txt.insert(END, "\n") self.module_txt.insert(END, ugettext("Pypi servers\n")) for extra_url in extra_urls: self.module_txt.insert(END, "\t%s\n" % extra_url) self.module_txt.config(state=DISABLED) self.has_checked = True self.after(1000, lambda: Thread(target=self.check).start()) def _refresh_instance_list(self): self.instance_list.delete(0, END) luct_glo = LucteriosGlobal() instance_list = luct_glo.listing() for item in instance_list: self.instance_list.insert(END, item) if item not in self.running_instance.keys(): self.running_instance[item] = None instance_names = list(self.running_instance.keys()) for old_item in instance_names: if old_item not in instance_list: if self.running_instance[old_item] is not None: self.running_instance[old_item].stop() del self.running_instance[old_item] def set_select_instance_name(self, instance_name): cur_sel = 0 for sel_iter in range(self.instance_list.size()): if self.instance_list.get(sel_iter) == instance_name: cur_sel = sel_iter break self.instance_list.selection_set(cur_sel) self.select_instance(None) def get_selected_instance_name(self): if len(self.instance_list.curselection()) > 0: return self.instance_list.get(int(self.instance_list.curselection()[0])) else: return "" def set_ugrade_state(self, must_upgrade): if must_upgrade: self.btnupgrade.config(state=NORMAL) self.btnupgrade["text"] = ugettext("Upgrade needs") else: self.btnupgrade["text"] = ugettext("No upgrade") self.btnupgrade.config(state=DISABLED) def check(self): must_upgrade = False try: lct_glob = LucteriosGlobal() _, must_upgrade = lct_glob.check() finally: self.after(300, self.set_ugrade_state, must_upgrade) @ThreadRun def upgrade(self): self.btnupgrade.config(state=DISABLED) self.instance_list.config(state=DISABLED) try: from logging import getLogger admin_path = import_module( "lucterios.install.lucterios_admin").__file__ proc = Popen( [sys.executable, admin_path, "update"], stderr=STDOUT, stdout=PIPE) value = proc.communicate()[0] try: value = value.decode('ascii') except: pass six.print_(value) if proc.returncode != 0: getLogger("lucterios.admin").error(value) else: getLogger("lucterios.admin").info(value) showinfo(ugettext("Lucterios installer"), ugettext( "The application must restart")) python = sys.executable os.execl(python, python, *sys.argv) finally: self._refresh_modules() self.btnupgrade.config(state=NORMAL) self.instance_list.config(state=NORMAL) @ThreadRun def select_instance(self, evt): if self.instance_list['state'] == NORMAL: self.instance_list.config(state=DISABLED) try: instance_name = self.get_selected_instance_name() self.instance_txt.configure(state=NORMAL) self.instance_txt.delete("1.0", END) if instance_name != '': if instance_name not in self.running_instance.keys(): self.running_instance[instance_name] = None inst = LucteriosInstance(instance_name) inst.read() self.instance_txt.insert(END, "\t\t\t%s\n\n" % inst.name) self.instance_txt.insert( END, ugettext("Database\t\t%s\n") % inst.get_database_txt()) self.instance_txt.insert( END, ugettext("Appli\t\t%s\n") % inst.get_appli_txt()) self.instance_txt.insert( END, ugettext("Modules\t\t%s\n") % inst.get_module_txt()) self.instance_txt.insert( END, ugettext("Extra\t\t%s\n") % inst.get_extra_txt()) self.instance_txt.insert(END, '\n') if self.running_instance[instance_name] is not None and self.running_instance[instance_name].is_running(): self.instance_txt.insert(END, ugettext( "=> Running in http://%(ip)s:%(port)d\n") % {'ip': self.running_instance[instance_name].lan_ip, 'port': self.running_instance[instance_name].port}) self.btninstframe.winfo_children()[0]["text"] = ugettext( "Stop") else: self.running_instance[instance_name] = None self.instance_txt.insert(END, ugettext("=> Stopped\n")) self.btninstframe.winfo_children()[0]["text"] = ugettext( "Launch") else: self.btninstframe.winfo_children()[0]["text"] = ugettext( "Launch") self.btninstframe.winfo_children()[0].disabled = ( instance_name == '') self.btninstframe.winfo_children()[1].disabled = ( instance_name == '') self.btninstframe.winfo_children()[2].disabled = ( instance_name == '') self.btninstframe.winfo_children()[3].disabled = ( instance_name == '') self.btninstframe.winfo_children()[4].disabled = ( instance_name == '') self.instance_txt.configure(state=DISABLED) finally: setup_from_none() self.instance_list.config(state=NORMAL) @ThreadRun def add_modif_inst_result(self, result, to_create): inst = LucteriosInstance(result[0]) inst.set_extra("LANGUAGE_CODE='%s'" % result[5]) inst.set_appli(result[1]) inst.set_module(result[2]) inst.set_database(result[4]) if to_create: inst.add() else: inst.modif() inst = LucteriosInstance(result[0]) inst.set_extra(result[3]) inst.security() self.refresh(result[0]) def add_inst(self): self.enabled(False) try: self.do_progress(False) ist_edt = InstanceEditor() ist_edt.execute() ist_edt.transient(self) self.wait_window(ist_edt) finally: self.enabled(True) if ist_edt.result is not None: self.add_modif_inst_result(ist_edt.result, True) def modify_inst(self): self.enabled(False) try: self.do_progress(False) ist_edt = InstanceEditor() ist_edt.execute(self.get_selected_instance_name()) ist_edt.transient(self) self.wait_window(ist_edt) finally: self.enabled(True) if ist_edt.result is not None: self.add_modif_inst_result(ist_edt.result, False) @ThreadRun def delete_inst_name(self, instance_name): inst = LucteriosInstance(instance_name) inst.delete() self.refresh() def delete_inst(self): setup_from_none() instance_name = self.get_selected_instance_name() if askokcancel(None, ugettext("Do you want to delete '%s'?") % instance_name): self.delete_inst_name(instance_name) else: self.refresh() @ThreadRun def open_inst(self): instance_name = self.get_selected_instance_name() if instance_name != '': try: if instance_name not in self.running_instance.keys(): self.running_instance[instance_name] = None if self.running_instance[instance_name] is None: port = FIRST_HTTP_PORT for inst_obj in self.running_instance.values(): if (inst_obj is not None) and (inst_obj.port >= port): port = inst_obj.port + 1 self.running_instance[instance_name] = RunServer( instance_name, port) self.running_instance[instance_name].start() else: self.running_instance[instance_name].stop() self.running_instance[instance_name] = None finally: self.set_select_instance_name(instance_name) @ThreadRun def save_instance(self, instance_name, file_name): inst = LucteriosInstance(instance_name) inst.filename = file_name if inst.archive(): showinfo(ugettext("Lucterios installer"), ugettext( "Instance saved to %s") % file_name) else: showerror( ugettext("Lucterios installer"), ugettext("Instance not saved!")) self.refresh(instance_name) def save_inst(self): instance_name = self.get_selected_instance_name() if instance_name != '': file_name = asksaveasfilename( parent=self, filetypes=[('lbk', '.lbk'), ('*', '.*')]) if file_name != '': self.save_instance(instance_name, file_name) @ThreadRun def restore_instance(self, instance_name, file_name): if file_name[-4:] == '.bkf': rest_inst = MigrateFromV1(instance_name, withlog=True) else: rest_inst = LucteriosInstance(instance_name) rest_inst.filename = file_name if rest_inst.restore(): showinfo(ugettext("Lucterios installer"), ugettext( "Instance restore from %s") % file_name) else: showerror( ugettext("Lucterios installer"), ugettext("Instance not restored!")) self.refresh(instance_name) def restore_inst(self): instance_name = self.get_selected_instance_name() if instance_name != '': file_name = askopenfilename( parent=self, filetypes=[('lbk', '.lbk'), ('bkf', '.bkf'), ('*', '.*')]) if file_name != '': self.restore_instance(instance_name, file_name) def execute(self): self.refresh() center(self, (700, 300)) self.mainloop()
class Trace(Module): ''' Module to manage all of the different traces (with unique names/colors) and the Crosshairs objects associated to each one. In particular, handles creation/modfication of traces and crosshairs. ''' def __init__(self, app): info(' - initializing module: Trace') self.app = app # some images for the buttons # Source for icons: https://material.io/tools/icons/?style=outline # License: Apache Version 2.0 www.apache.org/licenses/LICENSE-2.0.txt data_copy = '''R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAJHjI+pCe3/1oHUSdOunmDvHFTWBYrjUnbMuWIqAqEqCMdt+HI25yrVTZMEcT3NMPXJEZckJdKorCWbU2H0JqvKTBErl+XZFAAAOw''' data_paste = '''R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAJBjI+pq+DAonlPToqza7rv9FlBeJCSOUJpd3EXm7piDKoi+nkqvnttPaMhUAzeiwJMapJDm8U44+kynCkmiM1qZwUAOw''' self.img_copy = PhotoImage(data=data_copy) self.img_paste = PhotoImage(data=data_paste) self.displayedColour = None #self.app.Data.getCurrentTraceColor() # array of trace names for this directory self.available = self.app.Data.getTopLevel('traces') self.available = [] if self.available == None else self.available # dictionary to hold trace -> [crosshairs] data self.crosshairs = {} # set of currently selected crosshairs self.selected = set() # set of copied crosshairs self.copied = [] # declare & init trace string variable self.traceSV = StringVar() self.traceSV.set('') # frame for (most of) our widgets self.frame = Frame(self.app.LEFT) #, pady=7, padx=7) self.frame.grid(row=4) # listbox to contain all of our traces lbframe = Frame(self.frame) self.scrollbar = Scrollbar(lbframe) self.listbox = Listbox(lbframe, yscrollcommand=self.scrollbar.set, width=12, exportselection=False, takefocus=0) self.scrollbar.config(command=self.listbox.yview) for trace in self.available: self.listbox.insert('end', trace) for i, item in enumerate(self.listbox.get(0, 'end')): # select our "default trace" if item == self.app.Data.getTopLevel('defaultTraceName'): self.listbox.selection_clear(0, 'end') self.listbox.select_set(i) # this module is responsible for so many widgets that we need a different # strategy for keeping track of everything that needs constistent grid() / # grid_remove() behavior self.TkWidgets = [ self.getWidget(Header(self.frame, text="Choose a trace"), row=5, column=0, columnspan=4), self.getWidget(lbframe, row=10, column=0, rowspan=50), self.getWidget(Button(self.frame, text='Set as default', command=self.setDefaultTraceName, takefocus=0), row=10, column=2, columnspan=2), self.getWidget(Button(self.frame, text='Select all', command=self.selectAll, takefocus=0), row=11, column=2, columnspan=2), self.getWidget(Button(self.frame, image=self.img_copy, command=self.copy, takefocus=0), row=12, column=2), # FIXME: add tooltip for "Copy" self.getWidget(Button(self.frame, image=self.img_paste, command=self.paste, takefocus=0), row=12, column=3), # FIXME: add tooltip for "Paste" self.getWidget(Entry(self.frame, width=8, textvariable=self.displayedColour), row=13, column=1, columnspan=2, sticky='w'), self.getWidget(Button(self.frame, text='Recolor', command=self.recolor, takefocus=0), row=13, column=3), self.getWidget(Button(self.frame, text='Clear', command=self.clear, takefocus=0), row=15, column=2, columnspan=2), self.getWidget(Entry(self.frame, width=12, textvariable=self.traceSV), row=100, column=0, sticky='w'), self.getWidget(Button(self.frame, text='New', command=self.newTrace, takefocus=0), row=100, column=2), self.getWidget(Button(self.frame, text='Rename', command=self.renameTrace, takefocus=0), row=100, column=3) ] # there's probably a better way to do this than indexing into self.TkWidgets self.TkWidgets[6]['widget'].bind( '<Return>', lambda ev: self.TkWidgets[0]['widget'].focus()) self.TkWidgets[6]['widget'].bind( '<Escape>', lambda ev: self.TkWidgets[0]['widget'].focus()) self.TkWidgets[9]['widget'].bind( '<Return>', lambda ev: self.TkWidgets[0]['widget'].focus()) self.TkWidgets[9]['widget'].bind( '<Escape>', lambda ev: self.TkWidgets[0]['widget'].focus()) if util.get_platform() == 'Linux': self.app.bind('<Control-r>', self.recolor) self.app.bind('<Control-c>', self.copy) self.app.bind('<Control-v>', self.paste) else: self.app.bind('<Command-r>', self.recolor) self.app.bind('<Command-c>', self.copy) self.app.bind('<Command-v>', self.paste) self.grid() def update(self): ''' on change frames ''' # self.grid() #NOTE this is called during zoom and pan #this means the crosshairs are redrawn for every <Motion> call, which is a lot #we could probably just move them instead self.reset() # clear our crosshairs self.read() # read from file #self.frame.update() #debug("TraceModule", self.frame.winfo_width()) def reset(self): ''' on change files ''' # undraw all the crosshairs for trace in self.crosshairs: for ch in self.crosshairs[trace]: ch.undraw() # and empty out our trackers self.crosshairs = {} self.selected = set() def add(self, x, y, _trace=None, transform=True): ''' add a crosshair to the zoom frame canvas ''' trace = self.getCurrentTraceName() if _trace == None else _trace color = self.available[trace]['color'] ch = Crosshairs(self.app.Dicom.zframe, x, y, color, transform) if trace not in self.crosshairs: self.crosshairs[trace] = [] self.crosshairs[trace].append(ch) return ch def remove(self, ch, write=True): ''' remove a crosshair from the zoom frame canvas ... doesn't actually remove it but instead just makes it "invisible" ''' ch.undraw() if write: self.write() return ch def move(self): ''' called when window resizes to move to correct relative locations''' # trace = self.getCurrentTraceName() if self.crosshairs: for trace in self.crosshairs: for ch in self.crosshairs[trace]: truex, truey = ch.getTrueCoords() ch.x, ch.y = ch.transformTrueToCoords(truex, truey) ch.dragTo((ch.x, ch.y)) def read(self): ''' read a list of crosshair coordinates from the metadata file ''' frame = self.app.frame for trace in self.available: try: newCrosshairs = [] for item in self.app.Data.getTraceCurrentFrame(trace): ch = self.add(item['x'], item['y'], _trace=trace, transform=False) if trace not in self.crosshairs: self.crosshairs[trace] = [] self.crosshairs[trace].append(ch) newCrosshairs.append(ch) self.app.Control.push({'type': 'add', 'chs': newCrosshairs}) except KeyError: pass def write(self): ''' write out the coordinates of all of our crosshairs to the metadata file: ''' trace = self.getCurrentTraceName() traces = [] # prepare trace data in format for metadata array if trace in self.crosshairs: for ch in self.crosshairs[trace]: if ch.isVisible: x, y = ch.getTrueCoords() data = {'x': x, 'y': y} if data not in traces: # add trace to temporary array for including in metadata array traces.append(data) # add to metadata array and update file self.app.Data.setCurrentTraceCurrentFrame(traces) # update tier labels for number of annotated frames self.app.TextGrid.updateTierLabels() def getCurrentTraceName(self): ''' return string of current trace name ''' try: return self.listbox.get(self.listbox.curselection()) except Exception as e: # tkinter.TclError? error('Can\'t select from empty listbox!', e) def setDefaultTraceName(self): ''' wrapper for changing the default trace ''' self.app.Data.setTopLevel('defaultTraceName', self.getCurrentTraceName()) def select(self, ch): ''' select a crosshairs ''' ch.select() self.selected.add(ch) def selectAll(self): ''' select all crosshairs ''' if self.getCurrentTraceName() in self.crosshairs: for ch in self.crosshairs[self.getCurrentTraceName()]: self.select(ch) def unselect(self, ch): ''' unselect a crosshairs ''' ch.unselect() self.selected.remove(ch) def unselectAll(self): ''' unselect all crosshairs ''' for ch in self.selected: ch.unselect() self.selected = set() def getNearClickAllTraces(self, click): ''' takes a click object ( (x,y) tuple ) and returns a list of crosshairs within _CROSSHAIR_SELECT_RADIUS first searches for crosshairs matching the current trace iterates thru the other traces if it doesnt find anything if nothing is found for any trace, returns None ''' # get nearby crosshairs from this trace nearby = self.getNearClickOneTrace(click, self.getCurrentTraceName()) if nearby != None: return nearby # otherwise else: # ... check our other traces to see if they contain any nearby guys for trace in self.available: nearby = self.getNearClickOneTrace(click, trace) # if we got something if nearby != None: # switch to that trace and exit the loop for i, item in enumerate(self.listbox.get(0, 'end')): if item == trace: self.listbox.selection_clear(0, 'end') self.listbox.select_set(i) return nearby return None def getNearClickOneTrace(self, click, trace): ''' takes a click object and a trace and returns a list of crosshairs within util.CROSSHAIR_SELECT_RADIUS of that click ''' # see if we clicked near any existing crosshairs possibleSelections = {} if trace in self.crosshairs: for ch in self.crosshairs[trace]: d = ch.getDistance(click) if d < util.CROSSHAIR_SELECT_RADIUS: if d in possibleSelections: possibleSelections[d].append(ch) else: possibleSelections[d] = [ch] # if we did ... if possibleSelections != {}: # ... get the closest one ... dMin = sorted(possibleSelections.keys())[0] # ... in case of a tie, select a random one ch = random.choice(possibleSelections[dMin]) return ch return None def copy(self, event=None): ''' copies relative positions of selected crosshairs for pasting''' # debug('copy') self.copied = [] if len(self.selected) > 0: for ch in self.selected: self.copied.append(ch.getTrueCoords()) def paste(self, event=None): ''' pastes copied crosshairs and add them to undo/redo buffer ''' if len(self.copied) > 0: newChs = [] for xy in self.copied: ch = self.add(xy[0], xy[1], transform=False) newChs.append(ch) self.write() self.app.Control.push({'type': 'add', 'chs': newChs}) def recolor(self, event=None, trace=None, color=None): ''' change the color of a particular trace ''' trace = self.getCurrentTraceName() if trace == None else trace # grab a new color and save our old color (for generating Control data) newColor = self.getRandomHexColor() if color == None else color oldColor = self.app.Data.getCurrentTraceColor() self.available[trace]['color'] = newColor self.app.Data.setTraceColor(trace, newColor) if trace in self.crosshairs: for ch in self.crosshairs[trace]: ch.recolor(newColor) if trace == None or color == None: self.app.Control.push({ 'type': 'recolor', 'trace': self.getCurrentTraceName(), 'color': oldColor }) self.redoQueue = [] # FIXME: get this to update the widget self.app.Trace.displayedColour = newColor # FIXME: also get the widget to update the colour! return oldColor def clear(self): ''' remove all crosshairs for the current trace ''' # now we remove all the traces and save deleted = [] trace = self.getCurrentTraceName() if trace in self.crosshairs: for ch in self.crosshairs[trace]: if ch.isVisible: deleted.append(ch) self.remove(ch, write=False) self.write() self.app.Control.push({'type': 'delete', 'chs': deleted}) def newTrace(self): ''' add a new trace to our listbox ''' # max length 12 chars (so it displays nicely) name = self.traceSV.get()[:12] # don't want to add traces we already have or empty strings if name not in self.available and len(name) > 0: # choose a random color color = self.getRandomHexColor() # save the new trace name and color to metadata & update vars self.available[name] = {'color': color, 'files': {}} self.app.Data.setTopLevel('traces', self.available) self.traceSV.set('') # update our listbox self.listbox.insert('end', name) self.listbox.selection_clear(0, 'end') self.listbox.select_set(len(self.available) - 1) def renameTrace(self, oldName=None, newName=None): ''' change a trace name from oldName -> newName ''' fromUndo = (oldName != None or newName != None) oldName = self.getCurrentTraceName() if oldName == None else oldName newName = self.traceSV.get()[:12] if newName == None else newName # don't overwrite anything if newName not in self.available and len(newName) > 0: # get data from the old name and change the dictionary key in the metadata data = self.available.pop(oldName) self.available[newName] = data self.app.Data.setTopLevel('traces', self.available) if oldName == self.app.Data.getTopLevel('defaultTraceName'): self.app.Data.setTopLevel('defaultTraceName', newName) self.traceSV.set('') # update our listbox index = self.listbox.curselection() self.listbox.delete(index) self.listbox.insert(index, newName) self.listbox.selection_clear(0, 'end') self.listbox.select_set(index) if not (fromUndo): self.app.Control.push({ 'type': 'rename', 'old': oldName, 'new': newName }) def getRandomHexColor(self): ''' helper for getting a random color ''' return '#%06x' % random.randint(0, 0xFFFFFF) def getWidget(self, widget, row=0, column=0, rowspan=1, columnspan=1, sticky=()): ''' helper for managing all of our widgets ''' return { 'widget': widget, 'row': row, 'rowspan': rowspan, 'column': column, 'columnspan': columnspan, 'sticky': sticky } def grid(self): ''' grid all of our widgets ''' for item in self.TkWidgets: item['widget'].grid(row=item['row'], column=item['column'], rowspan=item['rowspan'], columnspan=item['columnspan'], sticky=item['sticky']) self.listbox.pack(side='left', fill='y') self.scrollbar.pack(side='right', fill='y') def grid_remove(self): ''' remove all of our widgets from the grid ''' for item in self.TkWidgets: item['widget'].grid_remove() self.listbox.packforget() self.scrollbar.packforget()
for i in range(26): xcoord +=20 b = HoverButton(frame4, width = 2, height=1, padx=0, pady=0, text = "%s" % (letters[i]), command=lambda i=i: filter_std_alpha(letters[i])) if i <= 12: b.place(x=xcoord, y=ycoord) else: b.place(x=xcoord-260, y=ycoord+25) buttons.append(b) stdCanvas = Canvas(frame4, bg='green', width=340, height=900) stdCanvas.place(x=10,y=190) stdScrollbar = Scrollbar(stdCanvas, orient="vertical") stdScrollbar.pack(side="right", fill="y") stdListBox = Listbox(stdCanvas, width=45, height=50, background = "black", foreground="white", font = ('Consolas', 10, 'bold')) stdListBox.pack() stdListBox.insert(tk.END, "LIST OF STANDARDIZED WORDS..") stdListBox.configure(yscrollcommand=stdScrollbar.set) stdScrollbar.config(command=stdListBox.yview) #bind event to std listbox so words show in frame 5 stdListBox.bind('<<ListboxSelect>>', onselect) #FRAME 5 backSearchBtn = HoverButton(frame5, text="Search", command=back_search, padx=2, pady=2) backSearchInput = Entry(frame5, width=36, justify = "left", font=('Consolas', 10, 'bold')) backSearchBtn.place(x=10, y=25) backSearchInput.place(x=80, y=25)
class MyApp(Frame): def __init__(self): self.root = Tk() Frame.__init__(self, self.root) # high level GUI configuration self.root.geometry('800x600') self.root.resizable(width=1, height=1) self.root.option_add('*tearOff', False) # keeps file menus from looking weird # members related to the background thread and operator instance self.long_thread = None self.background_operator = None # tk variables we can access later self.label_string = StringVar() self.build_dir_1_var = StringVar() self.build_dir_2_var = StringVar() self.run_period_option = StringVar() self.run_period_option.set(RunOptions.DONT_FORCE) self.reporting_frequency = StringVar() self.reporting_frequency.set(ReportingFrequency.HOURLY) # widgets that we might want to access later self.build_dir_1_button = None self.build_dir_2_button = None self.run_button = None self.stop_button = None self.build_dir_1_label = None self.build_dir_1_var.set('/eplus/repos/1eplus/builds') # "<Select build dir 1>") self.build_dir_2_label = None self.build_dir_2_var.set('/eplus/repos/1eplus/builds') # "<Select build dir 2>") self.progress = None self.log_message_listbox = None self.results_tree = None self.num_threads_spinner = None self.full_idf_listbox = None self.move_idf_to_active_button = None self.active_idf_listbox = None self.remove_idf_from_active_button = None self.idf_select_all_button = None self.idf_deselect_all_button = None self.idf_select_n_random_button = None self.run_period_option_menu = None self.reporting_frequency_option_menu = None # some data holders self.tree_folders = dict() self.valid_idfs_in_listing = False self.run_button_color = '#008000' # initialize the GUI self.init_window() # wire up the background thread pub.subscribe(self.status_handler, PubSubMessageTypes.STATUS) pub.subscribe(self.finished_handler, PubSubMessageTypes.FINISHED) pub.subscribe(self.cancelled_handler, PubSubMessageTypes.CANCELLED) def init_window(self): # changing the title of our master widget self.root.title("EnergyPlus Regression Tool 2") self.root.protocol("WM_DELETE_WINDOW", self.client_exit) # create the menu menu = Menu(self.root) self.root.config(menu=menu) file_menu = Menu(menu) file_menu.add_command(label="Exit", command=self.client_exit) menu.add_cascade(label="File", menu=file_menu) # main notebook holding everything main_notebook = ttk.Notebook(self.root) # run configuration pane_run = Frame(main_notebook) group_build_dir_1 = LabelFrame(pane_run, text="Build Directory 1") group_build_dir_1.pack(fill=X, padx=5) self.build_dir_1_button = Button(group_build_dir_1, text="Change...", command=self.client_build_dir_1) self.build_dir_1_button.grid(row=1, column=1, sticky=W) self.build_dir_1_label = Label(group_build_dir_1, textvariable=self.build_dir_1_var) self.build_dir_1_label.grid(row=1, column=2, sticky=E) group_build_dir_2 = LabelFrame(pane_run, text="Build Directory 2") group_build_dir_2.pack(fill=X, padx=5) self.build_dir_2_button = Button(group_build_dir_2, text="Change...", command=self.client_build_dir_2) self.build_dir_2_button.grid(row=1, column=1, sticky=W) self.build_dir_2_label = Label(group_build_dir_2, textvariable=self.build_dir_2_var) self.build_dir_2_label.grid(row=1, column=2, sticky=E) group_run_options = LabelFrame(pane_run, text="Run Options") group_run_options.pack(fill=X, padx=5) Label(group_run_options, text="Number of threads for suite: ").grid(row=1, column=1, sticky=E) self.num_threads_spinner = Spinbox(group_run_options, from_=1, to_=48) # validate later self.num_threads_spinner.grid(row=1, column=2, sticky=W) Label(group_run_options, text="Test suite run configuration: ").grid(row=2, column=1, sticky=E) self.run_period_option_menu = OptionMenu(group_run_options, self.run_period_option, *RunOptions.get_all()) self.run_period_option_menu.grid(row=2, column=2, sticky=W) Label(group_run_options, text="Minimum reporting frequency: ").grid(row=3, column=1, sticky=E) self.reporting_frequency_option_menu = OptionMenu( group_run_options, self.reporting_frequency, *ReportingFrequency.get_all() ) self.reporting_frequency_option_menu.grid(row=3, column=2, sticky=W) main_notebook.add(pane_run, text='Configuration') # now let's set up a list of checkboxes for selecting IDFs to run pane_idfs = Frame(main_notebook) group_idf_tools = LabelFrame(pane_idfs, text="IDF Selection Tools") group_idf_tools.pack(fill=X, padx=5) self.idf_select_all_button = Button( group_idf_tools, text="Refresh", command=self.client_idf_refresh ) self.idf_select_all_button.pack(side=LEFT, expand=1) self.idf_select_all_button = Button( group_idf_tools, text="Select All", command=self.idf_select_all ) self.idf_select_all_button.pack(side=LEFT, expand=1) self.idf_deselect_all_button = Button( group_idf_tools, text="Deselect All", command=self.idf_deselect_all ) self.idf_deselect_all_button.pack(side=LEFT, expand=1) self.idf_select_n_random_button = Button( group_idf_tools, text="Select N Random", command=self.idf_select_random ) self.idf_select_n_random_button.pack(side=LEFT, expand=1) group_full_idf_list = LabelFrame(pane_idfs, text="Full IDF List") group_full_idf_list.pack(fill=X, padx=5) scrollbar = Scrollbar(group_full_idf_list) self.full_idf_listbox = Listbox(group_full_idf_list, yscrollcommand=scrollbar.set) self.full_idf_listbox.bind('<Double-1>', self.idf_move_to_active) self.full_idf_listbox.pack(fill=BOTH, side=LEFT, expand=True) scrollbar.pack(fill=Y, side=LEFT) scrollbar.config(command=self.full_idf_listbox.yview) self.move_idf_to_active_button = Button( pane_idfs, text="↓ Add to Active List ↓", command=self.idf_move_to_active ) self.move_idf_to_active_button.pack(side=TOP, fill=X, expand=True) self.remove_idf_from_active_button = Button( pane_idfs, text="↑ Remove from Active List ↑", command=self.idf_remove_from_active ) self.remove_idf_from_active_button.pack(side=TOP, fill=X, expand=True) group_active_idf_list = LabelFrame(pane_idfs, text="Active IDF List") group_active_idf_list.pack(fill=X, padx=5) scrollbar = Scrollbar(group_active_idf_list) self.active_idf_listbox = Listbox(group_active_idf_list, yscrollcommand=scrollbar.set) self.active_idf_listbox.bind('<Double-1>', self.idf_remove_from_active) self.active_idf_listbox.pack(fill=BOTH, side=LEFT, expand=True) scrollbar.pack(fill=Y, side=LEFT) scrollbar.config(command=self.active_idf_listbox.yview) self.build_idf_listing(initialize=True) main_notebook.add(pane_idfs, text="IDF Selection") # set up a scrolled listbox for the log messages frame_log_messages = Frame(main_notebook) group_log_messages = LabelFrame(frame_log_messages, text="Log Message Tools") group_log_messages.pack(fill=X, padx=5) Button(group_log_messages, text="Clear Log Messages", command=self.clear_log).pack(side=LEFT, expand=1) Button(group_log_messages, text="Copy Log Messages", command=self.copy_log).pack(side=LEFT, expand=1) scrollbar = Scrollbar(frame_log_messages) self.log_message_listbox = Listbox(frame_log_messages, yscrollcommand=scrollbar.set) self.add_to_log("Program started!") self.log_message_listbox.pack(fill=BOTH, side=LEFT, expand=True) scrollbar.pack(fill=Y, side=LEFT) scrollbar.config(command=self.log_message_listbox.yview) main_notebook.add(frame_log_messages, text="Log Messages") # set up a tree-view for the results frame_results = Frame(main_notebook) scrollbar = Scrollbar(frame_results) self.results_tree = ttk.Treeview(frame_results, columns=("Base File", "Mod File", "Diff File")) self.results_tree.heading("#0", text="Results") self.results_tree.column('#0', minwidth=200, width=200) self.results_tree.heading("Base File", text="Base File") self.results_tree.column("Base File", minwidth=100, width=100) self.results_tree.heading("Mod File", text="Mod File") self.results_tree.column("Mod File", minwidth=100, width=100) self.results_tree.heading("Diff File", text="Diff File") self.results_tree.column("Diff File", minwidth=100, width=100) self.build_results_tree() self.results_tree.pack(fill=BOTH, side=LEFT, expand=True) scrollbar.pack(fill=Y, side=LEFT) scrollbar.config(command=self.results_tree.yview) main_notebook.add(frame_results, text="Run Control and Results") # pack the main notebook on the window main_notebook.pack(fill=BOTH, expand=1) # status bar at the bottom frame_status = Frame(self.root) self.run_button = Button(frame_status, text="Run", bg=self.run_button_color, command=self.client_run) self.run_button.pack(side=LEFT, expand=0) self.stop_button = Button(frame_status, text="Stop", command=self.client_stop, state='disabled') self.stop_button.pack(side=LEFT, expand=0) self.progress = ttk.Progressbar(frame_status) self.progress.pack(side=LEFT, expand=0) label = Label(frame_status, textvariable=self.label_string) self.label_string.set("Initialized") label.pack(side=LEFT, anchor=W) frame_status.pack(fill=X) def run(self): self.root.mainloop() def build_idf_listing(self, initialize=False, desired_selected_idfs=None): # clear any existing ones self.active_idf_listbox.delete(0, END) self.full_idf_listbox.delete(0, END) # now rebuild them self.valid_idfs_in_listing = False path_1 = Path(self.build_dir_1_var.get()) path_2 = Path(self.build_dir_2_var.get()) if path_1.exists() and path_2.exists(): idf_dir_1 = dummy_get_idf_dir(path_1) idfs_dir_1 = dummy_get_idfs_in_dir(idf_dir_1) idf_dir_2 = dummy_get_idf_dir(path_2) idfs_dir_2 = dummy_get_idfs_in_dir(idf_dir_2) common_idfs = idfs_dir_1.intersection(idfs_dir_2) for idf in sorted(common_idfs): self.full_idf_listbox.insert(END, str(idf)) self.valid_idfs_in_listing = True elif initialize: self.full_idf_listbox.insert(END, "This will be the master list") self.full_idf_listbox.insert(END, "Select build folders to fill listing") elif path_1.exists(): self.full_idf_listbox.insert(END, "Cannot update master list master list") self.full_idf_listbox.insert(END, "Build folder path #2 is invalid") self.full_idf_listbox.insert(END, "Select build folders to fill listing") elif path_2.exists(): self.full_idf_listbox.insert(END, "Cannot update master list master list") self.full_idf_listbox.insert(END, "Build folder path #1 is invalid") self.full_idf_listbox.insert(END, "Select build folders to fill listing") else: self.full_idf_listbox.insert(END, "Cannot update master list master list") self.full_idf_listbox.insert(END, "Both build folders are invalid") self.full_idf_listbox.insert(END, "Select build folders to fill listing") if desired_selected_idfs is None: ... # add things to the listbox def build_results_tree(self, results=None): self.results_tree.delete(*self.results_tree.get_children()) for root in ResultsTreeRoots.get_all(): self.tree_folders[root] = self.results_tree.insert( parent="", index='end', text=root, values=("", "", "") ) if results: self.results_tree.insert( parent=self.tree_folders[root], index="end", text="Pretend", values=("These", "Are", "Real") ) else: self.results_tree.insert( parent=self.tree_folders[root], index="end", text="Run test for results", values=("", "", "") ) def add_to_log(self, message): self.log_message_listbox.insert(END, f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]: {message}") def clear_log(self): self.log_message_listbox.delete(0, END) def copy_log(self): messages = self.log_message_listbox.get(0, END) message_string = '\n'.join(messages) self.root.clipboard_append(message_string) def client_idf_refresh(self): self.build_idf_listing() def idf_move_to_active(self, _): if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return current_selection = self.full_idf_listbox.curselection() if not current_selection: simpledialog.messagebox.showerror("IDF Selection Error", "No IDF Selected") return currently_selected_idf = self.full_idf_listbox.get(current_selection) try: self.active_idf_listbox.get(0, "end").index(currently_selected_idf) simpledialog.messagebox.showwarning("IDF Selection Warning", "IDF already exists in active list") return except ValueError: pass # the value error indicates it was _not_ found, so this is success self.active_idf_listbox.insert(END, currently_selected_idf) self.idf_refresh_count_status(currently_selected_idf, True) def idf_remove_from_active(self, event=None): if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return current_selection = self.active_idf_listbox.curselection() if not current_selection: if event: return simpledialog.messagebox.showerror("IDF Selection Error", "No IDF Selected") return self.active_idf_listbox.delete(current_selection) self.idf_refresh_count_status(current_selection, False) def idf_select_all(self): self.idf_deselect_all() if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return all_idfs = self.full_idf_listbox.get(0, END) for idf in all_idfs: self.active_idf_listbox.insert(END, idf) self.idf_refresh_count_status() def idf_deselect_all(self): if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return self.active_idf_listbox.delete(0, END) self.idf_refresh_count_status() def idf_select_random(self): if not self.valid_idfs_in_listing: simpledialog.messagebox.showerror("IDF Selection Error", "Invalid build folders or IDF list") return potential_number_to_select = simpledialog.askinteger("Input Amount", "How many would you like to select?") if not potential_number_to_select: return self.idf_deselect_all() number_to_select = int(potential_number_to_select) number_of_idf_files = self.full_idf_listbox.size() if number_of_idf_files <= number_to_select: # just take all of them self.idf_select_all() else: # down select randomly indices_to_take = random.sample(range(number_of_idf_files), number_to_select) idfs_to_take = list() for i in indices_to_take: idf_to_get = self.full_idf_listbox.get(i) idfs_to_take.append(idf_to_get) for idf_to_get in sorted(idfs_to_take): self.active_idf_listbox.insert(END, idf_to_get) self.idf_refresh_count_status() def idf_refresh_count_status(self, test_case=None, checked=False): if not self.valid_idfs_in_listing: return num_total = self.full_idf_listbox.size() num_active = self.active_idf_listbox.size() if test_case: chk_string = "Checked" if checked else "Unchecked" if checked: self.label_string.set(f"{chk_string} {test_case} ({num_active}/{num_total} selected)") else: self.label_string.set(f"{num_active}/{num_total} selected") def set_gui_status_for_run(self, is_running: bool): if is_running: run_button_state = 'disabled' stop_button_state = 'normal' else: run_button_state = 'normal' stop_button_state = 'disabled' self.build_dir_1_button.configure(state=run_button_state) self.build_dir_2_button.configure(state=run_button_state) self.run_button.configure(state=run_button_state) self.idf_select_all_button.configure(state=run_button_state) self.idf_deselect_all_button.configure(state=run_button_state) self.idf_select_n_random_button.configure(state=run_button_state) self.move_idf_to_active_button.configure(state=run_button_state) self.remove_idf_from_active_button.configure(state=run_button_state) self.run_period_option_menu.configure(state=run_button_state) self.reporting_frequency_option_menu.configure(state=run_button_state) self.num_threads_spinner.configure(state=run_button_state) self.stop_button.configure(state=stop_button_state) def client_build_dir_1(self): selected_dir = filedialog.askdirectory() if selected_dir: self.build_dir_1_var.set(selected_dir) self.build_idf_listing() def client_build_dir_2(self): selected_dir = filedialog.askdirectory() if selected_dir: self.build_dir_2_var.set(selected_dir) self.build_idf_listing() def client_run(self): if self.long_thread: messagebox.showerror("Cannot run another thread, wait for the current to finish -- how'd you get here?!?") return potential_num_threads = self.num_threads_spinner.get() try: num_threads = int(potential_num_threads) except ValueError: messagebox.showerror("Invalid Configuration", "Number of threads must be an integer") return idfs_to_run = list() for i in self.active_idf_listbox.get(0, END): idfs_to_run.append(i) self.background_operator = BackgroundOperation(num_threads, idfs_to_run) self.background_operator.get_ready_to_go( MyApp.status_listener, MyApp.finished_listener, MyApp.cancelled_listener ) self.set_gui_status_for_run(True) self.long_thread = Thread(target=self.background_operator.run) self.add_to_log("Starting a new set of tests") self.long_thread.start() def client_stop(self): self.add_to_log("Attempting to cancel") self.label_string.set("Attempting to cancel...") self.background_operator.please_stop() def client_exit(self): if self.long_thread: messagebox.showerror("Uh oh!", "Cannot exit program while operations are running; abort them then exit") return exit() def client_done(self): self.set_gui_status_for_run(False) self.long_thread = None # -- Callbacks from the background thread coming via PyPubSub @staticmethod def status_listener(status, object_completed, percent_complete): """Operates on background thread, just issues a pubsub message""" pub.sendMessage( PubSubMessageTypes.STATUS, status=status, object_completed=object_completed, percent_complete=percent_complete) def status_handler(self, status, object_completed, percent_complete): self.add_to_log(object_completed) self.progress['value'] = percent_complete self.label_string.set(f"Hey, status update: {str(status)}") @staticmethod def finished_listener(results_dict): """Operates on background thread, just issues a pubsub message""" pub.sendMessage(PubSubMessageTypes.FINISHED, results=results_dict) def finished_handler(self, results): self.add_to_log("All done, finished") self.label_string.set("Hey, all done!") self.build_results_tree(results) self.client_done() @staticmethod def cancelled_listener(): """Operates on background thread, just issues a pubsub message""" pub.sendMessage(PubSubMessageTypes.CANCELLED) def cancelled_handler(self): self.add_to_log("Cancelled!") self.label_string.set("Properly cancelled!") self.client_done()
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent, background="#8080FF") self.parent = parent self.initUI() def initUI(self): self.parent.title("EQ GuildViewer 0.1") fontb = Font(size=12, weight="bold") # inicializo variables self.ant = None self.lastLine = 0 self.name = "" # frame padre area = Frame(self) area.pack(side=BOTTOM, fill=BOTH, expand=1) areab = Frame(self) areab.pack(side=TOP, fill=BOTH, expand=1) # scroll players self.scrollbar2 = Scrollbar(areab, orient=VERTICAL) # construimos un menu con todos los nombres del diccionario y un boton self.refreshButton = Button(areab, text="""PARSEA!""", command=self.onRefresh, bd=2, relief="groove") self.listboxLogs = Listbox( areab, width=50, activestyle="none", highlightthickness=0, yscrollcommand=self.scrollbar2.set, relief=RIDGE ) self.listboxLogs.pack(side=LEFT, fill=Y) self.scrollbar2.pack(side=LEFT, fill=Y) self.refreshButton.pack(side=LEFT, fill=BOTH, expand=1) for player in optionsDictionary: self.listboxLogs.insert(END, player) # scroll self.scrollbar = Scrollbar(area, orient=VERTICAL) self.scrollbar.pack(side=RIGHT, fill=Y) # area1 area1 = Frame(area) area1.pack(side=LEFT, fill=Y) lbl = Label(area1, text="Name") self.listbox = Listbox( area1, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl.pack(side=TOP) self.listbox.pack(side=BOTTOM, fill=Y, expand=1) # area2 area2 = Frame(area) area2.pack(side=LEFT, fill=Y) lbl2 = Label(area2, text="Level") self.listbox2 = Listbox( area2, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl2.pack(side=TOP) self.listbox2.pack(side=BOTTOM, fill=Y, expand=1) # area3 area3 = Frame(area) area3.pack(side=LEFT, fill=Y) lbl3 = Label(area3, text="Class") self.listbox3 = Listbox( area3, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl3.pack(side=TOP) self.listbox3.pack(side=BOTTOM, fill=Y, expand=1) # area4 area4 = Frame(area) area4.pack(side=LEFT, fill=Y) lbl4 = Label(area4, text="Race") self.listbox4 = Listbox( area4, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl4.pack(side=TOP) self.listbox4.pack(side=BOTTOM, fill=Y, expand=1) # area3 area5 = Frame(area) area5.pack(side=LEFT, fill=Y) lbl5 = Label(area5, text="Zone") self.listbox5 = Listbox( area5, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl5.pack(side=TOP) self.listbox5.pack(side=BOTTOM, fill=Y, expand=1) self.pack(fill=BOTH, expand=1) # config-scrollbar self.scrollbar.config(command=self.yview) self.scrollbar2["command"] = self.listboxLogs.yview # bindeos de acciones self.listbox.bind("<<ListboxSelect>>", self.onSelect) self.listbox.bind("<MouseWheel>", self.onTest) self.listbox2.bind("<<ListboxSelect>>", self.onSelect) self.listbox2.bind("<MouseWheel>", self.onTest) self.listbox3.bind("<<ListboxSelect>>", self.onSelect) self.listbox3.bind("<MouseWheel>", self.onTest) self.listbox4.bind("<<ListboxSelect>>", self.onSelect) self.listbox4.bind("<MouseWheel>", self.onTest) self.listbox5.bind("<<ListboxSelect>>", self.onSelect) self.listbox5.bind("<MouseWheel>", self.onTest) self.listboxLogs.bind("<<ListboxSelect>>", self.onSelectPlayer) # mostrar la barra de scroll def yview(self, *args): self.listbox.yview(*args) self.listbox2.yview(*args) self.listbox3.yview(*args) self.listbox4.yview(*args) self.listbox5.yview(*args) # accion de la rueda del raton def onTest(self, val): return "break" # seleccionar un elementos de una listbox def onSelect(self, val): try: if self.ant != None: self.listbox.itemconfig(self.ant, background="#FFFFFF") self.listbox2.itemconfig(self.ant, background="#FFFFFF") self.listbox3.itemconfig(self.ant, background="#FFFFFF") self.listbox4.itemconfig(self.ant, background="#FFFFFF") self.listbox5.itemconfig(self.ant, background="#FFFFFF") self.listbox.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox2.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox3.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox4.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox5.itemconfig(val.widget.curselection(), background="#C0C0C0") self.ant = val.widget.curselection() except: None # print('No hay valores') # dependiendo de que nombre se elija en el menu cargamos en lastLine la linea de ese nombre del diccionario def onSelectPlayer(self, val): try: self.name = val.widget.get(val.widget.curselection()) self.lastLine = optionsDictionary[self.name] # print(self.name, ' ', self.lastLine) except: None # print('No hay valores') # recorremos el fichero log al clickar sobre el boton 'Refresh!' def onRefresh(self): if self.name != "": yes = False count = 0 dictionary = {} dictionaryAuxiliar = {} stringLog = "../eqlog_" + str(self.name) + "_project1999.txt" with open(stringLog, "r") as log: for i in range(int(self.lastLine)): next(log) count = count + 1 for line in log: match = re.match("\[.*\] \[(.*) (.*)\] (.*) \((.*)\) <.*> ZONE: (.*)", line) matchRole = re.match("\[.*\] \[(.*)\] (.*) <.*>", line) matchToken = re.match("\[.*\] You say, 't0000'", line) matchTokenI = re.match("\[.*\] You say, 't0001'", line) if matchTokenI != None: yes = True elif match != None and yes: dictionaryAuxiliar[match.group(3)] = ( match.group(1), match.group(2), match.group(4), match.group(5), ) elif matchRole != None and yes: dictionaryAuxiliar[matchRole.group(2)] = [(matchRole.group(1))] elif matchToken != None and yes: dictionary = dictionaryAuxiliar.copy() dictionaryAuxiliar.clear() yes = False count = count + 1 # bucle para sacar datos, primero eliminamos todo lo que haya self.listbox.delete(0, self.listbox.size()) self.listbox2.delete(0, self.listbox2.size()) self.listbox3.delete(0, self.listbox3.size()) self.listbox4.delete(0, self.listbox4.size()) self.listbox5.delete(0, self.listbox5.size()) for member in dictionary: self.listbox.insert(END, member) self.listbox2.insert(END, dictionary[member][0]) try: self.listbox3.insert(END, dictionary[member][1]) self.listbox4.insert(END, dictionary[member][2]) self.listbox5.insert(END, dictionary[member][3]) except IndexError as error: self.listbox3.insert(END, "-") self.listbox5.insert(END, "-") self.listbox4.insert(END, "-") # print(dictionary) # print('Longitud', len(dictionary)) # guardamos la linea ultima leida en el diccionario # self.lastLine = count # optionsDictionary[self.name] = count # print('Despues:', optionsDictionary) # guardamos el diccionario en el archivo options options = open("options.txt", "w") for player in optionsDictionary: options.write(str(player) + ":" + str(optionsDictionary[player])) options.close()
class RecursiveDescentApp(object): """ A graphical tool for exploring the recursive descent parser. The tool displays the parser's tree and the remaining text, and allows the user to control the parser's operation. In particular, the user can expand subtrees on the frontier, match tokens on the frontier against the text, and backtrack. A "step" button simply steps through the parsing process, performing the operations that ``RecursiveDescentParser`` would use. """ def __init__(self, grammar, sent, trace=0): self._sent = sent self._parser = SteppingRecursiveDescentParser(grammar, trace) # Set up the main window. self._top = Tk() self._top.title('Recursive Descent Parser Application') # Set up key bindings. self._init_bindings() # Initialize the fonts. self._init_fonts(self._top) # Animations. animating_lock is a lock to prevent the demo # from performing new operations while it's animating. self._animation_frames = IntVar(self._top) self._animation_frames.set(5) self._animating_lock = 0 self._autostep = 0 # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_feedback(self._top) self._init_grammar(self._top) self._init_canvas(self._top) # Initialize the parser. self._parser.initialize(self._sent) # Resize callback self._canvas.bind('<Configure>', self._configure) ######################################### ## Initialization Helpers ######################################### def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = tkinter.font.Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget('size')) self._boldfont = tkinter.font.Font(family='helvetica', weight='bold', size=self._size.get()) self._font = tkinter.font.Font(family='helvetica', size=self._size.get()) if self._size.get() < 0: big = self._size.get() - 2 else: big = self._size.get() + 2 self._bigfont = tkinter.font.Font(family='helvetica', weight='bold', size=big) def _init_grammar(self, parent): # Grammar view. self._prodframe = listframe = Frame(parent) self._prodframe.pack(fill='both', side='left', padx=2) self._prodlist_label = Label(self._prodframe, font=self._boldfont, text='Available Expansions') self._prodlist_label.pack() self._prodlist = Listbox(self._prodframe, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._prodlist.pack(side='right', fill='both', expand=1) self._productions = list(self._parser.grammar().productions()) for production in self._productions: self._prodlist.insert('end', (' %s' % production)) self._prodlist.config(height=min(len(self._productions), 25)) # Add a scrollbar if there are more than 25 productions. if len(self._productions) > 25: listscroll = Scrollbar(self._prodframe, orient='vertical') self._prodlist.config(yscrollcommand=listscroll.set) listscroll.config(command=self._prodlist.yview) listscroll.pack(side='left', fill='y') # If they select a production, apply it. self._prodlist.bind('<<ListboxSelect>>', self._prodlist_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind('<Control-q>', self.destroy) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Escape>', self.destroy) self._top.bind('e', self.expand) #self._top.bind('<Alt-e>', self.expand) #self._top.bind('<Control-e>', self.expand) self._top.bind('m', self.match) self._top.bind('<Alt-m>', self.match) self._top.bind('<Control-m>', self.match) self._top.bind('b', self.backtrack) self._top.bind('<Alt-b>', self.backtrack) self._top.bind('<Control-b>', self.backtrack) self._top.bind('<Control-z>', self.backtrack) self._top.bind('<BackSpace>', self.backtrack) self._top.bind('a', self.autostep) #self._top.bind('<Control-a>', self.autostep) self._top.bind('<Control-space>', self.autostep) self._top.bind('<Control-c>', self.cancel_autostep) self._top.bind('<space>', self.step) self._top.bind('<Delete>', self.reset) self._top.bind('<Control-p>', self.postscript) #self._top.bind('<h>', self.help) #self._top.bind('<Alt-h>', self.help) self._top.bind('<Control-h>', self.help) self._top.bind('<F1>', self.help) #self._top.bind('<g>', self.toggle_grammar) #self._top.bind('<Alt-g>', self.toggle_grammar) #self._top.bind('<Control-g>', self.toggle_grammar) self._top.bind('<Control-g>', self.edit_grammar) self._top.bind('<Control-t>', self.edit_sentence) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill='none', side='bottom', padx=3, pady=2) Button( buttonframe, text='Step', background='#90c0d0', foreground='black', command=self.step, ).pack(side='left') Button( buttonframe, text='Autostep', background='#90c0d0', foreground='black', command=self.autostep, ).pack(side='left') Button(buttonframe, text='Expand', underline=0, background='#90f090', foreground='black', command=self.expand).pack(side='left') Button(buttonframe, text='Match', underline=0, background='#90f090', foreground='black', command=self.match).pack(side='left') Button(buttonframe, text='Backtrack', underline=0, background='#f0a0a0', foreground='black', command=self.backtrack).pack(side='left') # Replace autostep... # self._autostep_button = Button(buttonframe, text='Autostep', # underline=0, command=self.autostep) # self._autostep_button.pack(side='left') def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas['scrollregion'] = '%d %d %d %d' % (x1, y1, x2, y2) self._redraw() def _init_feedback(self, parent): self._feedbackframe = feedbackframe = Frame(parent) feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3) self._lastoper_label = Label(feedbackframe, text='Last Operation:', font=self._font) self._lastoper_label.pack(side='left') lastoperframe = Frame(feedbackframe, relief='sunken', border=1) lastoperframe.pack(fill='x', side='right', expand=1, padx=5) self._lastoper1 = Label(lastoperframe, foreground='#007070', background='#f0f0f0', font=self._font) self._lastoper2 = Label(lastoperframe, anchor='w', width=30, foreground='#004040', background='#f0f0f0', font=self._font) self._lastoper1.pack(side='left') self._lastoper2.pack(side='left', fill='x', expand=1) def _init_canvas(self, parent): self._cframe = CanvasFrame( parent, background='white', #width=525, height=250, closeenough=10, border=2, relief='sunken') self._cframe.pack(expand=1, fill='both', side='top', pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Reset Parser', underline=0, command=self.reset, accelerator='Del') filemenu.add_command(label='Print to Postscript', underline=0, command=self.postscript, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label='Edit Grammar', underline=5, command=self.edit_grammar, accelerator='Ctrl-g') editmenu.add_command(label='Edit Text', underline=5, command=self.edit_sentence, accelerator='Ctrl-t') menubar.add_cascade(label='Edit', underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label='Step', underline=1, command=self.step, accelerator='Space') rulemenu.add_separator() rulemenu.add_command(label='Match', underline=0, command=self.match, accelerator='Ctrl-m') rulemenu.add_command(label='Expand', underline=0, command=self.expand, accelerator='Ctrl-e') rulemenu.add_separator() rulemenu.add_command(label='Backtrack', underline=0, command=self.backtrack, accelerator='Ctrl-b') menubar.add_cascade(label='Apply', underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton(label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar) viewmenu.add_separator() viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animation_frames, value=0) animatemenu.add_radiobutton(label="Slow Animation", underline=0, variable=self._animation_frames, value=10, accelerator='-') animatemenu.add_radiobutton(label="Normal Animation", underline=0, variable=self._animation_frames, value=5, accelerator='=') animatemenu.add_radiobutton(label="Fast Animation", underline=0, variable=self._animation_frames, value=2, accelerator='+') menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) helpmenu.add_command(label='Instructions', underline=0, command=self.help, accelerator='F1') menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Helper ######################################### def _get(self, widget, treeloc): for i in treeloc: widget = widget.subtrees()[i] if isinstance(widget, TreeSegmentWidget): widget = widget.label() return widget ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old tree, widgets, etc. if self._tree is not None: self._cframe.destroy_widget(self._tree) for twidget in self._textwidgets: self._cframe.destroy_widget(twidget) if self._textline is not None: self._canvas.delete(self._textline) # Draw the tree. helv = ('helvetica', -self._size.get()) bold = ('helvetica', -self._size.get(), 'bold') attribs = { 'tree_color': '#000000', 'tree_width': 2, 'node_font': bold, 'leaf_font': helv, } tree = self._parser.tree() self._tree = tree_to_treesegment(canvas, tree, **attribs) self._cframe.add_widget(self._tree, 30, 5) # Draw the text. helv = ('helvetica', -self._size.get()) bottom = y = self._cframe.scrollregion()[3] self._textwidgets = [ TextWidget(canvas, word, font=self._font) for word in self._sent ] for twidget in self._textwidgets: self._cframe.add_widget(twidget, 0, 0) twidget.move(0, bottom - twidget.bbox()[3] - 5) y = min(y, twidget.bbox()[1]) # Draw a line over the text, to separate it from the tree. self._textline = canvas.create_line(-5000, y - 5, 5000, y - 5, dash='.') # Highlight appropriate nodes. self._highlight_nodes() self._highlight_prodlist() # Make sure the text lines up. self._position_text() def _redraw_quick(self): # This should be more-or-less sufficient after an animation. self._highlight_nodes() self._highlight_prodlist() self._position_text() def _highlight_nodes(self): # Highlight the list of nodes to be checked. bold = ('helvetica', -self._size.get(), 'bold') for treeloc in self._parser.frontier()[:1]: self._get(self._tree, treeloc)['color'] = '#20a050' self._get(self._tree, treeloc)['font'] = bold for treeloc in self._parser.frontier()[1:]: self._get(self._tree, treeloc)['color'] = '#008080' def _highlight_prodlist(self): # Highlight the productions that can be expanded. # Boy, too bad tkinter doesn't implement Listbox.itemconfig; # that would be pretty useful here. self._prodlist.delete(0, 'end') expandable = self._parser.expandable_productions() untried = self._parser.untried_expandable_productions() productions = self._productions for index in range(len(productions)): if productions[index] in expandable: if productions[index] in untried: self._prodlist.insert(index, ' %s' % productions[index]) else: self._prodlist.insert(index, ' %s (TRIED)' % productions[index]) self._prodlist.selection_set(index) else: self._prodlist.insert(index, ' %s' % productions[index]) def _position_text(self): # Line up the text widgets that are matched against the tree numwords = len(self._sent) num_matched = numwords - len(self._parser.remaining_text()) leaves = self._tree_leaves()[:num_matched] xmax = self._tree.bbox()[0] for i in range(0, len(leaves)): widget = self._textwidgets[i] leaf = leaves[i] widget['color'] = '#006040' leaf['color'] = '#006040' widget.move(leaf.bbox()[0] - widget.bbox()[0], 0) xmax = widget.bbox()[2] + 10 # Line up the text widgets that are not matched against the tree. for i in range(len(leaves), numwords): widget = self._textwidgets[i] widget['color'] = '#a0a0a0' widget.move(xmax - widget.bbox()[0], 0) xmax = widget.bbox()[2] + 10 # If we have a complete parse, make everything green :) if self._parser.currently_complete(): for twidget in self._textwidgets: twidget['color'] = '#00a000' # Move the matched leaves down to the text. for i in range(0, len(leaves)): widget = self._textwidgets[i] leaf = leaves[i] dy = widget.bbox()[1] - leaf.bbox()[3] - 10.0 dy = max(dy, leaf.parent().label().bbox()[3] - leaf.bbox()[3] + 10) leaf.move(0, dy) def _tree_leaves(self, tree=None): if tree is None: tree = self._tree if isinstance(tree, TreeSegmentWidget): leaves = [] for child in tree.subtrees(): leaves += self._tree_leaves(child) return leaves else: return [tree] ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def reset(self, *e): self._autostep = 0 self._parser.initialize(self._sent) self._lastoper1['text'] = 'Reset Application' self._lastoper2['text'] = '' self._redraw() def autostep(self, *e): if self._animation_frames.get() == 0: self._animation_frames.set(2) if self._autostep: self._autostep = 0 else: self._autostep = 1 self._step() def cancel_autostep(self, *e): #self._autostep_button['text'] = 'Autostep' self._autostep = 0 # Make sure to stop auto-stepping if we get any user input. def step(self, *e): self._autostep = 0 self._step() def match(self, *e): self._autostep = 0 self._match() def expand(self, *e): self._autostep = 0 self._expand() def backtrack(self, *e): self._autostep = 0 self._backtrack() def _step(self): if self._animating_lock: return # Try expanding, matching, and backtracking (in that order) if self._expand(): pass elif self._parser.untried_match() and self._match(): pass elif self._backtrack(): pass else: self._lastoper1['text'] = 'Finished' self._lastoper2['text'] = '' self._autostep = 0 # Check if we just completed a parse. if self._parser.currently_complete(): self._autostep = 0 self._lastoper2['text'] += ' [COMPLETE PARSE]' def _expand(self, *e): if self._animating_lock: return old_frontier = self._parser.frontier() rv = self._parser.expand() if rv is not None: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = rv self._prodlist.selection_clear(0, 'end') index = self._productions.index(rv) self._prodlist.selection_set(index) self._animate_expand(old_frontier[0]) return True else: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = '(all expansions tried)' return False def _match(self, *e): if self._animating_lock: return old_frontier = self._parser.frontier() rv = self._parser.match() if rv is not None: self._lastoper1['text'] = 'Match:' self._lastoper2['text'] = rv self._animate_match(old_frontier[0]) return True else: self._lastoper1['text'] = 'Match:' self._lastoper2['text'] = '(failed)' return False def _backtrack(self, *e): if self._animating_lock: return if self._parser.backtrack(): elt = self._parser.tree() for i in self._parser.frontier()[0]: elt = elt[i] self._lastoper1['text'] = 'Backtrack' self._lastoper2['text'] = '' if isinstance(elt, Tree): self._animate_backtrack(self._parser.frontier()[0]) else: self._animate_match_backtrack(self._parser.frontier()[0]) return True else: self._autostep = 0 self._lastoper1['text'] = 'Finished' self._lastoper2['text'] = '' return False def about(self, *e): ABOUT = ("NLTK Recursive Descent Parser Application\n" + "Written by Edward Loper") TITLE = 'About: Recursive Descent Parser Application' try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def help(self, *e): self._autostep = 0 # The default font's not very legible; try using 'fixed' instead. try: ShowText(self._top, 'Help: Recursive Descent Parser Application', (__doc__ or '').strip(), width=75, font='fixed') except: ShowText(self._top, 'Help: Recursive Descent Parser Application', (__doc__ or '').strip(), width=75) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size + 2))) self._redraw() ######################################### ## Expand Production Selection ######################################### def _toggle_grammar(self, *e): if self._show_grammar.get(): self._prodframe.pack(fill='both', side='left', padx=2, after=self._feedbackframe) self._lastoper1['text'] = 'Show Grammar' else: self._prodframe.pack_forget() self._lastoper1['text'] = 'Hide Grammar' self._lastoper2['text'] = '' # def toggle_grammar(self, *e): # self._show_grammar = not self._show_grammar # if self._show_grammar: # self._prodframe.pack(fill='both', expand='y', side='left', # after=self._feedbackframe) # self._lastoper1['text'] = 'Show Grammar' # else: # self._prodframe.pack_forget() # self._lastoper1['text'] = 'Hide Grammar' # self._lastoper2['text'] = '' def _prodlist_select(self, event): selection = self._prodlist.curselection() if len(selection) != 1: return index = int(selection[0]) old_frontier = self._parser.frontier() production = self._parser.expand(self._productions[index]) if production: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = production self._prodlist.selection_clear(0, 'end') self._prodlist.selection_set(index) self._animate_expand(old_frontier[0]) else: # Reset the production selections. self._prodlist.selection_clear(0, 'end') for prod in self._parser.expandable_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) ######################################### ## Animation ######################################### def _animate_expand(self, treeloc): oldwidget = self._get(self._tree, treeloc) oldtree = oldwidget.parent() top = not isinstance(oldtree.parent(), TreeSegmentWidget) tree = self._parser.tree() for i in treeloc: tree = tree[i] widget = tree_to_treesegment(self._canvas, tree, node_font=self._boldfont, leaf_color='white', tree_width=2, tree_color='white', node_color='white', leaf_font=self._font) widget.label()['color'] = '#20a050' (oldx, oldy) = oldtree.label().bbox()[:2] (newx, newy) = widget.label().bbox()[:2] widget.move(oldx - newx, oldy - newy) if top: self._cframe.add_widget(widget, 0, 5) widget.move(30 - widget.label().bbox()[0], 0) self._tree = widget else: oldtree.parent().replace_child(oldtree, widget) # Move the children over so they don't overlap. # Line the children up in a strange way. if widget.subtrees(): dx = (oldx + widget.label().width() / 2 - widget.subtrees()[0].bbox()[0] / 2 - widget.subtrees()[0].bbox()[2] / 2) for subtree in widget.subtrees(): subtree.move(dx, 0) self._makeroom(widget) if top: self._cframe.destroy_widget(oldtree) else: oldtree.destroy() colors = [ 'gray%d' % (10 * int(10 * x / self._animation_frames.get())) for x in range(self._animation_frames.get(), 0, -1) ] # Move the text string down, if necessary. dy = widget.bbox()[3] + 30 - self._canvas.coords(self._textline)[1] if dy > 0: for twidget in self._textwidgets: twidget.move(0, dy) self._canvas.move(self._textline, 0, dy) self._animate_expand_frame(widget, colors) def _makeroom(self, treeseg): """ Make sure that no sibling tree bbox's overlap. """ parent = treeseg.parent() if not isinstance(parent, TreeSegmentWidget): return index = parent.subtrees().index(treeseg) # Handle siblings to the right rsiblings = parent.subtrees()[index + 1:] if rsiblings: dx = treeseg.bbox()[2] - rsiblings[0].bbox()[0] + 10 for sibling in rsiblings: sibling.move(dx, 0) # Handle siblings to the left if index > 0: lsibling = parent.subtrees()[index - 1] dx = max(0, lsibling.bbox()[2] - treeseg.bbox()[0] + 10) treeseg.move(dx, 0) # Keep working up the tree. self._makeroom(parent) def _animate_expand_frame(self, widget, colors): if len(colors) > 0: self._animating_lock = 1 widget['color'] = colors[0] for subtree in widget.subtrees(): if isinstance(subtree, TreeSegmentWidget): subtree.label()['color'] = colors[0] else: subtree['color'] = colors[0] self._top.after(50, self._animate_expand_frame, widget, colors[1:]) else: widget['color'] = 'black' for subtree in widget.subtrees(): if isinstance(subtree, TreeSegmentWidget): subtree.label()['color'] = 'black' else: subtree['color'] = 'black' self._redraw_quick() widget.label()['color'] = 'black' self._animating_lock = 0 if self._autostep: self._step() def _animate_backtrack(self, treeloc): # Flash red first, if we're animating. if self._animation_frames.get() == 0: colors = [] else: colors = ['#a00000', '#000000', '#a00000'] colors += [ 'gray%d' % (10 * int(10 * x / (self._animation_frames.get()))) for x in range(1, self._animation_frames.get() + 1) ] widgets = [self._get(self._tree, treeloc).parent()] for subtree in widgets[0].subtrees(): if isinstance(subtree, TreeSegmentWidget): widgets.append(subtree.label()) else: widgets.append(subtree) self._animate_backtrack_frame(widgets, colors) def _animate_backtrack_frame(self, widgets, colors): if len(colors) > 0: self._animating_lock = 1 for widget in widgets: widget['color'] = colors[0] self._top.after(50, self._animate_backtrack_frame, widgets, colors[1:]) else: for widget in widgets[0].subtrees(): widgets[0].remove_child(widget) widget.destroy() self._redraw_quick() self._animating_lock = 0 if self._autostep: self._step() def _animate_match_backtrack(self, treeloc): widget = self._get(self._tree, treeloc) node = widget.parent().label() dy = ((node.bbox()[3] - widget.bbox()[1] + 14) / max(1, self._animation_frames.get())) self._animate_match_backtrack_frame(self._animation_frames.get(), widget, dy) def _animate_match(self, treeloc): widget = self._get(self._tree, treeloc) dy = ((self._textwidgets[0].bbox()[1] - widget.bbox()[3] - 10.0) / max(1, self._animation_frames.get())) self._animate_match_frame(self._animation_frames.get(), widget, dy) def _animate_match_frame(self, frame, widget, dy): if frame > 0: self._animating_lock = 1 widget.move(0, dy) self._top.after(10, self._animate_match_frame, frame - 1, widget, dy) else: widget['color'] = '#006040' self._redraw_quick() self._animating_lock = 0 if self._autostep: self._step() def _animate_match_backtrack_frame(self, frame, widget, dy): if frame > 0: self._animating_lock = 1 widget.move(0, dy) self._top.after(10, self._animate_match_backtrack_frame, frame - 1, widget, dy) else: widget.parent().remove_child(widget) widget.destroy() self._animating_lock = 0 if self._autostep: self._step() def edit_grammar(self, *e): CFGEditor(self._top, self._parser.grammar(), self.set_grammar) def set_grammar(self, grammar): self._parser.set_grammar(grammar) self._productions = list(grammar.productions()) self._prodlist.delete(0, 'end') for production in self._productions: self._prodlist.insert('end', (' %s' % production)) def edit_sentence(self, *e): sentence = " ".join(self._sent) title = 'Edit Text' instr = 'Enter a new sentence to parse.' EntryDialog(self._top, sentence, instr, self.set_sentence, title) def set_sentence(self, sentence): self._sent = sentence.split() #[XX] use tagged? self.reset()
#scroll bar scroll_bar_4_my_listbox = Scrollbar(my_frame, orient=VERTICAL) scroll_bar_4_my_listbox.pack(side=RIGHT, fill=Y) #? y is to fill UP and DOWN all the way #? pack in on RIGHT hand side #Listbox #* SELECT MODE = SINGLE IS AT DEFAULT. <OTHER OPTIONS> BROWSE, MULTIPLE, EXTENDED my_listbox = Listbox( my_frame, width=50, bg="#353130", fg="white", yscrollcommand=scroll_bar_4_my_listbox.set, selectmode=EXTENDED) #?yscrollcommand -> is for horizontal scrollbar my_listbox.pack(pady=15) ## coz of my_listbox no defined so got to put it here scroll_bar_4_my_listbox.config(command=my_listbox.yview) # my_listbox.insert(0, "This is an item") #? 0 -> put it in the first one # #? END -> put it in the END my_listbox.insert(END, "This is an item") my_listbox.insert(END, "second item") my_list = [ "1", "2", "3", "4", "2", "3", "4", "2", "3", "4", "2", "3", "4", "2", "3", "4", "2", "3", "4", "2", "3", "4", "2", "3", "4" ]
class Window(Frame): # Inicialización def __init__(self, master): # Parametros para mi clase Frame Frame.__init__(self, master) # Referenciamos self.master = master # GUI Here self.init_window() def init_window(self): # Titulo de la ventana self.master.title("QA Tools") # Instanciamos un menu menu = Menu(self.master) # Referenciamos al widget self.master.config(menu=menu) # Agreamos submenus file = Menu(menu, tearoff=0) # Agregamos submenu Open file.add_command(label="Open", command=self.openFile) # Agregamos submenu exit file.add_command(label="Exit", command=self.client_exit) # menu File menu.add_cascade(label="File", menu=file) # Scrollbar self.scrollbar = Scrollbar(self.master, orient=VERTICAL) self.scrollbar.pack(side=RIGHT, fill=Y) # Lista self.lista = Listbox(self.master, font=("Helvetica", 8), borderwidth=0, activestyle=NONE, yscrollcommand=self.scrollbar.set) self.lista.pack(fill=BOTH, expand=1) self.scrollbar.config(command=self.lista.yview) # Funcion para cerrar la app def client_exit(self): self.master.destroy() # Funcion para abrir un doc def openFile(self): self.lista.delete(0, END) # obtenemos el archivo filepath = fdialog.askopenfilename(initialdir="C:/Users/%s" % user, filetypes=( ("SQL File", "*.sql"), ("All Files", "*.*")), title="Selección de Archivo") switchCommentOn = 'N' flagBlockBD = 'N' listBlockBD = [use, database] listBlockHeader = [if_, exists, from_, sysobjects, objectid_, and_, type_, drop, procedure] listBlockBody = [create, procedure] listBlockFoot = [grant, execute] listBlockMerge = [listBlockHeader,listBlockBody,listBlockFoot] dic = {} dicBlock = {} # dicParameters = {} dicBlockDescriptions = {} # listObjects = [] listConstants = [use, if_, exists, from_, sysobjects, objectid_, and_, type_, drop, procedure, create, grant, execute] listStatements = [usp] # listParameters = ['@'] listDescriptions = [datos, generales, parametros, control, version, historial, autor, fecha] listBlock = [] conjBlockBD = set(listBlockBD) conjBlockHeader = set(listBlockHeader) conjBlockBody = set(listBlockBody) conjBlockFoot = set(listBlockFoot) # listBlockParameters = [] listBlockDescriptions = [] try: # con el nombre del archivo with open(filepath) as fp: # obtenemos la primera linea line = fp.readline() cnt = 1 # mientras exista una linea while line: # damos formato estandar a la linea reemplazando )([].' por un espacio line = line.lower().replace(')', ' ').replace('(', ' ').replace('[', ' ').replace( ']', ' ').replace('.', ' ').replace("'", ' ').replace("\n", ' ').replace("\t", ' ') strippedLine = line.strip() if strippedLine == "": line = fp.readline() cnt += 1 continue if strippedLine == go: conjBlock = set(listBlock) if conjBlock == conjBlockBD: flagBlockBD = 'S' print(conjBlock) elif conjBlockHeader.issubset(conjBlock): print(conjBlock) elif conjBlockBody.issubset(conjBlock): print(conjBlock) elif conjBlockFoot.issubset(conjBlock): print(conjBlock) #print (listBlockDescriptions) listBlock.clear() # limpiamos la lista por bloque #listBlockParameters.clear() #listBlockDescriptions.clear() else: indexBlockComentOpen = line.find(blockCommentOpen, beg) if indexBlockComentOpen >= 0 or switchCommentOn == 'S': indexBlockComentClose = line.find(blockCommentClose, beg) if indexBlockComentClose >= 0: switchCommentOn = 'N' else: for const in listDescriptions: startPosition = line.find(const, beg) while startPosition >= 0: endPosition = line.find(space, startPosition) object_ = line[startPosition: endPosition] if object_ in listDescriptions: # listObjects.append(object_) if object_ in listBlockDescriptions: dicBlockDescriptions[object_] += 1 else: dicBlockDescriptions[object_] = 1 listBlockDescriptions.append(object_) startPosition = line.find(const, endPosition + 1) switchCommentOn = 'S' if flagBlockBD == 'N': for const in listBlockBD: startPosition = line.find(const, beg) while startPosition >= 0: endPosition = line.find(space, startPosition) object_ = line[startPosition: endPosition] if object_ in listBlockBD: # listObjects.append(object_) if object_ in listBlock: dicBlock[object_] += 1 else: dicBlock[object_] = 1 listBlock.append(object_) startPosition = line.find(const, endPosition + 1) line = fp.readline() continue for target in listBlockMerge: listFusion = target + listStatements for const in listFusion: startPosition = line.find(const, beg) while startPosition >= 0: endPosition = line.find(space, startPosition) object_ = line[startPosition: endPosition] if object_ in target or const in listStatements: if object_ in listBlock: dicBlock[object_] += 1 else: dicBlock[object_] = 1 listBlock.append(object_) startPosition = line.find(const, endPosition + 1) # for par in listParameters: # startPosition = line.find(par) # while startPosition >= 0: # endPosition = line.find(space, startPosition) # object_ = line[startPosition: endPosition] # # listObjects.append(object_) # if object_ in listBlockParameters: # dicParameters[object_] += 1 # else: # dicParameters[object_] = 1 # listBlockParameters.append(object_) # # startPosition = line.find(par, endPosition + 1) # siguiente linea line = fp.readline() cnt += 1 except OSError as e: if e.errno == errno.ENOENT: messagebox.showwarning("Warning", "File not found / File not selected")
uzrasas1 = Label(top_frame, text="Įveskite asmenį", width=40) laukas1 = Entry(top_frame) laukas1_uzr = Label(top_frame, text="Vardas") laukas2 = Entry(top_frame) laukas2_uzr = Label(top_frame, text="Pavardė") laukas3 = Entry(top_frame) laukas3_uzr = Label(top_frame, text="Amžius") mygtukas1 = Button(top_frame, text="Įvesti") mygtukas1.bind("<Button-1>", ui_add) laukas1.bind("<Return>", ui_add) laukas2.bind("<Return>", ui_add) laukas3.bind("<Return>", ui_add) mygtukas2 = Button(top_frame, text="Redaguoti", command=ui_edit) mygtukas3 = Button(top_frame, text="Ištrinti", command=ui_delete) # Graphic Objects visualization uzrasas1.grid(row=0, columnspan=2) laukas1_uzr.grid(row=1, column=0) laukas1.grid(row=1, column=1) laukas2_uzr.grid(row=2, column=0) laukas2.grid(row=2, column=1) laukas3_uzr.grid(row=3, column=0) laukas3.grid(row=3, column=1) mygtukas1.grid(row=4, columnspan=2, sticky="E") mygtukas2.grid(row=4, columnspan=2) mygtukas3.grid(row=4, columnspan=2, sticky="W") boksas.pack() top_frame.pack() button_frame.pack() main_window.mainloop()
list2[bb_[nn][0]].coords(can, x, y, N2.x, N2.y) else: list2[bb_[nn][0]].coords(can, N1.x, N1.y, x, y) itr += 1 root = Tk() root.geometry("900x700") root.title("Distribution") can = Canvas(root, width=w, height=h, bg='grey') can.pack(side=RIGHT) list1 = Listbox(root) list1.select_set(0) list1.pack() list2 = [] #line list list3 = [] #source list list4 = [] #recepteur list list5 = [] #point de rencontre list6 = [] #resultat b3 = Button(root, text="new source") b3.pack() b4 = Button(root, text="new recever") b4.pack() b5 = Button(root, text="new line") #b5.pack() b52 = Button(root, text="new line 2") b52.pack()
class ShiftReduceApp(object): """ A graphical tool for exploring the shift-reduce parser. The tool displays the parser's stack and the remaining text, and allows the user to control the parser's operation. In particular, the user can shift tokens onto the stack, and can perform reductions on the top elements of the stack. A "step" button simply steps through the parsing process, performing the operations that ``nltk.parse.ShiftReduceParser`` would use. """ def __init__(self, grammar, sent, trace=0): self._sent = sent self._parser = SteppingShiftReduceParser(grammar, trace) # Set up the main window. self._top = Tk() self._top.title('Shift Reduce Parser Application') # Animations. animating_lock is a lock to prevent the demo # from performing new operations while it's animating. self._animating_lock = 0 self._animate = IntVar(self._top) self._animate.set(10) # = medium # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Initialize fonts. self._init_fonts(self._top) # Set up key bindings. self._init_bindings() # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_feedback(self._top) self._init_grammar(self._top) self._init_canvas(self._top) # A popup menu for reducing. self._reduce_menu = Menu(self._canvas, tearoff=0) # Reset the demo, and set the feedback frame to empty. self.reset() self._lastoper1['text'] = '' ######################################### ## Initialization Helpers ######################################### def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = tkinter.font.Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget('size')) self._boldfont = tkinter.font.Font(family='helvetica', weight='bold', size=self._size.get()) self._font = tkinter.font.Font(family='helvetica', size=self._size.get()) def _init_grammar(self, parent): # Grammar view. self._prodframe = listframe = Frame(parent) self._prodframe.pack(fill='both', side='left', padx=2) self._prodlist_label = Label(self._prodframe, font=self._boldfont, text='Available Reductions') self._prodlist_label.pack() self._prodlist = Listbox(self._prodframe, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._prodlist.pack(side='right', fill='both', expand=1) self._productions = list(self._parser.grammar().productions()) for production in self._productions: self._prodlist.insert('end', (' %s' % production)) self._prodlist.config(height=min(len(self._productions), 25)) # Add a scrollbar if there are more than 25 productions. if 1:#len(self._productions) > 25: listscroll = Scrollbar(self._prodframe, orient='vertical') self._prodlist.config(yscrollcommand = listscroll.set) listscroll.config(command=self._prodlist.yview) listscroll.pack(side='left', fill='y') # If they select a production, apply it. self._prodlist.bind('<<ListboxSelect>>', self._prodlist_select) # When they hover over a production, highlight it. self._hover = -1 self._prodlist.bind('<Motion>', self._highlight_hover) self._prodlist.bind('<Leave>', self._clear_hover) def _init_bindings(self): # Quit self._top.bind('<Control-q>', self.destroy) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Alt-q>', self.destroy) self._top.bind('<Alt-x>', self.destroy) # Ops (step, shift, reduce, undo) self._top.bind('<space>', self.step) self._top.bind('<s>', self.shift) self._top.bind('<Alt-s>', self.shift) self._top.bind('<Control-s>', self.shift) self._top.bind('<r>', self.reduce) self._top.bind('<Alt-r>', self.reduce) self._top.bind('<Control-r>', self.reduce) self._top.bind('<Delete>', self.reset) self._top.bind('<u>', self.undo) self._top.bind('<Alt-u>', self.undo) self._top.bind('<Control-u>', self.undo) self._top.bind('<Control-z>', self.undo) self._top.bind('<BackSpace>', self.undo) # Misc self._top.bind('<Control-p>', self.postscript) self._top.bind('<Control-h>', self.help) self._top.bind('<F1>', self.help) self._top.bind('<Control-g>', self.edit_grammar) self._top.bind('<Control-t>', self.edit_sentence) # Animation speed control self._top.bind('-', lambda e,a=self._animate:a.set(20)) self._top.bind('=', lambda e,a=self._animate:a.set(10)) self._top.bind('+', lambda e,a=self._animate:a.set(4)) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill='none', side='bottom') Button(buttonframe, text='Step', background='#90c0d0', foreground='black', command=self.step,).pack(side='left') Button(buttonframe, text='Shift', underline=0, background='#90f090', foreground='black', command=self.shift).pack(side='left') Button(buttonframe, text='Reduce', underline=0, background='#90f090', foreground='black', command=self.reduce).pack(side='left') Button(buttonframe, text='Undo', underline=0, background='#f0a0a0', foreground='black', command=self.undo).pack(side='left') def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Reset Parser', underline=0, command=self.reset, accelerator='Del') filemenu.add_command(label='Print to Postscript', underline=0, command=self.postscript, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label='Edit Grammar', underline=5, command=self.edit_grammar, accelerator='Ctrl-g') editmenu.add_command(label='Edit Text', underline=5, command=self.edit_sentence, accelerator='Ctrl-t') menubar.add_cascade(label='Edit', underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label='Step', underline=1, command=self.step, accelerator='Space') rulemenu.add_separator() rulemenu.add_command(label='Shift', underline=0, command=self.shift, accelerator='Ctrl-s') rulemenu.add_command(label='Reduce', underline=0, command=self.reduce, accelerator='Ctrl-r') rulemenu.add_separator() rulemenu.add_command(label='Undo', underline=0, command=self.undo, accelerator='Ctrl-u') menubar.add_cascade(label='Apply', underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton(label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar) viewmenu.add_separator() viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animate, value=0) animatemenu.add_radiobutton(label="Slow Animation", underline=0, variable=self._animate, value=20, accelerator='-') animatemenu.add_radiobutton(label="Normal Animation", underline=0, variable=self._animate, value=10, accelerator='=') animatemenu.add_radiobutton(label="Fast Animation", underline=0, variable=self._animate, value=4, accelerator='+') menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) helpmenu.add_command(label='Instructions', underline=0, command=self.help, accelerator='F1') menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar) def _init_feedback(self, parent): self._feedbackframe = feedbackframe = Frame(parent) feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3) self._lastoper_label = Label(feedbackframe, text='Last Operation:', font=self._font) self._lastoper_label.pack(side='left') lastoperframe = Frame(feedbackframe, relief='sunken', border=1) lastoperframe.pack(fill='x', side='right', expand=1, padx=5) self._lastoper1 = Label(lastoperframe, foreground='#007070', background='#f0f0f0', font=self._font) self._lastoper2 = Label(lastoperframe, anchor='w', width=30, foreground='#004040', background='#f0f0f0', font=self._font) self._lastoper1.pack(side='left') self._lastoper2.pack(side='left', fill='x', expand=1) def _init_canvas(self, parent): self._cframe = CanvasFrame(parent, background='white', width=525, closeenough=10, border=2, relief='sunken') self._cframe.pack(expand=1, fill='both', side='top', pady=2) canvas = self._canvas = self._cframe.canvas() self._stackwidgets = [] self._rtextwidgets = [] self._titlebar = canvas.create_rectangle(0,0,0,0, fill='#c0f0f0', outline='black') self._exprline = canvas.create_line(0,0,0,0, dash='.') self._stacktop = canvas.create_line(0,0,0,0, fill='#408080') size = self._size.get()+4 self._stacklabel = TextWidget(canvas, 'Stack', color='#004040', font=self._boldfont) self._rtextlabel = TextWidget(canvas, 'Remaining Text', color='#004040', font=self._boldfont) self._cframe.add_widget(self._stacklabel) self._cframe.add_widget(self._rtextlabel) ######################################### ## Main draw procedure ######################################### def _redraw(self): scrollregion = self._canvas['scrollregion'].split() (cx1, cy1, cx2, cy2) = [int(c) for c in scrollregion] # Delete the old stack & rtext widgets. for stackwidget in self._stackwidgets: self._cframe.destroy_widget(stackwidget) self._stackwidgets = [] for rtextwidget in self._rtextwidgets: self._cframe.destroy_widget(rtextwidget) self._rtextwidgets = [] # Position the titlebar & exprline (x1, y1, x2, y2) = self._stacklabel.bbox() y = y2-y1+10 self._canvas.coords(self._titlebar, -5000, 0, 5000, y-4) self._canvas.coords(self._exprline, 0, y*2-10, 5000, y*2-10) # Position the titlebar labels.. (x1, y1, x2, y2) = self._stacklabel.bbox() self._stacklabel.move(5-x1, 3-y1) (x1, y1, x2, y2) = self._rtextlabel.bbox() self._rtextlabel.move(cx2-x2-5, 3-y1) # Draw the stack. stackx = 5 for tok in self._parser.stack(): if isinstance(tok, Tree): attribs = {'tree_color': '#4080a0', 'tree_width': 2, 'node_font': self._boldfont, 'node_color': '#006060', 'leaf_color': '#006060', 'leaf_font':self._font} widget = tree_to_treesegment(self._canvas, tok, **attribs) widget.label()['color'] = '#000000' else: widget = TextWidget(self._canvas, tok, color='#000000', font=self._font) widget.bind_click(self._popup_reduce) self._stackwidgets.append(widget) self._cframe.add_widget(widget, stackx, y) stackx = widget.bbox()[2] + 10 # Draw the remaining text. rtextwidth = 0 for tok in self._parser.remaining_text(): widget = TextWidget(self._canvas, tok, color='#000000', font=self._font) self._rtextwidgets.append(widget) self._cframe.add_widget(widget, rtextwidth, y) rtextwidth = widget.bbox()[2] + 4 # Allow enough room to shift the next token (for animations) if len(self._rtextwidgets) > 0: stackx += self._rtextwidgets[0].width() # Move the remaining text to the correct location (keep it # right-justified, when possible); and move the remaining text # label, if necessary. stackx = max(stackx, self._stacklabel.width()+25) rlabelwidth = self._rtextlabel.width()+10 if stackx >= cx2-max(rtextwidth, rlabelwidth): cx2 = stackx + max(rtextwidth, rlabelwidth) for rtextwidget in self._rtextwidgets: rtextwidget.move(4+cx2-rtextwidth, 0) self._rtextlabel.move(cx2-self._rtextlabel.bbox()[2]-5, 0) midx = (stackx + cx2-max(rtextwidth, rlabelwidth))/2 self._canvas.coords(self._stacktop, midx, 0, midx, 5000) (x1, y1, x2, y2) = self._stacklabel.bbox() # Set up binding to allow them to shift a token by dragging it. if len(self._rtextwidgets) > 0: def drag_shift(widget, midx=midx, self=self): if widget.bbox()[0] < midx: self.shift() else: self._redraw() self._rtextwidgets[0].bind_drag(drag_shift) self._rtextwidgets[0].bind_click(self.shift) # Draw the stack top. self._highlight_productions() def _draw_stack_top(self, widget): # hack.. midx = widget.bbox()[2]+50 self._canvas.coords(self._stacktop, midx, 0, midx, 5000) def _highlight_productions(self): # Highlight the productions that can be reduced. self._prodlist.selection_clear(0, 'end') for prod in self._parser.reducible_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) ######################################### ## Button Callbacks ######################################### def destroy(self, *e): if self._top is None: return self._top.destroy() self._top = None def reset(self, *e): self._parser.initialize(self._sent) self._lastoper1['text'] = 'Reset App' self._lastoper2['text'] = '' self._redraw() def step(self, *e): if self.reduce(): return True elif self.shift(): return True else: if list(self._parser.parses()): self._lastoper1['text'] = 'Finished:' self._lastoper2['text'] = 'Success' else: self._lastoper1['text'] = 'Finished:' self._lastoper2['text'] = 'Failure' def shift(self, *e): if self._animating_lock: return if self._parser.shift(): tok = self._parser.stack()[-1] self._lastoper1['text'] = 'Shift:' self._lastoper2['text'] = '%r' % tok if self._animate.get(): self._animate_shift() else: self._redraw() return True return False def reduce(self, *e): if self._animating_lock: return production = self._parser.reduce() if production: self._lastoper1['text'] = 'Reduce:' self._lastoper2['text'] = '%s' % production if self._animate.get(): self._animate_reduce() else: self._redraw() return production def undo(self, *e): if self._animating_lock: return if self._parser.undo(): self._redraw() def postscript(self, *e): self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) ######################################### ## Menubar callbacks ######################################### def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) #self._stacklabel['font'] = ('helvetica', -size-4, 'bold') #self._rtextlabel['font'] = ('helvetica', -size-4, 'bold') #self._lastoper_label['font'] = ('helvetica', -size) #self._lastoper1['font'] = ('helvetica', -size) #self._lastoper2['font'] = ('helvetica', -size) #self._prodlist['font'] = ('helvetica', -size) #self._prodlist_label['font'] = ('helvetica', -size-2, 'bold') self._redraw() def help(self, *e): # The default font's not very legible; try using 'fixed' instead. try: ShowText(self._top, 'Help: Shift-Reduce Parser Application', (__doc__ or '').strip(), width=75, font='fixed') except: ShowText(self._top, 'Help: Shift-Reduce Parser Application', (__doc__ or '').strip(), width=75) def about(self, *e): ABOUT = ("NLTK Shift-Reduce Parser Application\n"+ "Written by Edward Loper") TITLE = 'About: Shift-Reduce Parser Application' try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def edit_grammar(self, *e): CFGEditor(self._top, self._parser.grammar(), self.set_grammar) def set_grammar(self, grammar): self._parser.set_grammar(grammar) self._productions = list(grammar.productions()) self._prodlist.delete(0, 'end') for production in self._productions: self._prodlist.insert('end', (' %s' % production)) def edit_sentence(self, *e): sentence = " ".join(self._sent) title = 'Edit Text' instr = 'Enter a new sentence to parse.' EntryDialog(self._top, sentence, instr, self.set_sentence, title) def set_sentence(self, sent): self._sent = sent.split() #[XX] use tagged? self.reset() ######################################### ## Reduce Production Selection ######################################### def _toggle_grammar(self, *e): if self._show_grammar.get(): self._prodframe.pack(fill='both', side='left', padx=2, after=self._feedbackframe) self._lastoper1['text'] = 'Show Grammar' else: self._prodframe.pack_forget() self._lastoper1['text'] = 'Hide Grammar' self._lastoper2['text'] = '' def _prodlist_select(self, event): selection = self._prodlist.curselection() if len(selection) != 1: return index = int(selection[0]) production = self._parser.reduce(self._productions[index]) if production: self._lastoper1['text'] = 'Reduce:' self._lastoper2['text'] = '%s' % production if self._animate.get(): self._animate_reduce() else: self._redraw() else: # Reset the production selections. self._prodlist.selection_clear(0, 'end') for prod in self._parser.reducible_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) def _popup_reduce(self, widget): # Remove old commands. productions = self._parser.reducible_productions() if len(productions) == 0: return self._reduce_menu.delete(0, 'end') for production in productions: self._reduce_menu.add_command(label=str(production), command=self.reduce) self._reduce_menu.post(self._canvas.winfo_pointerx(), self._canvas.winfo_pointery()) ######################################### ## Animations ######################################### def _animate_shift(self): # What widget are we shifting? widget = self._rtextwidgets[0] # Where are we shifting from & to? right = widget.bbox()[0] if len(self._stackwidgets) == 0: left = 5 else: left = self._stackwidgets[-1].bbox()[2]+10 # Start animating. dt = self._animate.get() dx = (left-right)*1.0/dt self._animate_shift_frame(dt, widget, dx) def _animate_shift_frame(self, frame, widget, dx): if frame > 0: self._animating_lock = 1 widget.move(dx, 0) self._top.after(10, self._animate_shift_frame, frame-1, widget, dx) else: # but: stacktop?? # Shift the widget to the stack. del self._rtextwidgets[0] self._stackwidgets.append(widget) self._animating_lock = 0 # Display the available productions. self._draw_stack_top(widget) self._highlight_productions() def _animate_reduce(self): # What widgets are we shifting? numwidgets = len(self._parser.stack()[-1]) # number of children widgets = self._stackwidgets[-numwidgets:] # How far are we moving? if isinstance(widgets[0], TreeSegmentWidget): ydist = 15 + widgets[0].label().height() else: ydist = 15 + widgets[0].height() # Start animating. dt = self._animate.get() dy = ydist*2.0/dt self._animate_reduce_frame(dt/2, widgets, dy) def _animate_reduce_frame(self, frame, widgets, dy): if frame > 0: self._animating_lock = 1 for widget in widgets: widget.move(0, dy) self._top.after(10, self._animate_reduce_frame, frame-1, widgets, dy) else: del self._stackwidgets[-len(widgets):] for widget in widgets: self._cframe.remove_widget(widget) tok = self._parser.stack()[-1] if not isinstance(tok, Tree): raise ValueError() label = TextWidget(self._canvas, str(tok.label()), color='#006060', font=self._boldfont) widget = TreeSegmentWidget(self._canvas, label, widgets, width=2) (x1, y1, x2, y2) = self._stacklabel.bbox() y = y2-y1+10 if not self._stackwidgets: x = 5 else: x = self._stackwidgets[-1].bbox()[2] + 10 self._cframe.add_widget(widget, x, y) self._stackwidgets.append(widget) # Display the available productions. self._draw_stack_top(widget) self._highlight_productions() # # Delete the old widgets.. # del self._stackwidgets[-len(widgets):] # for widget in widgets: # self._cframe.destroy_widget(widget) # # # Make a new one. # tok = self._parser.stack()[-1] # if isinstance(tok, Tree): # attribs = {'tree_color': '#4080a0', 'tree_width': 2, # 'node_font': bold, 'node_color': '#006060', # 'leaf_color': '#006060', 'leaf_font':self._font} # widget = tree_to_treesegment(self._canvas, tok.type(), # **attribs) # widget.node()['color'] = '#000000' # else: # widget = TextWidget(self._canvas, tok.type(), # color='#000000', font=self._font) # widget.bind_click(self._popup_reduce) # (x1, y1, x2, y2) = self._stacklabel.bbox() # y = y2-y1+10 # if not self._stackwidgets: x = 5 # else: x = self._stackwidgets[-1].bbox()[2] + 10 # self._cframe.add_widget(widget, x, y) # self._stackwidgets.append(widget) #self._redraw() self._animating_lock = 0 ######################################### ## Hovering. ######################################### def _highlight_hover(self, event): # What production are we hovering over? index = self._prodlist.nearest(event.y) if self._hover == index: return # Clear any previous hover highlighting. self._clear_hover() # If the production corresponds to an available reduction, # highlight the stack. selection = [int(s) for s in self._prodlist.curselection()] if index in selection: rhslen = len(self._productions[index].rhs()) for stackwidget in self._stackwidgets[-rhslen:]: if isinstance(stackwidget, TreeSegmentWidget): stackwidget.label()['color'] = '#00a000' else: stackwidget['color'] = '#00a000' # Remember what production we're hovering over. self._hover = index def _clear_hover(self, *event): # Clear any previous hover highlighting. if self._hover == -1: return self._hover = -1 for stackwidget in self._stackwidgets: if isinstance(stackwidget, TreeSegmentWidget): stackwidget.label()['color'] = 'black' else: stackwidget['color'] = 'black'
class MyGui(ttk.Frame): controller = None tabs = None tabs_history = [] _log = None _screen_width = None _screen_height = None COLOR_buttons = '#FFCB6B' COLOR_frames = '#333333' COLOR_foreground = '#D9C7B3' COLOR_log = '#1E1E1E' def v_restoreSession(self): with open("saved_sessions/saved_tabs.pkl", "rb") as f: history = pickle.load(f) for i in history: self.open_file(i) def v_splashscreen(self, master, height, width): image_splash = "icons/logo-gif.gif" image = tk.PhotoImage(file=image_splash) canvas = tk.Canvas(master, height=height * 0.8, width=width) canvas.create_image(width * 0.8 / 2, height * 0.8 / 2, image=image) canvas.grid() master.after(5000, master.destroy) def __init__(self, master, controller): super().__init__() master.protocol("WM_DELETE_WINDOW", self.v_on_closing) self.controller = controller self.v_initUi(master) if os.path.isfile("saved_sessions/saved_tabs.pkl"): self.v_restoreSession() def v_on_closing(self): close = messagebox.askyesnocancel( title="Warning", message="Do you want to save the session?") if close == True: picklefile = open("saved_sessions/saved_tabs.pkl", "wb") pickle.dump(self.tabs_history, picklefile) picklefile.close() self.master.destroy() elif close == False: if os.path.isfile("saved_sessions/saved_tabs.pkl"): os.remove("saved_sessions/saved_tabs.pkl") self.master.destroy() def dos2unix(self, file_path): # replacement strings WINDOWS_LINE_ENDING = b'\r\n' UNIX_LINE_ENDING = b'\n' with open(file_path, 'rb') as open_file: content = open_file.read() content = content.replace(WINDOWS_LINE_ENDING, UNIX_LINE_ENDING) with open(file_path, 'wb') as open_file: open_file.write(content) def help_window(self): self.top = tk.Toplevel() self.top.title("Usage") label = tk.Label( self.top, text="Open: takes in input DOT files,but can also it can get:\n" + " - Chorgram file (.txt), a grammar used for Global Graph\n" + " - DOT files (.gv) generated by Domitilla and converte them into DOT files with CA sintax\n\n\n" + "Once taken one or more files as input, Corinne can apply some functions on it:\n\n" + " - Product: a cartesian product of two CA\n" + " - Synchronization: given a CA, it can synchronize two participants of its\n" + " - Projection: given a CA, you can select one participant from it and get the relative CFSM", justify=tk.LEFT, padx=15, pady=15).pack() def v_initUi(self, master): self.master.title("Corinne 2.0") self.master.grid_columnconfigure(0, weight=1) self.master.grid_rowconfigure(2, weight=1) self.master.option_add('*foreground', 'black') self.master.option_add('*background', 'white') # Style for ttk widgets style = ttk.Style() style.configure("TNotebook", background=self.COLOR_frames, borderwidth=1, highlightthickness=1) style.configure("TNotebook.Tab", background=self.COLOR_frames, foreground="black", lightcolor=self.COLOR_frames, borderwidth=0) style.map("TNotebook.Tab", background=[("selected", self.COLOR_buttons)], foreground=[("selected", 'black')]) style.configure("TFrame", background=self.COLOR_frames, foreground="black") # get screen resolution self._screen_width, self._screen_height = master.winfo_screenwidth( ), master.winfo_screenheight() start_x = int((self._screen_width / 4)) start_y = int((self._screen_height / 4)) # fit the guy at screen resolution master.geometry('%dx%d+%d+%d' % (self._screen_width / 2, self._screen_height / 2, start_x, start_y)) #self.v_splashscreen(master,start_x,start_y) #create all the containers menu_frame = Frame(master, padx=10, pady=10) menu_frame.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W)) menu_frame.configure(bg=self.COLOR_frames) menu_frame.grid_columnconfigure(0, weight=1) menu_frame.grid_columnconfigure(1, weight=1) tab_frame = Frame(master, pady=15) tab_frame.grid(row=1, column=0, sticky=(tk.N, tk.S, tk.E, tk.W)) tab_frame.configure(bg=self.COLOR_frames) tab_frame.grid_columnconfigure(0, weight=1) tab_frame.grid_rowconfigure(0, weight=1) log_frame = Frame(master) log_frame.grid(row=2, column=0, sticky=(tk.N, tk.S, tk.E, tk.W)) log_frame.configure(bg=self.COLOR_frames) log_frame.grid_columnconfigure(0, weight=1) prova = Image.open("icons/open.png") open_icon = ImageTk.PhotoImage(prova) render_icon = PhotoImage(file="icons/render.png") prod_icon = PhotoImage(file="icons/product.png") sync_icon = PhotoImage(file="icons/sync.png") proj_icon = PhotoImage(file="icons/projection.png") menu_bar = Menu(master) file_menu = Menu(menu_bar, tearoff=False) file_menu.add_command(label="Open", compound=tk.LEFT, command=lambda: self.open_file(None)) file_menu.add_command(label="Open Saved Tabs", command=self.v_restoreSession) menu_bar.add_cascade(label="File", menu=file_menu) trasformation_menu = Menu(menu_bar, tearoff=False) trasformation_menu.add_command(label="Product", compound=tk.LEFT, command=self.open_product_view) trasformation_menu.add_command(label="Sync", compound=tk.LEFT, command=self.open_sync_view) trasformation_menu.add_command(label="Projection", compound=tk.LEFT, command=self.open_proj_view) menu_bar.add_cascade(label="Trasformations", menu=trasformation_menu) demonstration_menu = Menu(menu_bar, tearoff=False) demonstration_menu.add_command(label="Well-formedness", compound=tk.LEFT, command=self.open_well_formedness) demonstration_menu.add_separator() demonstration_menu.add_command(label="Well-branchedness", compound=tk.LEFT, command=self.open_well_branchedness) demonstration_menu.add_command(label="Well-sequencedness", compound=tk.LEFT, command=self.open_well_sequencedness) menu_bar.add_cascade(label="Properties", menu=demonstration_menu) help_menu = Menu(menu_bar, tearoff=False) help_menu.add_command(label="ReadMe", compound=tk.LEFT, command=self.help_window) menu_bar.add_cascade(label="Help", menu=help_menu) self.master.config(menu=menu_bar) # create the log box self._log = Listbox(log_frame, highlightthickness=0, height=1, background=self.COLOR_log, foreground=self.COLOR_foreground) self._log.pack(side="bottom", fill="x", padx=5, pady=5) self.tabs = ttk.Notebook(tab_frame) def open_file(self, path): if path == None: path = filedialog.askopenfilename(initialdir=".", filetypes=(("DOT graph", "*.gv *.dot"), ("Chorgram grammar", "*.txt"), ("all files", "*.*")), title="Choose a file.") self.dos2unix(path) msg_result = [] # Check in case user enter an unknown file # or closes without choosing a file. try: path_splitted = os.path.split(path) ext = path_splitted[1].split('.') # Chorgram file if ext[1] == 'txt': msg_result = self.__open_chorgram_file(path) # DOT files elif ext[1] == 'dot' or ext[1] == 'gv': msg_result = self.__open_dot_file__(path) else: self.popupmsg("Unknown extension file") # update log box self.log(msg_result) except: pass def __open_chorgram_file(self, path): path_splitted = os.path.split(path) # ask where store the converted dot file ask_for_path: bool = messagebox.askyesno( "Chorgram", "A Chorgram file was inserted\n" + "Do you wish to save the converted dot file in " + path_splitted[0] + "?\n" + "(Click NO to choose a new path)") if ask_for_path: # Yes, use same path # (input path, path to store) msg_result, graph_name = self.controller.GGparser( path, path_splitted[0]) else: new_folder = filedialog.askdirectory() msg_result, graph_name = self.controller.GGparser(path, new_folder) self.__add_new_tab__(graph_name, path) return msg_result def __open_dot_file__(self, path): # result[0] domitilla boolean # result[1] a message # result[2] graph name result = self.controller.DOTparser(path) msg_result = result[1] if result[0]: # if a domitilla graph was founded # ask where store the converted dot file path_splitted = os.path.split(path) ask_for_path: bool = messagebox.askyesno( "Domitilla", "A Domitilla file was inserted\n" "Do you wish to store the converted file in " + path_splitted[0] + "?\n" "(Click NO to choose a new path)") if ask_for_path: # Yes, use same path msg_result.append( self.controller.DomitillaConverter(result[2], path, path_splitted[0]) ) # (graph name, input path, path to store) else: new_folder = filedialog.askdirectory() msg_result.append( self.controller.DomitillaConverter(result[2], path, new_folder)) if len(result) > 2: # case NO-errors detected # add a new tab for the new graph just opened self.__add_new_tab__(result[2], path) return msg_result def open_render_view(self): try: path = filedialog.askopenfilename(initialdir=".", filetypes=(("DOT graph", "*.gv *.dot"), ("all files", "*.*")), title="Choose a file.") path_splitted = os.path.split(path) ext = path_splitted[1].split('.') # Check in case user enter an unknown file # or closes without choosing a file. if ext[1] != 'dot' and ext[1] != 'gv': self.popupmsg("Wrong extension file inserted!\n" "Please insert a DOT file") else: # define the frame and its geometry r_window = tk.Toplevel(padx=20, pady=20, bg=self.COLOR_frames) r_window.wm_title("Render") r_window.resizable(False, False) self.__set_window_dimension__(r_window) label_format = tk.Label( r_window, text="Choose a file format for render:", fg=self.COLOR_foreground, bg=self.COLOR_frames, wraplength=500) label_format.grid(row=0, column=0) # Initialize file format variable for radiobutton option = tk.StringVar() # Radiobutton rb1 = Radiobutton(r_window, text='png', value="png", var=option, bg=self.COLOR_frames) rb2 = Radiobutton(r_window, text='pdf', value="pdf", var=option, bg=self.COLOR_frames) rb1.grid(row=1, column=0) rb2.grid(row=1, column=1) # TODO try except for wrong dot files b = Button(r_window, text='Render', bg=self.COLOR_buttons, command=lambda: (self.log([ "[RENDER] " + self.controller.render( path, option.get(), True) ]), r_window.destroy())) b.grid(row=2, column=1) except: pass def open_product_view(self): # define the frame and its geometry p_window = tk.Toplevel(padx=20, pady=20, bg=self.COLOR_frames) p_window.wm_title("Product") p_window.resizable(False, False) # set window dimension self.__set_window_dimension__(p_window) # label and combo for 1st graph lbl1 = tk.Label(p_window, text="Choose 1st Graph", bg=self.COLOR_frames, fg=self.COLOR_foreground) lbl1.grid(row=0, column=0, pady=10) combo1 = ttk.Combobox(p_window, values=list(self.controller.get_all_ca().keys())) combo1.grid(row=0, column=1, pady=10) # label and combo for 2st graph lbl2 = tk.Label(p_window, text="Choose 2st Graph", bg=self.COLOR_frames, fg='white') lbl2.grid(row=1, column=0, pady=10) combo2 = ttk.Combobox(p_window, values=list(self.controller.get_all_ca().keys())) combo2.grid(row=1, column=1, pady=10) make_button = Button( p_window, text='Make product', bg=self.COLOR_buttons, command=lambda: (self.__exec_product_button__( combo1.get(), combo2.get()), p_window.destroy())) make_button.grid(row=2, column=0, pady=10) def open_sync_view(self): s_window = tk.Toplevel(padx=20, pady=20, bg=self.COLOR_frames) s_window.wm_title("Synchronisation") s_window.resizable(False, False) # set window dimension self.__set_window_dimension__(s_window) # label and combo for the graph to synchronize lbl1 = tk.Label(s_window, text="Choose Graph", fg='white', bg=self.COLOR_frames) lbl1.grid(row=0, column=0, padx=10, pady=10) option_v1 = tk.StringVar() option_v2 = tk.StringVar() combo = ttk.Combobox(s_window, values=list(self.controller.get_all_ca().keys())) combo.bind( "<<ComboboxSelected>>", lambda event: self.__make_sync_interface_menu__( s_window, list(self.controller.get_participants(combo.get())), option_v1, option_v2)) combo.grid(row=1, column=0, padx=10, pady=10) sync_button = Button( s_window, text='Synchronize', bg=self.COLOR_buttons, command=lambda: (self.__exec_sync_button__(combo.get( ), option_v1.get(), option_v2.get()), s_window.destroy())) sync_button.grid(row=4, column=0) def open_proj_view(self): proj_window = tk.Toplevel(padx=20, pady=20, bg=self.COLOR_frames) proj_window.wm_title("Projection") proj_window.resizable(False, False) # set window dimension self.__set_window_dimension__(proj_window) # label and combo for the graph to synchronize lbl1 = tk.Label(proj_window, text="Choose Graph", bg=self.COLOR_frames, fg='white') lbl1.grid(row=0, column=0, padx=10, pady=10) option = tk.StringVar() combo = ttk.Combobox(proj_window, values=list(self.controller.get_all_ca().keys())) combo.bind( "<<ComboboxSelected>>", lambda event: self.__make_proj_participant_menu__( proj_window, list(self.controller.get_participants(combo.get()) ), option)) combo.grid(row=1, column=0, padx=10, pady=10) proj_button = Button( proj_window, text='Project', bg=self.COLOR_buttons, command=lambda: (self.__exec_proj_button__(combo.get(), option.get( )), proj_window.destroy())) proj_button.grid(row=4, column=0) def open_well_formedness(self): p_window = tk.Toplevel(padx=20, pady=20, bg=self.COLOR_frames) p_window.wm_title("Well-formedness") p_window.resizable(False, False) # set window dimension self.__set_window_dimension__(p_window) # label and combo for 1st graph lbl1 = tk.Label(p_window, text="Choose Graph", bg=self.COLOR_frames, fg=self.COLOR_foreground) lbl1.grid(row=0, column=0, pady=10) combo1 = ttk.Combobox(p_window, values=list(self.controller.get_all_ca().keys())) combo1.grid(row=0, column=1, pady=10) verify_button = Button( p_window, text='Verify', bg=self.COLOR_buttons, command=lambda: (self.__exec_well_formedness__(combo1.get()), p_window.destroy())) verify_button.grid(row=2, column=0, pady=10) def open_well_branchedness(self): p_window = tk.Toplevel(padx=20, pady=20, bg=self.COLOR_frames) p_window.wm_title("Well-branchedness") p_window.resizable(False, False) # set window dimension self.__set_window_dimension__(p_window) # label and combo for 1st graph lbl1 = tk.Label(p_window, text="Choose Graph", bg=self.COLOR_frames, fg=self.COLOR_foreground) lbl1.grid(row=0, column=0, pady=10) combo1 = ttk.Combobox(p_window, values=list(self.controller.get_all_ca().keys())) combo1.grid(row=0, column=1, pady=10) verify_button = Button(p_window, text='Verify', bg=self.COLOR_buttons, command=lambda: (self.__exec_well_branchedness__(combo1.get()), p_window.destroy())) verify_button.grid(row=2, column=0, pady=10) def open_well_sequencedness(self): p_window = tk.Toplevel(padx=20, pady=20, bg=self.COLOR_frames) p_window.wm_title("Well-sequencedness") p_window.resizable(False, False) # set window dimension self.__set_window_dimension__(p_window) # label and combo for 1st graph lbl1 = tk.Label(p_window, text="Choose Graph", bg=self.COLOR_frames, fg=self.COLOR_foreground) lbl1.grid(row=0, column=0, pady=10) combo1 = ttk.Combobox(p_window, values=list(self.controller.get_all_ca().keys())) combo1.grid(row=0, column=1, pady=10) verify_button = Button(p_window, text='Verify', bg=self.COLOR_buttons, command=lambda: (self.__exec_well_sequencedness__(combo1.get()), p_window.destroy())) verify_button.grid(row=2, column=0, pady=10) def __add_new_tab__(self, graph_name, v_path): self.tabs.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W), padx=10, pady=5) frame = ttk.Frame(self.tabs) frame.grid_columnconfigure(4, weight=1) # Add the tab self.tabs.add(frame, text=graph_name) label_s = tk.Label(frame, text="N° States:", wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) label_s.grid(row=0, column=0, pady=10, padx=20) entry_s = tk.Label(frame, text=(str( len(self.controller.get_states(graph_name)))), wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) entry_s.grid(row=0, column=1, pady=10, padx=20) label_e = tk.Label(frame, text="N° Edges:", wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) label_e.grid(row=1, column=0, pady=10, padx=20) entry_e = tk.Label(frame, text=str(len( self.controller.get_edges(graph_name))), wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) entry_e.grid(row=1, column=1, pady=10, padx=20) label_sn = tk.Label(frame, text="Start Node:", wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) label_sn.grid(row=2, column=0, pady=10, padx=20) entry_sn = tk.Label(frame, text=str( self.controller.get_start_node(graph_name)), wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) entry_sn.grid(row=2, column=1, pady=10, padx=20) label_eps = tk.Label(frame, text="Epsilon moves:", wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) label_eps.grid(row=5, column=0, pady=10, padx=20) entry_eps = tk.Label( frame, text=self.controller.check_for_epsilon_moves(graph_name), wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) entry_eps.grid(row=5, column=1, pady=10, padx=20) label_l = tk.Label(frame, text="N° Labels:", wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) label_l.grid(row=3, column=0, pady=10, padx=20) elements_l = list(self.controller.get_labels(graph_name)) option_l = tk.StringVar() if not elements_l: print("lista vuota") else: option_l.set(elements_l[0]) label_menu = ttk.OptionMenu(frame, option_l, elements_l[0], *elements_l) label_menu.grid(row=3, column=2, pady=10, padx=20) entry_l = tk.Label(frame, text=len(elements_l), wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) entry_l.grid(row=3, column=1, pady=10, padx=20) label_p = tk.Label(frame, text="N° Participants:", wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) label_p.grid(row=4, column=0, pady=10, padx=20) elements_p = list(self.controller.get_participants(graph_name)) option_p = tk.StringVar() if not elements_p: print("seconda lista vuota") else: option_p.set(elements_p[0]) part_menu = ttk.OptionMenu(frame, option_p, elements_p[0], *elements_p) part_menu.grid(row=4, column=2, pady=10, padx=20) entry_p = tk.Label(frame, text=len(elements_p), wraplength=500, bg=self.COLOR_frames, fg=self.COLOR_foreground) entry_p.grid(row=4, column=1, pady=10, padx=20) self.controller.render(v_path, 'png', False) new_path = v_path + ".png" image = Image.open(new_path) image = image.resize((150, 200), Image.ANTIALIAS) img = ImageTk.PhotoImage(image) labelprova = tk.Label(frame, image=img) labelprova.photo = img labelprova.grid(row=0, column=3, rowspan=5, padx=(150, 0), pady=10) # create close button close_button = Button( frame, text='X', bg=self.COLOR_frames, highlightthickness=0, borderwidth=0, command=lambda: ( self.controller.remove_record( self.tabs.tab(self.tabs.select(), "text")), # remove the record from opened graphs struct self.tabs.forget(self.tabs.select()), self.tabs_history.remove(v_path))) # delete the tab close_button.grid(row=0, column=4, sticky=tk.E + tk.N) #update tab in tab history self.tabs_history.append(v_path) # once created, select the tab self.tabs.select(frame) def __exec_sync_button__(self, combo_value, interface1, interface2): path_to_store = filedialog.asksaveasfilename(initialdir=".", title="Save as", filetypes=("DOT graph", "*.gv *.dot")) result = self.controller.synchronize(combo_value, interface1, interface2, path_to_store) # print the log message self.log(result[0]) # create a new tab for the product graph self.open_file(path_to_store + ".gv") def __exec_product_button__(self, combo_value1, combo_value2): path_to_store = filedialog.asksaveasfilename(initialdir=".", title="Save as", filetypes=("DOT graph", "*.gv *.dot")) result = self.controller.make_product(combo_value1, combo_value2, path_to_store) # print the log message self.log(result[0]) # create a new tab for the product graph self.open_file(path_to_store + ".gv") def __exec_proj_button__(self, combo_value, participant): path_to_store = filedialog.asksaveasfilename(initialdir=".", title="Save as", filetypes=("DOT graph", "*.gv *.dot")) result = self.controller.projection(combo_value, participant, path_to_store) self.open_file(path_to_store + ".gv") # print the log message self.log(result[0]) def __make_sync_interface_menu__(self, frame, elements, option_v1, option_v2): # label and optionMenu for the 1st interface option_v1.set(elements[0]) lbl2 = tk.Label(frame, text="Select 1st participant", bg=self.COLOR_frames, fg=self.COLOR_foreground) lbl2.grid(row=2, column=0, padx=10, pady=10) op_menu_1 = ttk.OptionMenu(frame, option_v1, elements[0], *elements) op_menu_1.grid(row=2, column=1, padx=10, pady=10) # label and optionMenu for the 2st interface option_v2.set(elements[0]) lbl3 = tk.Label(frame, text='Select 2st participant', bg=self.COLOR_frames, fg=self.COLOR_foreground) lbl3.grid(row=3, column=0, pady=10) op_menu_2 = ttk.OptionMenu(frame, option_v2, elements[0], *elements) op_menu_2.grid(row=3, column=1, padx=10, pady=10) # update window dimension self.__set_window_dimension__(frame) def __make_proj_participant_menu__(self, frame, elements, option): option.set(elements[0]) lbl = tk.Label(frame, text='Select participant to project', bg=self.COLOR_frames, fg=self.COLOR_foreground) lbl.grid(row=2, column=0, padx=10, pady=10) op_menu = ttk.OptionMenu(frame, option, elements[0], *elements) op_menu.grid(row=2, column=1, padx=10, pady=10) self.__set_window_dimension__(frame) def __exec_well_formedness__(self, combo_value): result = self.controller.make_well_formedness(combo_value) self.log(result[0]) return def __exec_well_branchedness__(self, combo_value): result = self.controller.make_well_branchedness(combo_value) self.log(result[0]) return def __exec_well_sequencedness__(self, combo_value): result = self.controller.make_well_sequencedness(combo_value) self.log(result[0]) return def __set_window_dimension__(self, frame): # set window dimension width, height = frame.winfo_reqwidth(), frame.winfo_reqheight() frame.geometry('+%d+%d' % (self._screen_width / 2 - width / 2, self._screen_height / 2 - height / 2)) def log(self, msg): print(msg) # Write a message in the log box for line in msg: self._log.insert(tk.END, line) self._log.see(tk.END) # make the last item background red #self._log.itemconfig(tk.END, {'bg': 'red'}) def popupmsg(self, msg): popup = tk.Toplevel(padx=20, pady=20) popup.wm_title("!") popup.resizable(False, False) screen_width, screen_height = popup.winfo_screenwidth( ), popup.winfo_screenheight() width, height = popup.winfo_reqwidth(), popup.winfo_reqheight() popup.geometry( '+%d+%d' % (screen_width / 2 - width / 2, screen_height / 2 - height / 2)) max_size = popup.winfo_screenwidth() / 3 label = tk.Label(popup, text=msg, wraplength=max_size) label.grid(row=0, column=0) b = ttk.Button(popup, text="Okay", command=popup.destroy) b.grid(row=1, column=0)
class RecursiveDescentApp(object): """ A graphical tool for exploring the recursive descent parser. The tool displays the parser's tree and the remaining text, and allows the user to control the parser's operation. In particular, the user can expand subtrees on the frontier, match tokens on the frontier against the text, and backtrack. A "step" button simply steps through the parsing process, performing the operations that ``RecursiveDescentParser`` would use. """ def __init__(self, grammar, sent, trace=0): self._sent = sent self._parser = SteppingRecursiveDescentParser(grammar, trace) # Set up the main window. self._top = Tk() self._top.title('Recursive Descent Parser Application') # Set up key bindings. self._init_bindings() # Initialize the fonts. self._init_fonts(self._top) # Animations. animating_lock is a lock to prevent the demo # from performing new operations while it's animating. self._animation_frames = IntVar(self._top) self._animation_frames.set(5) self._animating_lock = 0 self._autostep = 0 # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_feedback(self._top) self._init_grammar(self._top) self._init_canvas(self._top) # Initialize the parser. self._parser.initialize(self._sent) # Resize callback self._canvas.bind('<Configure>', self._configure) ######################################### ## Initialization Helpers ######################################### def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = tkinter.font.Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget('size')) self._boldfont = tkinter.font.Font(family='helvetica', weight='bold', size=self._size.get()) self._font = tkinter.font.Font(family='helvetica', size=self._size.get()) if self._size.get() < 0: big = self._size.get()-2 else: big = self._size.get()+2 self._bigfont = tkinter.font.Font(family='helvetica', weight='bold', size=big) def _init_grammar(self, parent): # Grammar view. self._prodframe = listframe = Frame(parent) self._prodframe.pack(fill='both', side='left', padx=2) self._prodlist_label = Label(self._prodframe, font=self._boldfont, text='Available Expansions') self._prodlist_label.pack() self._prodlist = Listbox(self._prodframe, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._prodlist.pack(side='right', fill='both', expand=1) self._productions = list(self._parser.grammar().productions()) for production in self._productions: self._prodlist.insert('end', (' %s' % production)) self._prodlist.config(height=min(len(self._productions), 25)) # Add a scrollbar if there are more than 25 productions. if len(self._productions) > 25: listscroll = Scrollbar(self._prodframe, orient='vertical') self._prodlist.config(yscrollcommand = listscroll.set) listscroll.config(command=self._prodlist.yview) listscroll.pack(side='left', fill='y') # If they select a production, apply it. self._prodlist.bind('<<ListboxSelect>>', self._prodlist_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind('<Control-q>', self.destroy) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Escape>', self.destroy) self._top.bind('e', self.expand) #self._top.bind('<Alt-e>', self.expand) #self._top.bind('<Control-e>', self.expand) self._top.bind('m', self.match) self._top.bind('<Alt-m>', self.match) self._top.bind('<Control-m>', self.match) self._top.bind('b', self.backtrack) self._top.bind('<Alt-b>', self.backtrack) self._top.bind('<Control-b>', self.backtrack) self._top.bind('<Control-z>', self.backtrack) self._top.bind('<BackSpace>', self.backtrack) self._top.bind('a', self.autostep) #self._top.bind('<Control-a>', self.autostep) self._top.bind('<Control-space>', self.autostep) self._top.bind('<Control-c>', self.cancel_autostep) self._top.bind('<space>', self.step) self._top.bind('<Delete>', self.reset) self._top.bind('<Control-p>', self.postscript) #self._top.bind('<h>', self.help) #self._top.bind('<Alt-h>', self.help) self._top.bind('<Control-h>', self.help) self._top.bind('<F1>', self.help) #self._top.bind('<g>', self.toggle_grammar) #self._top.bind('<Alt-g>', self.toggle_grammar) #self._top.bind('<Control-g>', self.toggle_grammar) self._top.bind('<Control-g>', self.edit_grammar) self._top.bind('<Control-t>', self.edit_sentence) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill='none', side='bottom', padx=3, pady=2) Button(buttonframe, text='Step', background='#90c0d0', foreground='black', command=self.step,).pack(side='left') Button(buttonframe, text='Autostep', background='#90c0d0', foreground='black', command=self.autostep,).pack(side='left') Button(buttonframe, text='Expand', underline=0, background='#90f090', foreground='black', command=self.expand).pack(side='left') Button(buttonframe, text='Match', underline=0, background='#90f090', foreground='black', command=self.match).pack(side='left') Button(buttonframe, text='Backtrack', underline=0, background='#f0a0a0', foreground='black', command=self.backtrack).pack(side='left') # Replace autostep... # self._autostep_button = Button(buttonframe, text='Autostep', # underline=0, command=self.autostep) # self._autostep_button.pack(side='left') def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas['scrollregion'] = '%d %d %d %d' % (x1,y1,x2,y2) self._redraw() def _init_feedback(self, parent): self._feedbackframe = feedbackframe = Frame(parent) feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3) self._lastoper_label = Label(feedbackframe, text='Last Operation:', font=self._font) self._lastoper_label.pack(side='left') lastoperframe = Frame(feedbackframe, relief='sunken', border=1) lastoperframe.pack(fill='x', side='right', expand=1, padx=5) self._lastoper1 = Label(lastoperframe, foreground='#007070', background='#f0f0f0', font=self._font) self._lastoper2 = Label(lastoperframe, anchor='w', width=30, foreground='#004040', background='#f0f0f0', font=self._font) self._lastoper1.pack(side='left') self._lastoper2.pack(side='left', fill='x', expand=1) def _init_canvas(self, parent): self._cframe = CanvasFrame(parent, background='white', #width=525, height=250, closeenough=10, border=2, relief='sunken') self._cframe.pack(expand=1, fill='both', side='top', pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Reset Parser', underline=0, command=self.reset, accelerator='Del') filemenu.add_command(label='Print to Postscript', underline=0, command=self.postscript, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label='Edit Grammar', underline=5, command=self.edit_grammar, accelerator='Ctrl-g') editmenu.add_command(label='Edit Text', underline=5, command=self.edit_sentence, accelerator='Ctrl-t') menubar.add_cascade(label='Edit', underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label='Step', underline=1, command=self.step, accelerator='Space') rulemenu.add_separator() rulemenu.add_command(label='Match', underline=0, command=self.match, accelerator='Ctrl-m') rulemenu.add_command(label='Expand', underline=0, command=self.expand, accelerator='Ctrl-e') rulemenu.add_separator() rulemenu.add_command(label='Backtrack', underline=0, command=self.backtrack, accelerator='Ctrl-b') menubar.add_cascade(label='Apply', underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton(label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar) viewmenu.add_separator() viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animation_frames, value=0) animatemenu.add_radiobutton(label="Slow Animation", underline=0, variable=self._animation_frames, value=10, accelerator='-') animatemenu.add_radiobutton(label="Normal Animation", underline=0, variable=self._animation_frames, value=5, accelerator='=') animatemenu.add_radiobutton(label="Fast Animation", underline=0, variable=self._animation_frames, value=2, accelerator='+') menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) helpmenu.add_command(label='Instructions', underline=0, command=self.help, accelerator='F1') menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Helper ######################################### def _get(self, widget, treeloc): for i in treeloc: widget = widget.subtrees()[i] if isinstance(widget, TreeSegmentWidget): widget = widget.label() return widget ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old tree, widgets, etc. if self._tree is not None: self._cframe.destroy_widget(self._tree) for twidget in self._textwidgets: self._cframe.destroy_widget(twidget) if self._textline is not None: self._canvas.delete(self._textline) # Draw the tree. helv = ('helvetica', -self._size.get()) bold = ('helvetica', -self._size.get(), 'bold') attribs = {'tree_color': '#000000', 'tree_width': 2, 'node_font': bold, 'leaf_font': helv,} tree = self._parser.tree() self._tree = tree_to_treesegment(canvas, tree, **attribs) self._cframe.add_widget(self._tree, 30, 5) # Draw the text. helv = ('helvetica', -self._size.get()) bottom = y = self._cframe.scrollregion()[3] self._textwidgets = [TextWidget(canvas, word, font=self._font) for word in self._sent] for twidget in self._textwidgets: self._cframe.add_widget(twidget, 0, 0) twidget.move(0, bottom-twidget.bbox()[3]-5) y = min(y, twidget.bbox()[1]) # Draw a line over the text, to separate it from the tree. self._textline = canvas.create_line(-5000, y-5, 5000, y-5, dash='.') # Highlight appropriate nodes. self._highlight_nodes() self._highlight_prodlist() # Make sure the text lines up. self._position_text() def _redraw_quick(self): # This should be more-or-less sufficient after an animation. self._highlight_nodes() self._highlight_prodlist() self._position_text() def _highlight_nodes(self): # Highlight the list of nodes to be checked. bold = ('helvetica', -self._size.get(), 'bold') for treeloc in self._parser.frontier()[:1]: self._get(self._tree, treeloc)['color'] = '#20a050' self._get(self._tree, treeloc)['font'] = bold for treeloc in self._parser.frontier()[1:]: self._get(self._tree, treeloc)['color'] = '#008080' def _highlight_prodlist(self): # Highlight the productions that can be expanded. # Boy, too bad tkinter doesn't implement Listbox.itemconfig; # that would be pretty useful here. self._prodlist.delete(0, 'end') expandable = self._parser.expandable_productions() untried = self._parser.untried_expandable_productions() productions = self._productions for index in range(len(productions)): if productions[index] in expandable: if productions[index] in untried: self._prodlist.insert(index, ' %s' % productions[index]) else: self._prodlist.insert(index, ' %s (TRIED)' % productions[index]) self._prodlist.selection_set(index) else: self._prodlist.insert(index, ' %s' % productions[index]) def _position_text(self): # Line up the text widgets that are matched against the tree numwords = len(self._sent) num_matched = numwords - len(self._parser.remaining_text()) leaves = self._tree_leaves()[:num_matched] xmax = self._tree.bbox()[0] for i in range(0, len(leaves)): widget = self._textwidgets[i] leaf = leaves[i] widget['color'] = '#006040' leaf['color'] = '#006040' widget.move(leaf.bbox()[0] - widget.bbox()[0], 0) xmax = widget.bbox()[2] + 10 # Line up the text widgets that are not matched against the tree. for i in range(len(leaves), numwords): widget = self._textwidgets[i] widget['color'] = '#a0a0a0' widget.move(xmax - widget.bbox()[0], 0) xmax = widget.bbox()[2] + 10 # If we have a complete parse, make everything green :) if self._parser.currently_complete(): for twidget in self._textwidgets: twidget['color'] = '#00a000' # Move the matched leaves down to the text. for i in range(0, len(leaves)): widget = self._textwidgets[i] leaf = leaves[i] dy = widget.bbox()[1] - leaf.bbox()[3] - 10.0 dy = max(dy, leaf.parent().label().bbox()[3] - leaf.bbox()[3] + 10) leaf.move(0, dy) def _tree_leaves(self, tree=None): if tree is None: tree = self._tree if isinstance(tree, TreeSegmentWidget): leaves = [] for child in tree.subtrees(): leaves += self._tree_leaves(child) return leaves else: return [tree] ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def reset(self, *e): self._autostep = 0 self._parser.initialize(self._sent) self._lastoper1['text'] = 'Reset Application' self._lastoper2['text'] = '' self._redraw() def autostep(self, *e): if self._animation_frames.get() == 0: self._animation_frames.set(2) if self._autostep: self._autostep = 0 else: self._autostep = 1 self._step() def cancel_autostep(self, *e): #self._autostep_button['text'] = 'Autostep' self._autostep = 0 # Make sure to stop auto-stepping if we get any user input. def step(self, *e): self._autostep = 0; self._step() def match(self, *e): self._autostep = 0; self._match() def expand(self, *e): self._autostep = 0; self._expand() def backtrack(self, *e): self._autostep = 0; self._backtrack() def _step(self): if self._animating_lock: return # Try expanding, matching, and backtracking (in that order) if self._expand(): pass elif self._parser.untried_match() and self._match(): pass elif self._backtrack(): pass else: self._lastoper1['text'] = 'Finished' self._lastoper2['text'] = '' self._autostep = 0 # Check if we just completed a parse. if self._parser.currently_complete(): self._autostep = 0 self._lastoper2['text'] += ' [COMPLETE PARSE]' def _expand(self, *e): if self._animating_lock: return old_frontier = self._parser.frontier() rv = self._parser.expand() if rv is not None: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = rv self._prodlist.selection_clear(0, 'end') index = self._productions.index(rv) self._prodlist.selection_set(index) self._animate_expand(old_frontier[0]) return 1 else: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = '(all expansions tried)' return 0 def _match(self, *e): if self._animating_lock: return old_frontier = self._parser.frontier() rv = self._parser.match() if rv is not None: self._lastoper1['text'] = 'Match:' self._lastoper2['text'] = rv self._animate_match(old_frontier[0]) return 1 else: self._lastoper1['text'] = 'Match:' self._lastoper2['text'] = '(failed)' return 0 def _backtrack(self, *e): if self._animating_lock: return if self._parser.backtrack(): elt = self._parser.tree() for i in self._parser.frontier()[0]: elt = elt[i] self._lastoper1['text'] = 'Backtrack' self._lastoper2['text'] = '' if isinstance(elt, Tree): self._animate_backtrack(self._parser.frontier()[0]) else: self._animate_match_backtrack(self._parser.frontier()[0]) return 1 else: self._autostep = 0 self._lastoper1['text'] = 'Finished' self._lastoper2['text'] = '' return 0 def about(self, *e): ABOUT = ("NLTK Recursive Descent Parser Application\n"+ "Written by Edward Loper") TITLE = 'About: Recursive Descent Parser Application' try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def help(self, *e): self._autostep = 0 # The default font's not very legible; try using 'fixed' instead. try: ShowText(self._top, 'Help: Recursive Descent Parser Application', (__doc__ or '').strip(), width=75, font='fixed') except: ShowText(self._top, 'Help: Recursive Descent Parser Application', (__doc__ or '').strip(), width=75) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size+2))) self._redraw() ######################################### ## Expand Production Selection ######################################### def _toggle_grammar(self, *e): if self._show_grammar.get(): self._prodframe.pack(fill='both', side='left', padx=2, after=self._feedbackframe) self._lastoper1['text'] = 'Show Grammar' else: self._prodframe.pack_forget() self._lastoper1['text'] = 'Hide Grammar' self._lastoper2['text'] = '' # def toggle_grammar(self, *e): # self._show_grammar = not self._show_grammar # if self._show_grammar: # self._prodframe.pack(fill='both', expand='y', side='left', # after=self._feedbackframe) # self._lastoper1['text'] = 'Show Grammar' # else: # self._prodframe.pack_forget() # self._lastoper1['text'] = 'Hide Grammar' # self._lastoper2['text'] = '' def _prodlist_select(self, event): selection = self._prodlist.curselection() if len(selection) != 1: return index = int(selection[0]) old_frontier = self._parser.frontier() production = self._parser.expand(self._productions[index]) if production: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = production self._prodlist.selection_clear(0, 'end') self._prodlist.selection_set(index) self._animate_expand(old_frontier[0]) else: # Reset the production selections. self._prodlist.selection_clear(0, 'end') for prod in self._parser.expandable_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) ######################################### ## Animation ######################################### def _animate_expand(self, treeloc): oldwidget = self._get(self._tree, treeloc) oldtree = oldwidget.parent() top = not isinstance(oldtree.parent(), TreeSegmentWidget) tree = self._parser.tree() for i in treeloc: tree = tree[i] widget = tree_to_treesegment(self._canvas, tree, node_font=self._boldfont, leaf_color='white', tree_width=2, tree_color='white', node_color='white', leaf_font=self._font) widget.label()['color'] = '#20a050' (oldx, oldy) = oldtree.label().bbox()[:2] (newx, newy) = widget.label().bbox()[:2] widget.move(oldx-newx, oldy-newy) if top: self._cframe.add_widget(widget, 0, 5) widget.move(30-widget.label().bbox()[0], 0) self._tree = widget else: oldtree.parent().replace_child(oldtree, widget) # Move the children over so they don't overlap. # Line the children up in a strange way. if widget.subtrees(): dx = (oldx + widget.label().width()/2 - widget.subtrees()[0].bbox()[0]/2 - widget.subtrees()[0].bbox()[2]/2) for subtree in widget.subtrees(): subtree.move(dx, 0) self._makeroom(widget) if top: self._cframe.destroy_widget(oldtree) else: oldtree.destroy() colors = ['gray%d' % (10*int(10*x/self._animation_frames.get())) for x in range(self._animation_frames.get(),0,-1)] # Move the text string down, if necessary. dy = widget.bbox()[3] + 30 - self._canvas.coords(self._textline)[1] if dy > 0: for twidget in self._textwidgets: twidget.move(0, dy) self._canvas.move(self._textline, 0, dy) self._animate_expand_frame(widget, colors) def _makeroom(self, treeseg): """ Make sure that no sibling tree bbox's overlap. """ parent = treeseg.parent() if not isinstance(parent, TreeSegmentWidget): return index = parent.subtrees().index(treeseg) # Handle siblings to the right rsiblings = parent.subtrees()[index+1:] if rsiblings: dx = treeseg.bbox()[2] - rsiblings[0].bbox()[0] + 10 for sibling in rsiblings: sibling.move(dx, 0) # Handle siblings to the left if index > 0: lsibling = parent.subtrees()[index-1] dx = max(0, lsibling.bbox()[2] - treeseg.bbox()[0] + 10) treeseg.move(dx, 0) # Keep working up the tree. self._makeroom(parent) def _animate_expand_frame(self, widget, colors): if len(colors) > 0: self._animating_lock = 1 widget['color'] = colors[0] for subtree in widget.subtrees(): if isinstance(subtree, TreeSegmentWidget): subtree.label()['color'] = colors[0] else: subtree['color'] = colors[0] self._top.after(50, self._animate_expand_frame, widget, colors[1:]) else: widget['color'] = 'black' for subtree in widget.subtrees(): if isinstance(subtree, TreeSegmentWidget): subtree.label()['color'] = 'black' else: subtree['color'] = 'black' self._redraw_quick() widget.label()['color'] = 'black' self._animating_lock = 0 if self._autostep: self._step() def _animate_backtrack(self, treeloc): # Flash red first, if we're animating. if self._animation_frames.get() == 0: colors = [] else: colors = ['#a00000', '#000000', '#a00000'] colors += ['gray%d' % (10*int(10*x/(self._animation_frames.get()))) for x in range(1, self._animation_frames.get()+1)] widgets = [self._get(self._tree, treeloc).parent()] for subtree in widgets[0].subtrees(): if isinstance(subtree, TreeSegmentWidget): widgets.append(subtree.label()) else: widgets.append(subtree) self._animate_backtrack_frame(widgets, colors) def _animate_backtrack_frame(self, widgets, colors): if len(colors) > 0: self._animating_lock = 1 for widget in widgets: widget['color'] = colors[0] self._top.after(50, self._animate_backtrack_frame, widgets, colors[1:]) else: for widget in widgets[0].subtrees(): widgets[0].remove_child(widget) widget.destroy() self._redraw_quick() self._animating_lock = 0 if self._autostep: self._step() def _animate_match_backtrack(self, treeloc): widget = self._get(self._tree, treeloc) node = widget.parent().label() dy = (1.0 * (node.bbox()[3] - widget.bbox()[1] + 14) / max(1, self._animation_frames.get())) self._animate_match_backtrack_frame(self._animation_frames.get(), widget, dy) def _animate_match(self, treeloc): widget = self._get(self._tree, treeloc) dy = ((self._textwidgets[0].bbox()[1] - widget.bbox()[3] - 10.0) / max(1, self._animation_frames.get())) self._animate_match_frame(self._animation_frames.get(), widget, dy) def _animate_match_frame(self, frame, widget, dy): if frame > 0: self._animating_lock = 1 widget.move(0, dy) self._top.after(10, self._animate_match_frame, frame-1, widget, dy) else: widget['color'] = '#006040' self._redraw_quick() self._animating_lock = 0 if self._autostep: self._step() def _animate_match_backtrack_frame(self, frame, widget, dy): if frame > 0: self._animating_lock = 1 widget.move(0, dy) self._top.after(10, self._animate_match_backtrack_frame, frame-1, widget, dy) else: widget.parent().remove_child(widget) widget.destroy() self._animating_lock = 0 if self._autostep: self._step() def edit_grammar(self, *e): CFGEditor(self._top, self._parser.grammar(), self.set_grammar) def set_grammar(self, grammar): self._parser.set_grammar(grammar) self._productions = list(grammar.productions()) self._prodlist.delete(0, 'end') for production in self._productions: self._prodlist.insert('end', (' %s' % production)) def edit_sentence(self, *e): sentence = " ".join(self._sent) title = 'Edit Text' instr = 'Enter a new sentence to parse.' EntryDialog(self._top, sentence, instr, self.set_sentence, title) def set_sentence(self, sentence): self._sent = sentence.split() #[XX] use tagged? self.reset()
class GenerateWordlist: main_view = "" words = [] files_location = "" def __init__(self, view): self.main_view = view self.root = Toplevel() self.root.protocol("WM_DELETE_WINDOW", self.destroy_window) self.root.geometry('440x540') self.root.resizable(width=False, height=False) self.root.title('WiCC - Generate Wordlist') self.build_window() self.reset_list() self.root.mainloop() def build_window(self): """ Generates the window. :author: Pablo Sanz Alguacil """ # LABELFRAME - INFO self.labelframe_info = LabelFrame(self.root, text="") self.labelframe_info.pack(fill="both", expand="no", pady=5) # LABEL - INFO self.label_info = Label( self.labelframe_info, pady=15, text="In this window you can create your custom wordlist\n" "After generate the list don't forget to select it using\n" "\"Select wordlist\" button in the main window. Words\n" "must be separated by spaces") self.label_info.pack(side=TOP) # LABELFRAME - ADD WORDS self.labelframe_write_word = LabelFrame(self.root, text="Add words") self.labelframe_write_word.pack(fill="both", expand="no", pady=5) # LABEL - ADD WORDS self.label_write_words = Label(self.labelframe_write_word, text="Write words: ") self.label_write_words.pack(side=LEFT, padx=5, pady=10) # ENTRY - ADD WORDS self.entry_words = ttk.Entry(self.labelframe_write_word) self.entry_words.pack(side=LEFT, padx=5, pady=10) self.entry_words.bind('<Button-3>', rClicker, add='') # BUTTON - ADD WORDS self.button_add = Button(self.labelframe_write_word, text="Add", command=self.add_word) self.button_add.pack(side=RIGHT, padx=5, pady=10) # LABELFRMAE - LIST self.labelframe_list = LabelFrame(self.root, text="Key words") self.labelframe_list.pack(fill="both", expand="no", pady=5) # LISTBOX - WORDS self.list_scrollbar = Scrollbar(self.labelframe_list) self.listbox_words = Listbox(self.labelframe_list, width=20, height=12) self.list_scrollbar['command'] = self.listbox_words.yview self.listbox_words['yscroll'] = self.list_scrollbar.set self.list_scrollbar.pack(in_=self.labelframe_list, side=RIGHT, fill=Y, expand="no") self.listbox_words.pack(in_=self.labelframe_list, fill="both", expand="no") # LABELFRMAE - CONTROLS self.labelframe_controls = LabelFrame(self.root, text="Controls") self.labelframe_controls.pack(fill="both", expand="no", pady=5) # BUTTON - RESET LIST self.button_reset = Button(self.labelframe_controls, text="Reset list", command=self.reset_list) self.button_reset.grid(column=0, row=0, padx=5, pady=10) # BUTTON - LOCATION self.button_location = Button(self.labelframe_controls, text="Location", command=self.choose_location) self.button_location.grid(column=1, row=0, padx=5, pady=10) # BUTTON - GENERATE LIST self.button_generate = Button(self.labelframe_controls, text="Generate", command=self.generate_list) self.button_generate.grid(column=2, row=0, padx=5, pady=10) def add_word(self): """ Adds the word/words to the words array, and refreshes the Listbox :author: Pablo Sanz Alguacil """ new_words = self.entry_words.get().split(" ") for word in new_words: self.words.append(word) self.listbox_words.delete(0, END) self.listbox_words.insert(END, *self.words) self.entry_words.delete(0, 'end') def reset_list(self): """ Deletes all elements in the words array and Listobx :author: Pablo Sanz Alguacil """ self.words = [] self.listbox_words.delete(0, END) def choose_location(self): """ Shows a popup window to select a directory to choose save the lists generated. then sends the path to the main view. :author: Pablo Sanz Algucil """ path = filedialog.askdirectory(title="Choose directory", initialdir="/home", mustexist=True) self.files_location = path self.main_view.get_notify_childs(4, self.files_location) def generate_list(self): """ Sends the order and words array to the main view. :author: Pablo Sanz Alguacil """ self.main_view.get_notify_childs(5, self.words) def destroy_window(self): """ Enables all buttons in the main window and destroys this window. :author: Pablo Sanz Alguacil """ self.main_view.disable_window(False) self.root.destroy()
class Player(object): """Player class""" def __init__(self): """Initialisation of the Player object""" self.cfg = None self.db = None self.root = Tk() self.URL1L = StringVar(master=self.root) self.URL2L = StringVar(master=self.root) self.URL3L = StringVar(master=self.root) self.URL4L = StringVar(master=self.root) self.URL5L = StringVar(master=self.root) self.files = {} self.start() #---------------------------------------------------------------------# def start(self): """Start the Player""" print("*** Starting the Player ***") # Configuration self.cfg = Config() while not self.cfg.readConf() or not self.cfg.checkConf(): self.displayConfig() if self.cfg.readConf() and self.cfg.checkConf(): # Database self.db = Db(self.cfg) if self.db.openDb(): self.display() return(True) else: error("Database not open") return(False) else: error("Cannot read configuration file") return(False) #---------------------------------------------------------------------# def stop(self): """Stop the Player""" msg = "Do you want to quit Raspyplayer ?" if messagebox.askokcancel("Raspyplayer MC", msg): print("*** Stopping the Player ***") self.db.closeDb() self.root.destroy() #---------------------------------------------------------------------# def scanDB(self): """Add movies in DB""" print("*** Adding movies in database") self.db.initDb() scanFiles(self.db, self.cfg, self.cfg.PATH) self.db.commitDb() return(True) #---------------------------------------------------------------------# def loadAllMovies(self): """Load movies from DB""" self.files = self.db.getAllMovies() return(True) #---------------------------------------------------------------------# def loadSrcMovies(self, src): """Load movies matching search pattern""" self.files = self.db.getSrcMovies(src) return(True) #---------------------------------------------------------------------# def play(self, url, file): """Play a movie""" print("Playing {}".format(file)) if self.cfg.useOmx(): if not url: sub = file[0:-3] + "srt" if isfile(sub): cmd = self.cfg.OMXCMD2.format(self.cfg.OPT, self.cfg.OUT, sub, file) else: cmd = self.cfg.OMXCMD1.format(self.cfg.OPT, self.cfg.OUT, file) else: cmd = self.cfg.OMXCMD1.format(self.cfg.OPT, self.cfg.OUT, file) else: cmd = self.cfg.MPLRCMD.format(file) if DEBUG: print(cmd) system(cmd) return(True) #---------------------------------------------------------------------# def directPlay(self): """Direct play a file""" file = askopenfilename(title="Select a movie") if file: ps = playScreen() self.play(False, file) ps.destroy() return(True) #---------------------------------------------------------------------# def displayHelp(self): """Display help""" messagebox.showinfo("Help...", getHelp()) return(True) #---------------------------------------------------------------------# def displayConfig(self): """Display Config Window""" self.cfg.display(self) self.askToRefreshDataBase() return(True) #---------------------------------------------------------------------# def playSelection(self): """Play selected files""" sel = self.ui_files.curselection() ps = playScreen() for i in sel: f = self.ui_files.get(i) self.play(False, self.files[f]) ps.destroy() return(True) #---------------------------------------------------------------------# def playUrl(self, url): """Play selected url""" ps = playScreen() self.play(True, url) ps.destroy() return(True) #---------------------------------------------------------------------# def display(self): """Display the player""" self.createGui() self.cfg.toggleUrl(self) self.askToRefreshDataBase() self.root.mainloop() #---------------------------------------------------------------------# def askToRefreshDataBase(self): """Ask to refresh database""" msg = "Do you want to refresh the movies database ?" if messagebox.askokcancel("Raspyplayer MC", msg): self.refreshDataBase() else: self.refreshFilesList() return(True) #---------------------------------------------------------------------# def refreshDataBase(self): """Refresh the movies database""" if isdir(self.cfg.PATH): self.scanDB() self.refreshFilesList() return(True) #---------------------------------------------------------------------# def refreshFilesList(self): """Refresh the list of files""" src = self.ui_srcentry.get() # Empty variables : self.files = {} if self.ui_files.size() > 0: self.ui_files.delete(0, END) # Get files in DB : if src == "" or src == "*": if DEBUG: print("Get ALL") self.loadAllMovies() else: if DEBUG: print("Get '{}'".format(src)) self.loadSrcMovies(('%'+src+'%',)) # Sort results : liste = list() for f, p in self.files.items(): liste.append(f) liste.sort(key=str.lower) # Display result : for file in liste: self.ui_files.insert(END, file) return(True) #---------------------------------------------------------------------# def playUrl1(self): """Play URL 1""" self.playUrl(self.cfg.URL1) def playUrl2(self): """Play URL 2""" self.playUrl(self.cfg.URL2) def playUrl3(self): """Play URL 3""" self.playUrl(self.cfg.URL3) def playUrl4(self): """Play URL 4""" self.playUrl(self.cfg.URL4) def playUrl5(self): """Play URL 5""" self.playUrl(self.cfg.URL5) #---------------------------------------------------------------------# def evtPlay(self, evt): self.playSelection() def evtRefresh(self, evt): self.refreshFilesList() def evtScan(self, evt): self.askToRefreshDataBase() def evtCfg(self, cfg): self.displayConfig() def evtHelp(self, evt): self.displayHelp() def evtQuit(self, evt): self.stop() #---------------------------------------------------------------------# def createGui(self): """Create the GUI for Player""" print("*** Creating GUI ***") self.root.title("Raspyplayer Media Center v{}".format(VERSION)) font = Font(self.root, size=26, family='Sans') #self.root.attributes('-fullscreen', True) self.root.attributes('-zoomed', '1') # Top Frame (search group) self.ui_topframe = Frame(self.root, borderwidth=2) self.ui_topframe.pack({"side": "top"}) # Label search self.ui_srclabel = Label(self.ui_topframe, text="Search:", font=font) self.ui_srclabel.grid(row=1, column=0, padx=2, pady=2) # Entry search self.ui_srcentry = Entry(self.ui_topframe, font=font) self.ui_srcentry.grid(row=1, column=1, padx=2, pady=2) self.ui_srcentry.bind("<Return>", self.evtRefresh) # Button search self.ui_srcexec = Button(self.ui_topframe, text="Search", command=self.refreshFilesList, font=font) self.ui_srcexec.grid(row=1, column=2, padx=2, pady=2) # Frame (contain Middle and Url frames) self.ui_frame = Frame(self.root, borderwidth=2) self.ui_frame.pack(fill=BOTH, expand=1) # Middle Frame (files group) self.ui_midframe = Frame(self.ui_frame, borderwidth=2) self.ui_midframe.pack({"side": "left"}, fill=BOTH, expand=1) # Files liste and scrollbar self.ui_files = Listbox(self.ui_midframe, selectmode=EXTENDED, font=font) self.ui_files.pack(side=LEFT, fill=BOTH, expand=1) self.ui_files.bind("<Return>", self.evtPlay) self.ui_filesscroll = Scrollbar(self.ui_midframe, command=self.ui_files.yview) self.ui_files.configure(yscrollcommand=self.ui_filesscroll.set) self.ui_filesscroll.pack(side=RIGHT, fill=Y) # Url Frame (url group) self.ui_urlframe = Frame(self.ui_frame, borderwidth=2) self.ui_urlframe.pack({"side": "right"}) # Button Url 1 self.ui_buturl1 = Button(self.ui_urlframe, textvariable=self.URL1L, command=self.playUrl1, font=font) self.ui_buturl1.grid(row=1, column=0, padx=2, pady=2) # Button Url 2 self.ui_buturl2 = Button(self.ui_urlframe, textvariable=self.URL2L, command=self.playUrl2, font=font) self.ui_buturl2.grid(row=2, column=0, padx=2, pady=2) # Button Url 3 self.ui_buturl3 = Button(self.ui_urlframe, textvariable=self.URL3L, command=self.playUrl3, font=font) self.ui_buturl3.grid(row=3, column=0, padx=2, pady=2) # Button Url 4 self.ui_buturl4 = Button(self.ui_urlframe, textvariable=self.URL4L, command=self.playUrl4, font=font) self.ui_buturl4.grid(row=4, column=0, padx=2, pady=2) # Button Url 5 self.ui_buturl5 = Button(self.ui_urlframe, textvariable=self.URL5L, command=self.playUrl5, font=font) self.ui_buturl5.grid(row=5, column=0, padx=2, pady=2) # Bottom Frame (buttons group) self.ui_botframe = Frame(self.root, borderwidth=2) self.ui_botframe.pack({"side": "left"}) # Button Play self.ui_butplay = Button(self.ui_botframe, text="Play", command=self.playSelection, font=font) self.ui_butplay.grid(row=1, column=0, padx=2, pady=2) # Button Refresh self.ui_butscan = Button(self.ui_botframe, text="Scan", command=self.askToRefreshDataBase, font=font) self.ui_butscan.grid(row=1, column=1, padx=2, pady=2) # Button Direct Play self.ui_butdplay = Button(self.ui_botframe, text="Direct Play", command=self.directPlay, font=font) self.ui_butdplay.grid(row=1, column=2, padx=2, pady=2) # Button Config self.ui_butconf = Button(self.ui_botframe, text="Config", command=lambda : self.cfg.display(self), font=font) self.ui_butconf.grid(row=1, column=3, padx=2, pady=2) # Button Help self.ui_buthelp = Button(self.ui_botframe, text="Help", command=self.displayHelp, font=font) self.ui_buthelp.grid(row=1, column=4, padx=2, pady=2) # Button Quit self.ui_butquit = Button(self.ui_botframe, text="Quit", command=self.stop, font=font) self.ui_butquit.grid(row=1, column=5, padx=2, pady=2) # General bindings self.root.bind("<F1>", self.evtHelp) self.root.bind("<F2>", self.evtCfg) self.root.bind("<F3>", self.evtRefresh) self.root.bind("<F5>", self.evtScan) self.root.bind("<F12>", self.evtQuit) return(True)
class Masfir(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self._initUI() def _initUI(self): """ Initialise the UI """ self.parent.title("Masfir v0.1") self.style = Style() self.style.theme_use("default") self.pack(fill=BOTH, expand=1) self._createMenu() self._createUIElements() def _createMenu(self): """ Create the menu """ menubar = Menu(self.parent) self.parent.config(menu=menubar) # File Menu mnuFile = Menu(menubar) mnuFile.add_command(label="Exit", underline=1, command=self._onMenuFileExit) menubar.add_cascade(label="File", underline=0, menu=mnuFile) # Help Menu mnuHelp = Menu(menubar) mnuHelp.add_command(label="About", underline=0, command=self._onMenuHelpAbout) menubar.add_cascade(label="Help", underline=0, menu=mnuHelp) def _createUIElements(self): """ Create the main frame's UI elements """ # Top frame with the Load Directory controls frmLoadDir = Frame(self) frmLoadDir.pack(side=TOP, anchor=N, fill=X) self.sLoadDirVar = StringVar() lblLoadDir = Label(frmLoadDir, text="<Empty Directory>", textvariable=self.sLoadDirVar) lblLoadDir.pack(side=LEFT) btnLoadDir = Button(frmLoadDir, text="Load Directory", command=self._onBtnLoadDir) btnLoadDir.pack(side=RIGHT) # Dropdown with list of series (directories) detected frmSeriesSelector = Frame(self) frmSeriesSelector.pack(side=TOP, anchor=N, fill=X) self.sSeriesVar = StringVar() self.optSeries = OptionMenu(frmSeriesSelector, self.sSeriesVar, 'one', 'two', 'three', 'Loading', command=self._onBtnSeriesSelected) self.optSeries.pack(side=LEFT) # The two diff-style listboxes containing original and new episode list names frmListBoxes = Frame(self) frmListBoxes.pack(fill=BOTH, expand=1) self.lstOrgFiles = Listbox(frmListBoxes) self.lstOrgFiles.bind("<<ListboxSelect>>", self._onListOrgFiles) self.lstOrgFiles.pack(side=LEFT, fill=BOTH, expand=1, anchor=W) self.lstNewFiles = Listbox(frmListBoxes) self.lstNewFiles.bind("<<ListboxSelect>>", self._onListNewFiles) self.lstNewFiles.pack(side=RIGHT, fill=BOTH, expand=1, anchor=E) # Bottom buttons frmFinal = Frame(self) frmFinal.pack(side=BOTTOM, anchor=S, fill=X) btnRename = Button(frmFinal, text="Rename", command=self._onBtnRename) btnRename.pack(side=LEFT) btnExit = Button(frmFinal, text="Exit", command=self._onBtnExit) btnExit.pack(side=RIGHT) def _onBtnLoadDir(self): selectedDirectory = filedialog.askdirectory() self.optSeries['menu'].delete(0, END) # self.optSeries['menu'].insert('one', 'two', 'three') self.sSeriesVar.set('two') self.sLoadDirVar.set(selectedDirectory) # Populate listbox self.lstOrgFiles.delete(0, END) for item in os.listdir(selectedDirectory): self.lstOrgFiles.insert(END, item) def _onBtnExit(self): self._exit() def _onListOrgFiles(self): pass def _onListNewFiles(self): pass def _onBtnSeriesSelected(self): pass def _onBtnRename(self): pass def _onMenuFileExit(self): """ Jump to _exit() if Exit is clicked """ self._exit() def _onMenuHelpAbout(self): """ Something here """ pass def _exit(self): """ Exit the app """ self.quit()