class SpeciesListDialog(): def __init__(self, parent): self.parent = parent self.gui = Toplevel(parent.guiRoot) self.gui.grab_set() self.gui.focus() self.gui.columnconfigure(0, weight=1) self.gui.rowconfigure(1, weight=1) Label(self.gui, text="Registered Species:").grid(row=0, column=0, pady=5, padx=5, sticky="w") self.listRegisteredSpecies = Listbox(self.gui, width=70) self.buttonAdd = Button(self.gui, text=" + ") self.buttonDel = Button(self.gui, text=" - ") self.listRegisteredSpecies.grid(row=1, column=0, columnspan=3, sticky="nswe", pady=5, padx=5) self.buttonAdd.grid(row=2, column=1, pady=5, padx=5) self.buttonDel.grid(row=2, column=2, pady=5, padx=5) # Set (minimum + max) Window size self.gui.update() self.gui.minsize(self.gui.winfo_width(), self.gui.winfo_height()) # self.gui.maxsize(self.gui.winfo_width(), self.gui.winfo_height()) self.actionUpdate(None) self.gui.bind("<<Update>>", self.actionUpdate) self.gui.protocol("WM_DELETE_WINDOW", self.actionClose) self.buttonDel.bind("<ButtonRelease>", self.actionDel) self.buttonAdd.bind("<ButtonRelease>", self.actionAdd) self.gui.mainloop() def actionClose(self): self.parent.guiRoot.event_generate("<<Update>>", when="tail") self.gui.destroy() def actionUpdate(self, event): self.listRegisteredSpecies.delete(0, "end") for (taxid, name) in self.parent.optimizer.speciesList: self.listRegisteredSpecies.insert("end", taxid + ": " + name) def actionDel(self, event): try: selection = self.listRegisteredSpecies.selection_get() selectionSplit = selection.split(": ") self.parent.optimizer.speciesList.remove((selectionSplit[0], selectionSplit[1])) self.gui.event_generate("<<Update>>") except tkinter.TclError : # no selection pass def actionAdd(self, Event): SpeciesSearchDialog(self.parent, self)
def reset_server(): '''Restarts Choosing of CSV Files''' global tempdir, tempdir2, opened, gui, httpd threading.Thread(target=httpd.shutdown, daemon=True).start() threading.Thread(target=httpd.server_close, daemon=True).start() gui = Toplevel() gui.title('PythonGUI') #Title gui.iconbitmap('resources/snake.ico') #GUI Icon gui.minsize(500, 540) #Size of GUI gui.attributes('-topmost', True) #Set GUI to always be the topmost window opened = [0, 0] tempdir, tempdir2 = '', '' photo = PhotoImage(file="resources/gui.png") #Logo label_five = Label(gui, image=photo).grid(pady=10) btn_one = Button(gui, text="Choose 1st CSV file", command=lambda: open_file('1')).grid( pady=4) #CSV Selection btn_two = Button(gui, text="Choose 2nd CSV file", command=lambda: open_file('2')).grid(pady=4) browsers = { 'Firefox': "firefox", 'Chrome': "chrome", 'Opera': "opera", 'Iexplore': "iexplore" } items = StringVar(value=tuple(sorted(browsers.keys()))) listbox = Listbox(gui, listvariable=items, width=40, height=5) #Browser Selection listbox.grid(column=0, row=4, rowspan=6, pady=10) selectButton = Button(gui, text='Select Browser', underline=0, command=lambda: selection(listbox.selection_get())) selectButton.grid(pady=10) gui.mainloop()
class ChapterListWindow(BaseListMenu): # Window title TITLE = 'Chapter Results' def __init__(self, prior_window, manga_scraper_obj: MangaReaderScraper): # call parent object super().__init__(title=self.TITLE) # set scraper attribute self.scraper = manga_scraper_obj # listbox self.list_box = Listbox(self.frame, width=50, selectmode='single', yscrollcommand=self.scrollbar.set) # Update scraper object with current list of chapters for series. self.scraper.get_chapters_for_series() # Add each chapter number to list box [ self.list_box.insert('end', i) for i in self.scraper.get_chapters.keys() ] # default selection to first index self.list_box.select_set(0) # set scrollbar view to listbox self.scrollbar.config(command=self.list_box.yview) # pack scrollbar self.scrollbar.pack(side='right', fill='y') # set default icon self.iconbitmap(ICON_PATH) # pack frame self.frame.pack() # pack list box self.list_box.pack(pady=15) # inner method for retrieving chapter image files def get_chapter(self, chapter_chosen, chapter_text): try: # Update chapter attribute self.scraper.chapter = chapter_chosen self.scraper.chapter_name = utils.FileRenaming.strip_unwanted_characters( chapter_text) # Download image LoadingBar(func=self.scraper.get_pages) except Exception as e: messagebox.showerror(title='ERROR', message=e) finally: return # OK Button self.ok_btn = Button(self, text='OK', command=lambda: get_chapter( self, chapter_chosen=self.scraper.get_chapters[ self.list_box.selection_get()], chapter_text=self.list_box.selection_get())) self.ok_btn.pack(side='left', padx=(80, 10), pady=10) # closes the current window and restores focus to the prior open window (in this instance, the series results) def close_and_restore_focus(self, prior_window): self.destroy() prior_window.focus_force() prior_window.grab_set() # Cancel Button self.cancel_btn = Button( self, text='Cancel', command=lambda: close_and_restore_focus(self, prior_window)) self.cancel_btn.pack(side='right', padx=(10, 80), pady=10)
class SearchResultsWindow(BaseListMenu): # Window title TITLE = 'Search Results' def __init__(self, manga_scraper_obj: MangaReaderScraper): # call parent super().__init__(title=self.TITLE) # listbox self.list_box = Listbox(self.frame, width=50, selectmode='single', yscrollcommand=self.scrollbar.set) # add data to listbox self.list_box.insert('end', *manga_scraper_obj._text_list_of_series) # default selection to first index self.list_box.select_set(0) # set scrollbar view to listbox self.scrollbar.config(command=self.list_box.yview) # pack scrollbar self.scrollbar.pack(side='right', fill='y') # set default icon self.iconbitmap(ICON_PATH) # pack frame self.frame.pack() # pack list box self.list_box.pack(pady=15) # inner method for when ok button is clicked def ok_btn_click(self, manga_scraper_obj, series_chosen): self.check(manga_scraper_obj, series_chosen) # OK Button self.ok_btn = Button(self, text='OK', command=lambda: ok_btn_click( self, manga_scraper_obj=manga_scraper_obj, series_chosen=self.list_box.selection_get())) self.ok_btn.pack(side='left', padx=(80, 10), pady=10) # Cancel Button self.cancel_btn = Button(self, text='Cancel', command=lambda: self.destroy()) self.cancel_btn.pack(side='right', padx=(10, 80), pady=10) def check(self, manga_scraper_obj, series_chosen): if series_chosen is not None: # Set series attribute for manga scraper manga_scraper_obj.series = series_chosen # Initialize chapter list window chapter_results = ChapterListWindow( prior_window=self, manga_scraper_obj=manga_scraper_obj) chapter_results.focus_force() self.grab_release() chapter_results.grab_set() else: # Notify that a series hasn't been selected yet. messagebox.showinfo(title='Please select', message='No series selected.')
httpd.serve_forever() #Hosts HTTP Server on localhost if __name__ == "__main__": '''Styling of Tkinter GUI''' photo = PhotoImage(file="resources/gui.png") #Logo label_five = Label(gui, image=photo).grid(pady=10) btn_one = Button(gui, text="Choose 1st CSV file", command=lambda: open_file('1')).grid( pady=4) #CSV Selection btn_two = Button(gui, text="Choose 2nd CSV file", command=lambda: open_file('2')).grid(pady=4) browsers = { 'Firefox': "firefox", 'Chrome': "chrome", 'Opera': "opera", 'Iexplore': "iexplore" } items = StringVar(value=tuple(sorted(browsers.keys()))) listbox = Listbox(gui, listvariable=items, width=40, height=5) #Browser Selection listbox.grid(column=0, row=4, rowspan=6, pady=10) selectButton = Button(gui, text='Select Browser', underline=0, command=lambda: selection(listbox.selection_get())) selectButton.grid(pady=10) gui.mainloop()
class SpeciesSearchDialog(): def __init__(self, parent, caller): # main window self.parent=parent # dialog that called this second dialog self.caller=caller self.gui = Toplevel(parent.guiRoot) self.gui.grab_set() self.gui.focus() self.gui.columnconfigure(0, weight=1) self.gui.rowconfigure(1, weight=1) self.entrySearch = Entry(self.gui) self.buttonSearch = Button(self.gui, text=" Search ") self.buttonAdd = Button(self.gui, text=" Add Species ") self.buttonClose = Button(self.gui, text=" Close Window ") self.frameResults = Frame(self.gui) self.frameResults.columnconfigure(0, weight=1) self.frameResults.rowconfigure(0, weight=1) self.scrollResults = Scrollbar(self.frameResults, orient="vertical") self.scrollResults.grid(row=0, column=1, sticky="ns") self.listResults = Listbox(self.frameResults, width=70, height=20) self.listResults.grid(row=0, column=0, sticky="nswe") self.listResults.config(yscrollcommand=self.scrollResults.set) self.scrollResults.config(command=self.listResults.yview) self.entrySearch.grid(row=0, column=0, columnspan=2, sticky="we", padx=5, pady=5) self.frameResults.grid(row=1, column=0, columnspan=3, sticky="nswe", padx=5, pady=5) self.buttonSearch.grid(row=0, column=2, padx=5, pady=5, sticky="e") self.buttonAdd.grid(row=2, column=1, padx=5, pady=5, sticky="e") self.buttonClose.grid(row=2, column=2, padx=5, pady=5, sticky="e") self.gui.protocol("WM_DELETE_WINDOW", self.actionClose) self.buttonClose.bind("<ButtonRelease>", self.actionClose) self.buttonAdd.bind("<ButtonRelease>", self.actionAdd) self.buttonSearch.bind("<ButtonRelease>", self.actionSearch) self.entrySearch.bind("<Return>", self.actionSearch) self.gui.update() self.gui.minsize(self.gui.winfo_width(), self.gui.winfo_height()) self.gui.mainloop() def actionAdd(self, event): try: selection = self.listResults.selection_get() selectionSplit = selection.split(":\t", 1) selectionSplit2 = selectionSplit[1].split("\t") if not (selectionSplit[0], selectionSplit2[0]) in self.parent.optimizer.speciesList: self.parent.optimizer.speciesList.append((selectionSplit[0], selectionSplit2[0].strip())) self.caller.gui.event_generate("<<Update>>") except tkinter.TclError : # no selection pass def actionSearch(self, event): query = self.entrySearch.get() if(query): self.listResults.delete(0, "end") results = self.parent.optimizer.SPSUMHandler.search(query) # sort results by nr of CDS results = sorted(results.items(), reverse=True, key=lambda x: (int(x[1][1]))) for name, (taxid, ncs) in results: self.listResults.insert("end", taxid + ":\t " + name + " \t(" + ncs + " CDS)") def actionClose(self, event=None): self.caller.gui.event_generate("<<Update>>", when="tail") self.gui.destroy()
class OptimizerMainWindow(): ''' classdocs ''' #TODO: change that name def reactToClick(self, event): a = AddRestrictionDialog(self) def __init__(self, optimizer): # always have a reference to model/controller self.optimizer = optimizer # setup main GUI and make stretchable self.guiRoot = Tk() self.guiRoot.title("OPTIMIZR") self.guiRoot.columnconfigure(1, weight=1) self.guiRoot.rowconfigure(0, weight=1) # left (settings) and right (sequences) part self.frameLeft = Frame(self.guiRoot) self.frameLeft.grid(row=0, column=0, sticky=W+E+N+S) self.frameLeft.columnconfigure(0, weight=1) self.frameRight = Frame(self.guiRoot) self.frameRight.grid(row=0, column=1, sticky=W+E+N+S) self.frameRight.columnconfigure(0, weight=1) self.frameRight.rowconfigure(0, weight=1) self.frameRight.rowconfigure(1, weight=1) self.frameSpeciesControll = LabelFrame(self.frameLeft, text="Species", pady=10, padx=10) self.frameSpeciesControll.columnconfigure(1, weight=1) self.frameOptimizationControll = LabelFrame(self.frameLeft, text="Optimization", pady=10, padx=10) self.frameRestrictionControll = LabelFrame(self.frameLeft, text="Restriction Enzymes", pady=10, padx=10) self.frameSpeciesControll.grid(row=0, column=0, sticky=W+E, padx=10, pady=10) self.frameOptimizationControll.grid(row=1, column=0, sticky=W+E, padx=10, pady=10) self.frameRestrictionControll.grid(row=2, column=0, sticky=W+E, padx=10, pady=10) # Species Controll Label(self.frameSpeciesControll, text="Source:").grid(row=0, column=0) Label(self.frameSpeciesControll, text="Target:").grid(row=1, column=0) self.comboSourceSpecies = Combobox(self.frameSpeciesControll, state="readonly") self.comboSourceSpecies.grid(row=0, column=1, pady=5, sticky="ew") self.comboTargetSpecies = Combobox(self.frameSpeciesControll, state="readonly") self.comboTargetSpecies.grid(row=1, column=1, pady=5, sticky="we") self.buttonSpeciesList = Button(self.frameSpeciesControll, text="Edit Species List") self.buttonSpeciesList.grid(row=2, column=1, pady=5, sticky="e") self.comboSourceSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) self.comboTargetSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) # Optimization Controll Label(self.frameOptimizationControll, text="Optimization Strategy:").grid(row=0, column=0) self.comboOptimizationStrategy = Combobox(self.frameOptimizationControll, state="readonly") self.comboOptimizationStrategy.grid(row=0, column=1) self.comboOptimizationStrategy["values"] = self.optimizer.possibleOptimizationStrategies self.comboOptimizationStrategy.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) # Restriction Enzymes self.listRestriction = Listbox(self.frameRestrictionControll) self.listRestriction.grid(row=0, column=0, columnspan=3, pady=5, sticky=W+E) self.frameRestrictionControll.columnconfigure(0, weight=1) self.buttonRestricionAdd = Button(self.frameRestrictionControll, text=" + ") self.buttonRestricionDel = Button(self.frameRestrictionControll, text=" - ") self.buttonRestricionAdd.grid(row=1, column=1, padx=5) self.buttonRestricionDel.grid(row=1, column=2, padx=5) # Source Sequence Frame self.frameSourceSequence = LabelFrame(self.frameRight, text="Source Sequence", padx=10, pady=10) self.frameResultSequence = LabelFrame(self.frameRight, text="Result Sequence", padx=10, pady=10) self.frameSourceSequence.grid(row=0, column=0, sticky="wens", padx=10, pady=10) self.frameResultSequence.grid(row=1, column=0, sticky="wens", padx=10, pady=10) self.buttonSourceLoad = Button(self.frameSourceSequence, text=" Load ") self.textSourceSeq = ScrolledText(self.frameSourceSequence, height=10) self.buttonSourceLoad.grid(row=0, column=1, sticky="e", pady=5) self.textSourceSeq.grid(row=1, column=0, columnspan=2, sticky="wens") self.frameSourceSequence.columnconfigure(0, weight=1) self.frameSourceSequence.rowconfigure(1, weight=1) self.textSourceSeq.frame.columnconfigure(1, weight=1) self.textSourceSeq.frame.rowconfigure(0, weight=1) self.buttonOptimize = Button(self.frameResultSequence, text=" OPTIMIZE! ") self.buttonOptimize.bind("<ButtonRelease>", self.actionOptimize) self.buttonRemoveRestriction = Button(self.frameResultSequence, text=" RESTRICTION-B-GONE! ") self.buttonRemoveRestriction.bind("<ButtonRelease>", self.actionRemoveRestricion) self.buttonSaveResult = Button(self.frameResultSequence, text=" Save ") self.textResultSequence = ScrolledText(self.frameResultSequence, height=10) self.buttonOptimize.grid(column=0, row=0, pady=5, sticky="w") self.buttonRemoveRestriction.grid(column=1, row=0, pady=5, padx=10, sticky="w") self.textResultSequence.grid(row=1, column=0, columnspan=4, sticky="wens") self.buttonSaveResult.grid(row=2, column=3, pady=5, sticky="e") self.frameResultSequence.columnconfigure(2, weight=1) self.frameResultSequence.rowconfigure(1, weight=1) self.textResultSequence.frame.columnconfigure(1, weight=1) self.textResultSequence.frame.rowconfigure(0, weight=1) self.textSourceSeq.bind("<<Modified>>", self.actionSequenceModified) self.textResultSequence.bind("<<Modified>>", self.actionSequenceModified) #generate color tags for textboxes for i in range(101): #green for normal codons (r,g,b) = colorsys.hsv_to_rgb(210/360, i/100, 1.0) colorHex = "#%02x%02x%02x" % (int(r*255), int(g*255), int(b*255)) self.textSourceSeq.tag_config("normal"+str(i), background=colorHex) self.textResultSequence.tag_config("normal"+str(i), background=colorHex) #red for codons with restriction sites (r,g,b) = colorsys.hsv_to_rgb(5/360, i/100, 1.0) colorHex = "#%02x%02x%02x" % (int(r*255), int(g*255), int(b*255)) self.textSourceSeq.tag_config("restrict"+str(i), background=colorHex) self.textResultSequence.tag_config("restrict"+str(i), background=colorHex) # Set (minimum + max) Window size self.guiRoot.update() self.guiRoot.minsize(self.guiRoot.winfo_width(), self.guiRoot.winfo_height()) self.buttonRestricionAdd.bind("<ButtonRelease>", self.reactToClick) self.buttonRestricionDel.bind("<ButtonRelease>", self.actionRestrictionEnzymeDelete) self.buttonSpeciesList.bind("<ButtonRelease>", self.actionEditSpeciesButton) self.buttonSourceLoad.bind("<ButtonRelease>", self.actionLoadSequence) self.buttonSaveResult.bind("<ButtonRelease>", self.actionSaveSequence) # TEST # self.listRestriction.insert("end", "EcoRI") # self.listRestriction.insert("end", "BamHI") # # dummy event to manually trigger update self.guiRoot.bind("<<Update>>", self.actionUpdate) self.actionUpdate(None) self.guiRoot.mainloop() def actionRestrictionEnzymeDelete(self, event): try: selectedEnzyme = self.listRestriction.selection_get() self.optimizer.restrictionEnzymeList.remove(selectedEnzyme) self.guiRoot.event_generate("<<Update>>") except tkinter.TclError : # no selection pass def actionUpdate(self, event): # print("update called") # clear list of restriction enzymes self.listRestriction.delete(0, "end") for r in self.optimizer.restrictionEnzymeList: self.listRestriction.insert("end", r) self.comboSourceSpecies.delete(0, "end") self.comboTargetSpecies.delete(0, "end") speciesValues = list() for (taxid, name) in self.optimizer.speciesList: speciesValues.append(taxid + ": " + name) self.comboSourceSpecies["values"] = speciesValues self.comboTargetSpecies["values"] = speciesValues if self.comboSourceSpecies.get() not in speciesValues: self.comboSourceSpecies.set("") if self.comboTargetSpecies.get() not in speciesValues: self.comboTargetSpecies.set("") self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) self.optimizer.saveConfig("config.ini") def actionEditSpeciesButton(self, event): speciesListDialog = SpeciesListDialog(self) def actionOptimizerSettingsChanged(self, event=None): # print("Something happened") strategy = self.comboOptimizationStrategy.get() sourceString = self.comboSourceSpecies.get() targetString = self.comboTargetSpecies.get() if not (strategy and sourceString and targetString): return sourceTaxid = sourceString.split(":")[0] targetTaxid = targetString.split(":")[0] self.optimizer.setOptimizer(sourceTaxid, targetTaxid, strategy) self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) # self.optimizer.testPrint() def actionOptimize(self, event=None): self.optimizer.runOptimization() self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) def actionRemoveRestricion(self, event=None): self.optimizer.runRestricionRemoval() self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) def actionSequenceModified(self, event=None): # necessary if, otherwise -> infinite loop if self.textSourceSeq.edit_modified(): seq = self.textSourceSeq.get("1.0", "end").strip() seq = stripCharsNotInList(seq.upper(), ['A', 'C', 'G', 'T']) self.optimizer.setSourceSeq(seq) oldInsert = self.textSourceSeq.index("insert") self.textSourceSeq.delete("1.0", "end") sourceCodons = self.optimizer.getCodonsForPrint(True) if not sourceCodons: self.textSourceSeq.insert("end", self.optimizer.sourceSequence) else: for (co, sc, r) in sourceCodons: if sc: if not r: self.textSourceSeq.insert("end", co, "normal"+str(int(sc*100))) #print("normal"+str(int(sc*100))) else: self.textSourceSeq.insert("end", co, "restrict"+str(int(sc*100))) else: # remainder without color self.textSourceSeq.insert("end", co) self.textSourceSeq.mark_set("insert", oldInsert) # reset the modified status at the very end self.textSourceSeq.edit_modified(False) if self.textResultSequence.edit_modified(): seq = self.textResultSequence.get("1.0", "end").strip() # self.optimizer.setOptimizedSeq(seq) oldInsert = self.textResultSequence.index("insert") self.textResultSequence.delete("1.0", "end") targetCodons = self.optimizer.getCodonsForPrint(False) if not targetCodons: self.textSourceSeq.insert("end", self.optimizer.optimizedSequence) else: for (co, sc, r) in targetCodons: if sc: if not r: self.textResultSequence.insert("end", co, "normal"+str(int(sc*100))) #print("normal"+str(int(sc*100))) else: self.textResultSequence.insert("end", co, "restrict"+str(int(sc*100))) else: # remainder without color self.textResultSequence.insert("end", co) self.textSourceSeq.mark_set("insert", oldInsert) self.textResultSequence.edit_modified(False) def actionLoadSequence(self, event=None): filename = tkinter.filedialog.askopenfilename() if filename: seq = sequenceIO.readFile(filename) self.textSourceSeq.delete("1.0", "end") self.textSourceSeq.insert("end", seq) self.textSourceSeq.edit_modified(True) def actionSaveSequence(self, event=None): filename = tkinter.filedialog.asksaveasfilename() if filename: # print("file is " + filename) with open(filename, mode='w') as fd: fd.write(self.optimizer.optimizedSequence)
class StaffFrame(LabelFrame): """Contains data of staffmeeteng""" def __init__(self, window, base, **kwargs): super().__init__(window, **kwargs) self.base = base self.staff_id = None self.all_staff = [i.name for i in Staff.select()] self.data_label = Label(self, text="Data zespołu") self.data_label.grid(row=0, column=0, padx=5, pady=1, sticky='e') self.data_entry = Entry(self, width=20) self.data_entry.grid(row=0, column=1, padx=5, pady=1, sticky='w') self.table = Treeview(self, columns=("name", "speciality")) self.table.heading('#1', text='imię i nazwisko') self.table.heading('#2', text='specjalizacja') self.table.column('#1', width=200) self.table.column('#2', width=200) self.table.grid(row=1, column=0, rowspan=1, columnspan=2, padx=5, pady=5) self.table['show'] = 'headings' self.table.bind('<<TreeviewSelect>>', self.on_treeview_selected) self.another_stuff_frame = LabelFrame(self, text="Inni specjaliści") self.another_stuff_frame.grid(row=2, column=0, columnspan=2, pady=5) self.another_staff = Listbox(self.another_stuff_frame, width=48, height=12) self.another_staff.grid(row=0, column=0, rowspan=2, padx=5, pady=5) self.another_staff.bind('<<ListboxSelect>>', self.on_listbox_select) self.add_button = Button(self, text="Dodaj członka", command=self.add_member) self.add_button.grid(row=3, column=0, padx=5, pady=5) self.delete_button = Button(self, text="Usuń członka", command=self.remove_member) self.delete_button.grid(row=3, column=1, padx=5, pady=5) def get_staff_from_table(self): '''return list of member of staff_meeting from table eg. [[name, speciality],[name, speciality]]''' staff_meeting_list = [] for child in self.table.get_children(): staff_meeting_list.append(self.table.item(child)["values"]) return staff_meeting_list def insert_staff(self, base, staff): self.base = base self.staff = staff self.staff_id = staff['id'] if not self.staff_id: self.tables_tidying() return self.data_entry.delete(0, 'end') self.data_entry.insert(0, staff['date']) self.table.delete(*self.table.get_children()) self.another_staff.delete(0, 'end') for i in staff['team']: self.table.insert('', 'end', values=(i[0], i[1])) self.tables_tidying() def on_listbox_select(self, event): '''Remove selection from table after clicking listbox.''' if self.table.selection(): self.table.selection_remove(self.table.selection()[0]) def on_treeview_selected(self, event): '''Remove selection from lisbox after clicking table''' self.another_staff.select_clear(0, 'end') def tables_tidying(self): '''Remove unused staff from table.''' self.another_staff.delete(0, 'end') used_staff = [x[0] for x in self.get_staff_from_table()] for member in Staff.select(): if member.name not in used_staff: self.another_staff.insert('end', member.name) def add_member(self): '''Add member from listbox to table.''' if not self.another_staff.curselection(): pass else: self.table.insert( '', 'end', values=(self.another_staff.selection_get(), Staff.get(Staff.name == self.another_staff. selection_get()).speciality)) self.tables_tidying() def remove_member(self): '''Removes member from table to listbox.''' selected_item = self.table.selection() if selected_item: self.table.delete(selected_item) self.tables_tidying() def clear(self): self.table.delete(*self.table.get_children()) self.tables_tidying()
class ConfigMgr(Dialog): def __init__(self, x, y, board): self.root = Toplevel() self.root.title("Config Manager") self.board = board f1 = Frame(self.root) f2 = Frame(self.root) f3 = Frame(f2) f1.pack(side=LEFT) f2.pack(side=LEFT) f3.pack(side=TOP) self.listbox = Listbox(f1) self.files = [] self.loadFileList() self.listbox.pack() l1 = Label(f3, text="new File name:") l1.pack(side=LEFT) self.e = Entry(f3) self.e.delete(0, END) self.e.insert(0, "FILENAME") self.e.pack(side=LEFT) buttons = [] buttons.append( Button(f2, text="Save to selected", command=self.saveConf)) buttons.append( Button(f2, text="Save to new File", command=self.newConf)) buttons.append( Button(f2, text="Load selected File", command=self.loadConf)) buttons.append( Button(f2, text="Delete selected File", command=self.delConf)) buttons.append(Button(f2, text="Continue", command=self.root.destroy)) for b in buttons: b.pack(side=TOP) self.align(x, y) self.root.mainloop() def loadFileList(self): if (not os.path.exists("./CONF")): os.mkdir("./CONF") self.files = os.listdir("./CONF/") self.listbox.delete(0, END) for item in self.files: self.listbox.insert(END, item) self.listbox.selection_set(0) self.listbox.update() def saveConf(self): f = open(self.listbox.selection_get(), "wb") data = BoardConfig(copy(self.board)) data_b = pickle.dumps(data) f.write(data_b) f.close() self.loadConf() def newConf(self): f = open("./CONF/" + self.e.get(), "wb") data = BoardConfig(copy(self.board)) data_b = pickle.dumps(data) f.write(data_b) f.close() self.loadFileList() print(self.files) f = open("./CONF/" + self.e.get(), "rb") data_b = f.read() data = pickle.loads(data_b) data.load(self.board) f.close() self.redraw(0) def loadConf(self): f = open("./CONF/" + self.listbox.selection_get(), "rb") data_b = f.read() data = pickle.loads(data_b) data.load(self.board) f.close() self.redraw(0) def delConf(self): MsgBox = messagebox.askquestion( 'WARNING', 'Are you sure you want to delete this file?', icon='warning') if (MsgBox == "yes"): os.remove("./CONF/" + self.listbox.selection_get()) self.loadFileList() self.root.lift() def redraw(self, p): self.board.setHighlight(p) self.board.drawBoard(320, 320) self.board.drawPieces()
class SpeciesSearchDialog: def __init__(self, parent, caller): # main window self.parent = parent # dialog that called this second dialog self.caller = caller self.gui = Toplevel(parent.guiRoot) self.gui.grab_set() self.gui.focus() self.gui.columnconfigure(0, weight=1) self.gui.rowconfigure(1, weight=1) self.entrySearch = Entry(self.gui) self.buttonSearch = Button(self.gui, text=" Search ") self.buttonAdd = Button(self.gui, text=" Add Species ") self.buttonClose = Button(self.gui, text=" Close Window ") self.frameResults = Frame(self.gui) self.frameResults.columnconfigure(0, weight=1) self.frameResults.rowconfigure(0, weight=1) self.scrollResults = Scrollbar(self.frameResults, orient="vertical") self.scrollResults.grid(row=0, column=1, sticky="ns") self.listResults = Listbox(self.frameResults, width=70, height=20) self.listResults.grid(row=0, column=0, sticky="nswe") self.listResults.config(yscrollcommand=self.scrollResults.set) self.scrollResults.config(command=self.listResults.yview) self.entrySearch.grid(row=0, column=0, columnspan=2, sticky="we", padx=5, pady=5) self.frameResults.grid(row=1, column=0, columnspan=3, sticky="nswe", padx=5, pady=5) self.buttonSearch.grid(row=0, column=2, padx=5, pady=5, sticky="e") self.buttonAdd.grid(row=2, column=1, padx=5, pady=5, sticky="e") self.buttonClose.grid(row=2, column=2, padx=5, pady=5, sticky="e") self.gui.protocol("WM_DELETE_WINDOW", self.actionClose) self.buttonClose.bind("<ButtonRelease>", self.actionClose) self.buttonAdd.bind("<ButtonRelease>", self.actionAdd) self.buttonSearch.bind("<ButtonRelease>", self.actionSearch) self.entrySearch.bind("<Return>", self.actionSearch) self.gui.update() self.gui.minsize(self.gui.winfo_width(), self.gui.winfo_height()) self.gui.mainloop() def actionAdd(self, event): try: selection = self.listResults.selection_get() selectionSplit = selection.split(":\t", 1) selectionSplit2 = selectionSplit[1].split("\t") if not (selectionSplit[0], selectionSplit2[0]) in self.parent.optimizer.speciesList: self.parent.optimizer.speciesList.append((selectionSplit[0], selectionSplit2[0].strip())) self.caller.gui.event_generate("<<Update>>") except tkinter.TclError: # no selection pass def actionSearch(self, event): query = self.entrySearch.get() if query: self.listResults.delete(0, "end") results = self.parent.optimizer.SPSUMHandler.search(query) # sort results by nr of CDS results = sorted(results.items(), reverse=True, key=lambda x: (int(x[1][1]))) for name, (taxid, ncs) in results: self.listResults.insert("end", taxid + ":\t " + name + " \t(" + ncs + " CDS)") def actionClose(self, event=None): self.caller.gui.event_generate("<<Update>>", when="tail") self.gui.destroy()
class MainFrame(Frame): def popupmsg(self, monster_name, html): popup = Tk() popup.wm_title(monster_name) html_label = HtmlFrame(popup, horizontal_scrollbar="auto", vertical_scrollbar=True) html_label.pack(fill="both", expand=True) html_label.set_content(html) B1 = ttk.Button(popup, text="Close", command=popup.destroy) B1.pack() popup.mainloop() def set_defaults(self): self.master.title(_title) self.fpath = 'c:/d&d' self.always_on_top.set(False) def pin(self): self.master.wm_attributes('-topmost', self.always_on_top.get()) def add_character(self): self.w = popupWindow(self.master) self.add_button["state"] = "disabled" self.master.wait_window(self.w.top) self.add_button["state"] = "normal" self.next_button["state"] = "normal" self.roll_button["state"] = "normal" self.list_index += 1 self.tree.insert("", self.list_index, self.list_index.__str__(), text=self.entryValue("nome"), values=(self.entryValue("hp"), "")) def roll_dice(self, dice_faces): rng = SystemRandom() return rng.randint(1, dice_faces) def roll_initiative(self): for i in self.tree.get_children(): val = self.tree.item(i, "values") if val[1] == "": self.tree.set(i, 'one', self.roll_dice(20)) self.treeview_sort_column(self.tree, "one", True) def entryValue(self, campo): if campo == "nome": return self.w.name if campo == "hp": return self.w.hp return "" def next_character(self): self.list_selected_index += 1 if self.list_selected_index > len(self.tree.get_children()): self.list_selected_index = 1 self.tree.selection_set(self.list_selected_index) def remove_character(self): self.tree.delete(self.tree.focus()) def remove_all_characters(self): self.tree.delete(*self.tree.get_children()) self.list_index = 0 self.list_selected_index = 0 self.next_button["state"] = "disabled" self.roll_button["state"] = "disabled" def set_saved_title(self, fpath): fname = split(fpath)[-1].replace('.json', '') self.master.title('{} - {}'.format(fname, _title)) def set_unsaved_title(self, *args): # if len(roller_groups) < 1: # return title = self.master.title() if title == _title: title = '{} - {}'.format('Unsaved', title) if '*' not in title: title = '*' + title self.master.title(title) def ask_proceed(self): if '*' in self.master.title(): if not askyesno( 'Unsaved changes!', 'There are unsaved changes!\r\nWould you like to proceed anyway?' ): return False return True def load_monster_name(self): fpath = "C:/Users/Lorenzo/temp/srd_5e_monsters.json" if not fpath or not isfile(fpath): return self.dictionary = {} listanomi = [] with open(fpath, 'r') as f: monsters_file = load(f) try: for monster in monsters_file: listanomi.append(monster["name"]) self.dictionary[monster["name"]] = monster except KeyError: pass return listanomi def load_monster(self, monsterName): try: self.html = '<div style="width:90%; font-family:Arial,Helvetica,sans-serif;font-size:16px;">' self.html = self.convert_json_to_html(self.dictionary[monsterName], self.html) self.html = self.html + '</div>' self.html = self.html + '</body>' self.html = self.html + '</html>' except KeyError: pass def convert_json_to_html(self, monster, html): gradient = '<div style="background:#A73335;height:5px;margin:7px 0px;"></div>' keys = monster.keys() html = html + '<div style="font-size:225%;font-family:Georgia, serif;font-variant:small-caps;font-weight:bold;color:#A73335;">' + monster[ "name"] + '</div>' html = html + '<div style="font-style:italic;">' + monster[ "meta"] + '</div>' html = html + gradient html = html + '<div class="red">' html = html + ' <div ><span style="font-weight:bold;color:#A73335;">Armor Class: </span><span>' + monster[ "Armor Class"] + '</span></div>' html = html + ' <div><span style="font-weight:bold;color:#A73335;">Hit Points: </span><span>' + monster[ "Hit Points"] + '</span></div>' html = html + ' <div><span style="font-weight:bold;color:#A73335;">Speed: </span><span>' + monster[ "Speed"] + '</span></div>' html = html + '</div>' html = html + gradient html = html + '<table style="width:60%;border:0px;border-collapse:collapse;color:#A73335;">' html = html + ' <tr>' html = html + ' <th style="width:20%;text-align:center;">STR</th>' html = html + ' <th style="width:20%;text-align:center;">DEX</th>' html = html + ' <th style="width:20%;text-align:center;">CON</th>' html = html + ' <th style="width:20%;text-align:center;">INT</th>' html = html + ' <th style="width:20%;text-align:center;">WIS</th>' html = html + ' <th style="width:20%;text-align:center;">CHA</th>' html = html + ' </tr>' html = html + ' <tr>' html = html + ' <td style="width:20%;text-align:center;">' + monster[ "STR"] + ' ' + monster["STR_mod"] + '</td>' html = html + ' <td style="width:20%;text-align:center;">' + monster[ "DEX"] + ' ' + monster["DEX_mod"] + '</td>' html = html + ' <td style="width:20%;text-align:center;">' + monster[ "CON"] + ' ' + monster["CON_mod"] + '</td>' html = html + ' <td style="width:20%;text-align:center;">' + monster[ "INT"] + ' ' + monster["INT_mod"] + '</td>' html = html + ' <td style="width:20%;text-align:center;">' + monster[ "WIS"] + ' ' + monster["WIS_mod"] + '</td>' html = html + ' <td style="width:20%;text-align:center;">' + monster[ "CHA"] + ' ' + monster["CHA_mod"] + '</td>' html = html + ' </tr>' html = html + '</table>' html = html + gradient if "Saving Throws" in keys: html = html + '<div><span style="font-weight:bold;">Saving Throws: </span><span>' + monster[ "Saving Throws"] + '</span></div>' if "Skills" in keys: html = html + '<div><span style="font-weight:bold;">Skills: </span><span>' + monster[ "Skills"] + '</span></div>' if "Damage Immunities" in keys: html = html + '<div><span style="font-weight:bold;">Damage Immunities: </span><span>' + monster[ "Damage Immunities"] + '</span></div>' if "Damage Resistances" in keys: html = html + '<div><span style="font-weight:bold;">Damage Resistances: </span><span>' + monster[ "Damage Resistances"] + '</span></div>' if "Condition Immunities" in keys: html = html + '<div><span style="font-weight:bold;">Condition Immunities: </span><span>' + monster[ "Condition Immunities"] + '</span></div>' if "Senses" in keys: html = html + '<div><span style="font-weight:bold;">Senses: </span><span>' + monster[ "Senses"] + '</span></div>' if "Languages" in keys: html = html + '<div><span style="font-weight:bold;">Languages: </span><span>' + monster[ "Languages"] + '</span></div>' if "Challenge" in keys: html = html + '<div><span style="font-weight:bold;">Challenge: </span><span>' + monster[ "Challenge"] + '</span></div> ' html = html + gradient if "Traits" in keys: html = html + '<div style="font-size:175%;font-variant:small-caps;margin:17px 0px 0px 0px;">Traits</div>' html = html + '<div>' + monster["Traits"] + '</div>' html = html + gradient if "Actions" in keys: html = html + '<div style="font-size:175%;font-variant:small-caps;margin:17px 0px 0px 0px;">Actions</div>' html = html + '<div>' + monster["Actions"] + '</div>' html = html + gradient if "Legendary Actions" in keys: html = html + '<div style="font-size:175%;font-variant:small-caps;margin:17px 0px 0px 0px;">Legendary Actions</div>' html = html + '<div>' + monster["Legendary Actions"] + '</div>' html = html + gradient if "img_url" in keys: html = html + '<div><img src=' + monster["img_url"] + '></div>' # for key in item.keys(): # if key == "name" and oldkey == "": # html = html + '<div style="font-size:225%;font-family:Georgia, serif;font-variant:small-caps;font-weight:bold;color:#A73335;">' + item[key] + '</div>' # elif key == "name" and oldkey != "": # html = html + ('<h3 style="color: blue; text-align: left">') + oldkey + ('</H3>') # else: # keyPrint = key.replace("_", " ").capitalize() # # html = html + "<b>" + keyPrint + ": </b>" + str(item[key]) + "<br>" # # if (type(item[key]) is list): # html = self.convert_json_to_html(item[key], html, key) # print(html) return html def load_config(self): autosave = False if not self.ask_proceed(): return fpath = askopenfilename(filetypes=[('JSON', '*.json'), ('All', '*.*')], defaultextension='.json') if not fpath or not isfile(fpath): return self.fpath = fpath # self.clear_groups() # with open(fpath, 'r') as f: # group_dict = load(f) # # try: # settings_dict = group_dict.pop('settings') # autosave = (settings_dict['autosave']) # self.use_random_org.set(settings_dict['use_random_org']) # self.allow_odd .set(settings_dict['allow_odd' ]) # self.always_on_top .set(settings_dict['always_on_top' ]) # except KeyError: # pass # # g = 0 # for group_name, group_settings in group_dict.items(): # self.create_group(g, len(group_settings['rollers'])) # # group = roller_groups[g] # group.name.set(group_name) # group.index = group_settings['index'] # # r = 0 # h = 0 # for roller_name, roller_settings in group_settings['rollers'].items(): # roller = group.rollers[r] # roller.name.set(roller_name) # for attr, value in roller_settings.items(): # try: # getattr(roller, attr).set(value) # except AttributeError: # setattr(roller, attr, value) # roller.reset(loading=True) # h = len(roller.history) - 1 # r += 1 # # group.navigate_history(desired_index=h) # g += 1 # # roller_groups.sort(key=lambda x: x.index) # # maintain_group_indices() # for group in roller_groups: # group.rollers.sort(key=lambda x: x.index) # group.maintain_roller_indices() # for roller in group.rollers: # roller.apply_modifiers() # # maintain_tabstops() self.pin() self.autosave.set(autosave) self.set_saved_title(fpath) def save_config(self, fpath=''): if not fpath: fpath = asksaveasfilename(filetypes=[('JSON', '*.json'), ('All', '*.*')], defaultextension='.json') if not fpath: if '*' in self.master.title(): pass return self.fpath = fpath # d1 = {} # d1['settings'] = {'use_random_org': self.use_random_org.get(), # 'allow_odd' : self.allow_odd .get(), # 'always_on_top' : self.always_on_top .get(), # 'autosave' : self.autosave .get()} # for group in roller_groups: # group.maintain_roller_indices() # d2 = {} # d2['index'] = group.index # d2['rollers'] = {} # for roller in group.rollers: # name = roller.name.get() # while name in d2['rollers']: # name += '!' # d2['rollers'][name] = {'index' : roller.index , # 'history' : roller.history , # 'dice_qty' : roller.dice_qty .get(), # 'die_faces': roller.die_faces.get(), # 'modifier' : roller.modifier .get(), # 'finalmod' : roller.finalmod .get()} # name = group.name.get() # if name in d1: # name += '!' # d1[name] = d2 # # with open(fpath, 'w') as f: # f.write(dumps(d1, indent=2, separators=(',', ': '))) self.set_saved_title(fpath) def __init__(self, master): Frame.__init__(self, master) self.master = master self.always_on_top = BooleanVar() self.set_defaults() self.menubar = Menu(master) self.list_index = 0 self.list_selected_index = 0 self.filemenu = Menu(self.menubar, tearoff=0) self.filemenu.add_command(label='New', underline=0, command=self.add_character, accelerator='Ctrl+N') self.filemenu.add_command(label='Remove', underline=0, command=self.remove_character, accelerator='Ctrl+R') self.filemenu.add_command(label='Load', underline=0, command=self.load_config, accelerator='Ctrl+L') self.filemenu.add_separator() # ------------------ self.filemenu.add_command( label='Save', underline=0, command=lambda: self.save_config(fpath=self.fpath), accelerator='Ctrl+S') self.editmenu = Menu(self.menubar, tearoff=0) self.editmenu.add_checkbutton(label='Always on top', underline=10, variable=self.always_on_top, command=self.pin) self.menubar.add_cascade(label='Characters', underline=0, menu=self.filemenu) self.menubar.add_cascade(label='Config', underline=0, menu=self.editmenu) self.menubar.config(relief='flat') master.config(menu=self.menubar) self.bind_all('<Control-n>', lambda e: self.add_character()) self.bind_all('<Control-r>', lambda e: self.remove_character()) self.bind_all('<Control-s>', lambda e: self.save_config(fpath=self.fpath)) self.bind_all('<Control-l>', lambda e: self.load_config()) # gives weight to the cells in the grid master.grid() rows = 0 while rows < 50: master.rowconfigure(rows, weight=1) master.columnconfigure(rows, weight=1) rows += 1 self.tabControl = ttk.Notebook(master) # Defines and places the notebook widget self.tabControl.grid(row=1, column=0, columnspan=25, rowspan=49, sticky='NESW') # Adds tab 1 of the notebook page1 = ttk.Frame(self.tabControl) page1.pack(side=LEFT, expand=1, fill="both", padx=5, pady=5) self.tabControl.add(page1, text='Initiative') self.add_button = Button(page1, text="Add Char", fg="black", command=self.add_character) delete_button = Button(page1, text="Delete Char", fg="black", command=self.remove_character) self.roll_button = Button(page1, text="Roll Dice", fg="black", command=self.roll_initiative) clear_button = Button(page1, text="Clean", fg="black", command=self.remove_all_characters) self.next_button = Button(page1, text="Next Char", fg="black", command=self.next_character) # greenbutton.place(x = 20, y = 30, width=120, height=25) # greenbutton1.place(x = 20, y = 60, width=120, height=25) self.tree = ttk.Treeview(page1, selectmode=BROWSE, columns=("life", "one")) self.tree.column("#0", width=250, minwidth=250, stretch=True) self.tree.column("life", width=40, minwidth=40, stretch=True) self.tree.column("one", width=70, minwidth=70, stretch=True) self.tree.heading("#0", text="Character", anchor="w") self.tree.heading("life", text="HP", anchor="w") self.tree.heading("one", text="Initiative", anchor="w", command=lambda _col="one": self.treeview_sort_column( self.tree, _col, True)) # self.tree.pack(side=TOP, fill=X) self.add_button.pack(side=LEFT, padx=5, pady=5, anchor="s") delete_button.pack(side=LEFT, padx=5, pady=5, anchor="s") self.roll_button.pack(side=LEFT, padx=5, pady=5, anchor="s") clear_button.pack(side=LEFT, padx=5, pady=5, anchor="s") self.next_button.pack(side=LEFT, padx=5, pady=5, anchor="s") self.next_button["state"] = "disabled" self.roll_button["state"] = "disabled" # Adds tab 2 of the notebook page2 = ttk.Frame(self.tabControl) self.tabControl.add(page2, text='Characters') # Adds tab 2 of the notebook page3 = ttk.Frame(self.tabControl) self.tabControl.add(page3, text='Monsters') monsterList = self.load_monster_name() selectButton = Button(page3, text='Select', underline=0, command=self.selection) scrollbar = Scrollbar(page3, orient=VERTICAL) self.search_var = StringVar() self.search_var.trace("w", lambda name, index, mode: self.update_list()) self.listBoxFilter = Entry(page3, textvariable=self.search_var, width=13) self.monsterListBox = Listbox(page3, yscrollcommand=scrollbar.set) scrollbar.config(command=self.monsterListBox.yview) scrollbar.pack(side=RIGHT, fill=Y) self.listBoxFilter.pack(side=TOP, padx=5, pady=5, anchor="n") selectButton.pack(side=TOP, padx=5, pady=5, anchor="n") self.monsterListBox.pack(side=TOP, fill=BOTH, expand=1) for item in monsterList: self.monsterListBox.insert(END, item) self.monsterListBox.bind('<Double-1>', lambda x: selectButton.invoke()) #html_label = HtmlFrame(page3, horizontal_scrollbar="auto", vertical_scrollbar=True) #html_label.pack(fill="both", expand=True) #html_label.set_content(self.html) # Adds tab 2 of the notebook page4 = ttk.Frame(self.tabControl) self.tabControl.add(page4, text='Spells') # Adds tab 2 of the notebook page5 = ttk.Frame(self.tabControl) self.tabControl.add(page5, text='Rules') def treeview_sort_column(self, tv, col, reverse): l = [(tv.set(k, col), k) for k in tv.get_children('')] l.sort(reverse=reverse) # rearrange items in sorted positions for index, (val, k) in enumerate(l): tv.move(k, '', index) # reverse sort next time #tv.heading(col, command=lambda: self.treeview_sort_column(tv, col, not reverse)) def selection(self): try: self.load_monster(self.monsterListBox.selection_get()) self.wm = popupWindowMonster(self.master) #self.popupmsg(self.monsterListBox.selection_get(), self.html) except: pass def update_list(self): search_term = self.search_var.get() monsterList = self.load_monster_name() self.monsterListBox.delete(0, END) for item in monsterList: if search_term.lower() in item.lower(): self.monsterListBox.insert(END, item)
class OptimizerMainWindow: """ classdocs """ # TODO: change that name def reactToClick(self, event): a = AddRestrictionDialog(self) def __init__(self, optimizer): # always have a reference to model/controller self.optimizer = optimizer # setup main GUI and make stretchable self.guiRoot = Tk() self.guiRoot.title("OPTIMIZR") self.guiRoot.columnconfigure(1, weight=1) self.guiRoot.rowconfigure(0, weight=1) # left (settings) and right (sequences) part self.frameLeft = Frame(self.guiRoot) self.frameLeft.grid(row=0, column=0, sticky=W + E + N + S) self.frameLeft.columnconfigure(0, weight=1) self.frameRight = Frame(self.guiRoot) self.frameRight.grid(row=0, column=1, sticky=W + E + N + S) self.frameRight.columnconfigure(0, weight=1) self.frameRight.rowconfigure(0, weight=1) self.frameRight.rowconfigure(1, weight=1) self.frameSpeciesControll = LabelFrame(self.frameLeft, text="Species", pady=10, padx=10) self.frameSpeciesControll.columnconfigure(1, weight=1) self.frameOptimizationControll = LabelFrame(self.frameLeft, text="Optimization", pady=10, padx=10) self.frameRestrictionControll = LabelFrame(self.frameLeft, text="Restriction Enzymes", pady=10, padx=10) self.frameSpeciesControll.grid(row=0, column=0, sticky=W + E, padx=10, pady=10) self.frameOptimizationControll.grid(row=1, column=0, sticky=W + E, padx=10, pady=10) self.frameRestrictionControll.grid(row=2, column=0, sticky=W + E, padx=10, pady=10) # Species Controll Label(self.frameSpeciesControll, text="Source:").grid(row=0, column=0) Label(self.frameSpeciesControll, text="Target:").grid(row=1, column=0) self.comboSourceSpecies = Combobox(self.frameSpeciesControll, state="readonly") self.comboSourceSpecies.grid(row=0, column=1, pady=5, sticky="ew") self.comboTargetSpecies = Combobox(self.frameSpeciesControll, state="readonly") self.comboTargetSpecies.grid(row=1, column=1, pady=5, sticky="we") self.buttonSpeciesList = Button(self.frameSpeciesControll, text="Edit Species List") self.buttonSpeciesList.grid(row=2, column=1, pady=5, sticky="e") self.comboSourceSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) self.comboTargetSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) # Optimization Controll Label(self.frameOptimizationControll, text="Optimization Strategy:").grid(row=0, column=0) self.comboOptimizationStrategy = Combobox(self.frameOptimizationControll, state="readonly") self.comboOptimizationStrategy.grid(row=0, column=1) self.comboOptimizationStrategy["values"] = self.optimizer.possibleOptimizationStrategies self.comboOptimizationStrategy.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged) # Restriction Enzymes self.listRestriction = Listbox(self.frameRestrictionControll) self.listRestriction.grid(row=0, column=0, columnspan=3, pady=5, sticky=W + E) self.frameRestrictionControll.columnconfigure(0, weight=1) self.buttonRestricionAdd = Button(self.frameRestrictionControll, text=" + ") self.buttonRestricionDel = Button(self.frameRestrictionControll, text=" - ") self.buttonRestricionAdd.grid(row=1, column=1, padx=5) self.buttonRestricionDel.grid(row=1, column=2, padx=5) # Source Sequence Frame self.frameSourceSequence = LabelFrame(self.frameRight, text="Source Sequence", padx=10, pady=10) self.frameResultSequence = LabelFrame(self.frameRight, text="Result Sequence", padx=10, pady=10) self.frameSourceSequence.grid(row=0, column=0, sticky="wens", padx=10, pady=10) self.frameResultSequence.grid(row=1, column=0, sticky="wens", padx=10, pady=10) self.buttonSourceLoad = Button(self.frameSourceSequence, text=" Load ") self.textSourceSeq = ScrolledText(self.frameSourceSequence, height=10) self.buttonSourceLoad.grid(row=0, column=1, sticky="e", pady=5) self.textSourceSeq.grid(row=1, column=0, columnspan=2, sticky="wens") self.frameSourceSequence.columnconfigure(0, weight=1) self.frameSourceSequence.rowconfigure(1, weight=1) self.textSourceSeq.frame.columnconfigure(1, weight=1) self.textSourceSeq.frame.rowconfigure(0, weight=1) self.buttonOptimize = Button(self.frameResultSequence, text=" OPTIMIZE! ") self.buttonOptimize.bind("<ButtonRelease>", self.actionOptimize) self.buttonRemoveRestriction = Button(self.frameResultSequence, text=" RESTRICTION-B-GONE! ") self.buttonRemoveRestriction.bind("<ButtonRelease>", self.actionRemoveRestricion) self.buttonSaveResult = Button(self.frameResultSequence, text=" Save ") self.textResultSequence = ScrolledText(self.frameResultSequence, height=10) self.buttonOptimize.grid(column=0, row=0, pady=5, sticky="w") self.buttonRemoveRestriction.grid(column=1, row=0, pady=5, padx=10, sticky="w") self.textResultSequence.grid(row=1, column=0, columnspan=4, sticky="wens") self.buttonSaveResult.grid(row=2, column=3, pady=5, sticky="e") self.frameResultSequence.columnconfigure(2, weight=1) self.frameResultSequence.rowconfigure(1, weight=1) self.textResultSequence.frame.columnconfigure(1, weight=1) self.textResultSequence.frame.rowconfigure(0, weight=1) self.textSourceSeq.bind("<<Modified>>", self.actionSequenceModified) self.textResultSequence.bind("<<Modified>>", self.actionSequenceModified) # generate color tags for textboxes for i in range(101): # green for normal codons (r, g, b) = colorsys.hsv_to_rgb(210 / 360, i / 100, 1.0) colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255)) self.textSourceSeq.tag_config("normal" + str(i), background=colorHex) self.textResultSequence.tag_config("normal" + str(i), background=colorHex) # red for codons with restriction sites (r, g, b) = colorsys.hsv_to_rgb(5 / 360, i / 100, 1.0) colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255)) self.textSourceSeq.tag_config("restrict" + str(i), background=colorHex) self.textResultSequence.tag_config("restrict" + str(i), background=colorHex) # Set (minimum + max) Window size self.guiRoot.update() self.guiRoot.minsize(self.guiRoot.winfo_width(), self.guiRoot.winfo_height()) self.buttonRestricionAdd.bind("<ButtonRelease>", self.reactToClick) self.buttonRestricionDel.bind("<ButtonRelease>", self.actionRestrictionEnzymeDelete) self.buttonSpeciesList.bind("<ButtonRelease>", self.actionEditSpeciesButton) self.buttonSourceLoad.bind("<ButtonRelease>", self.actionLoadSequence) self.buttonSaveResult.bind("<ButtonRelease>", self.actionSaveSequence) # TEST # self.listRestriction.insert("end", "EcoRI") # self.listRestriction.insert("end", "BamHI") # # dummy event to manually trigger update self.guiRoot.bind("<<Update>>", self.actionUpdate) self.actionUpdate(None) self.guiRoot.mainloop() def actionRestrictionEnzymeDelete(self, event): try: selectedEnzyme = self.listRestriction.selection_get() self.optimizer.restrictionEnzymeList.remove(selectedEnzyme) self.guiRoot.event_generate("<<Update>>") except tkinter.TclError: # no selection pass def actionUpdate(self, event): # print("update called") # clear list of restriction enzymes self.listRestriction.delete(0, "end") for r in self.optimizer.restrictionEnzymeList: self.listRestriction.insert("end", r) self.comboSourceSpecies.delete(0, "end") self.comboTargetSpecies.delete(0, "end") speciesValues = list() for (taxid, name) in self.optimizer.speciesList: speciesValues.append(taxid + ": " + name) self.comboSourceSpecies["values"] = speciesValues self.comboTargetSpecies["values"] = speciesValues if self.comboSourceSpecies.get() not in speciesValues: self.comboSourceSpecies.set("") if self.comboTargetSpecies.get() not in speciesValues: self.comboTargetSpecies.set("") self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) self.optimizer.saveConfig("config.ini") def actionEditSpeciesButton(self, event): speciesListDialog = SpeciesListDialog(self) def actionOptimizerSettingsChanged(self, event=None): # print("Something happened") strategy = self.comboOptimizationStrategy.get() sourceString = self.comboSourceSpecies.get() targetString = self.comboTargetSpecies.get() if not (strategy and sourceString and targetString): return sourceTaxid = sourceString.split(":")[0] targetTaxid = targetString.split(":")[0] self.optimizer.setOptimizer(sourceTaxid, targetTaxid, strategy) self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) # self.optimizer.testPrint() def actionOptimize(self, event=None): self.optimizer.runOptimization() self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) def actionRemoveRestricion(self, event=None): self.optimizer.runRestricionRemoval() self.textSourceSeq.edit_modified(True) self.textResultSequence.edit_modified(True) def actionSequenceModified(self, event=None): # necessary if, otherwise -> infinite loop if self.textSourceSeq.edit_modified(): seq = self.textSourceSeq.get("1.0", "end").strip() seq = stripCharsNotInList(seq.upper(), ["A", "C", "G", "T"]) self.optimizer.setSourceSeq(seq) oldInsert = self.textSourceSeq.index("insert") self.textSourceSeq.delete("1.0", "end") sourceCodons = self.optimizer.getCodonsForPrint(True) if not sourceCodons: self.textSourceSeq.insert("end", self.optimizer.sourceSequence) else: for (co, sc, r) in sourceCodons: if sc: if not r: self.textSourceSeq.insert("end", co, "normal" + str(int(sc * 100))) # print("normal"+str(int(sc*100))) else: self.textSourceSeq.insert("end", co, "restrict" + str(int(sc * 100))) else: # remainder without color self.textSourceSeq.insert("end", co) self.textSourceSeq.mark_set("insert", oldInsert) # reset the modified status at the very end self.textSourceSeq.edit_modified(False) if self.textResultSequence.edit_modified(): seq = self.textResultSequence.get("1.0", "end").strip() # self.optimizer.setOptimizedSeq(seq) oldInsert = self.textResultSequence.index("insert") self.textResultSequence.delete("1.0", "end") targetCodons = self.optimizer.getCodonsForPrint(False) if not targetCodons: self.textSourceSeq.insert("end", self.optimizer.optimizedSequence) else: for (co, sc, r) in targetCodons: if sc: if not r: self.textResultSequence.insert("end", co, "normal" + str(int(sc * 100))) # print("normal"+str(int(sc*100))) else: self.textResultSequence.insert("end", co, "restrict" + str(int(sc * 100))) else: # remainder without color self.textResultSequence.insert("end", co) self.textSourceSeq.mark_set("insert", oldInsert) self.textResultSequence.edit_modified(False) def actionLoadSequence(self, event=None): filename = tkinter.filedialog.askopenfilename() if filename: seq = sequenceIO.readFile(filename) self.textSourceSeq.delete("1.0", "end") self.textSourceSeq.insert("end", seq) self.textSourceSeq.edit_modified(True) def actionSaveSequence(self, event=None): filename = tkinter.filedialog.asksaveasfilename() if filename: # print("file is " + filename) with open(filename, mode="w") as fd: fd.write(self.optimizer.optimizedSequence)
class ExclusionsSupp(Toplevel): """ list of paths that will be excluded from the suppression """ def __init__(self, master): Toplevel.__init__(self, master) self.protocol("WM_DELETE_WINDOW", self.quitter) self.columnconfigure(0, weight=1) self.columnconfigure(2, weight=1) self.rowconfigure(0, weight=1) self.title("Exclusions") self.transient(master) self.grab_set() self.last_path = "" # last opened path self.img_open = PhotoImage(file=IM_OPEN) self.img_doc = PhotoImage(file=IM_DOC) self.img_supp = PhotoImage(file=IM_SUPP) style = Style(self) style.configure("list.TFrame", background="white", relief="sunken") frame = Frame(self) frame.columnconfigure(0, weight=1) frame.rowconfigure(0, weight=1) frame.grid(row=0, columnspan=3, sticky="eswn", padx=10, pady=(10, 4)) listbox_frame = Frame(frame, borderwidth=1, style="list.TFrame") listbox_frame.columnconfigure(0, weight=1) listbox_frame.rowconfigure(0, weight=1) listbox_frame.grid(row=0, column=0, sticky="nswe") self.listvar = StringVar(self, value=CONFIG.get("Defaults", "exclude_supp")) self.exclude_list = split(r'(?<!\\) ', CONFIG.get("Defaults", "exclude_supp")) self.listbox = Listbox(listbox_frame, highlightthickness=0, listvariable=self.listvar) self.listbox.grid(sticky="eswn") scroll_x = Scrollbar(frame, orient="horizontal", command=self.listbox.xview) scroll_x.grid(row=1, column=0, sticky="ew") scroll_y = Scrollbar(frame, orient="vertical", command=self.listbox.yview) scroll_y.grid(row=0, column=1, sticky="ns") self.listbox.configure(xscrollcommand=scroll_x.set, yscrollcommand=scroll_y.set) Button(self, image=self.img_doc, command=self.add_doc).grid(row=1, column=0, sticky="e", padx=(10, 4), pady=(4, 10)) Button(self, image=self.img_open, command=self.add_dir).grid(row=1, column=1, padx=4, pady=(4, 10)) Button(self, image=self.img_supp, command=self.rem).grid(row=1, column=2, sticky="w", padx=(4, 10), pady=(4, 10)) self.geometry("500x400") def add_doc(self): try: path = self.listbox.selection_get() except TclError: # no item selected path = self.last_path docs = askfiles(path) if docs[0]: for d in docs: d = d.replace(" ", "\ ") if not d in self.exclude_list: self.exclude_list.append(d) self.last_path = dirname(docs[-1]) self.listvar.set(" ".join(self.exclude_list)) def add_dir(self): try: path = self.listbox.selection_get() except TclError: # no item selected path = self.last_path dirs = askdirectories(path) if dirs[0]: for d in dirs: d = d.replace(" ", "\ ") if not d in self.exclude_list: self.exclude_list.append(d) self.last_path = dirs[-1] self.listvar.set(" ".join(self.exclude_list)) def rem(self): sel = self.listbox.curselection() if sel: sel = sel[0] txt = self.listbox.get(sel) self.exclude_list.remove(txt.replace(" ", "\ ")) self.listbox.delete(sel) def quitter(self): CONFIG.set("Defaults", "exclude_supp", " ".join(self.exclude_list)) save_config() self.destroy()
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 Gui(Tk): """Gui window mostly built with grid layout. #####TOP##### #LEFT##RIGHT# ###BOTTOM#### """ def __init__(self, *args, **kwargs): Tk.__init__(self, *args, **kwargs) self.geometry('700x510+50+50') self.title('Notifier Beta') # Main Window container self.container = Frame(self, bg='white', width=660, height=460) self.container.grid(row=0, column=0, padx=20, pady=20, sticky='nesw') self.messages = defaultdict(dict) self.read_reminders() # LAYOUT WIDGET GRID self.window_top() self.window_left() self.window_right() self.window_bottom() # SEND EMAILS if any date matches TODAY if username is not '': notifier = DateChecker(self.messages) notifier.run() def create_json(self): """Create json file: messages.json """ with open('messages.json', 'w') as f: json.dump(self.messages, f, indent=4, sort_keys=True) def write_reminders(self, mydate, mytime, mymessage): """Grab the data from data_entry_var, time_entry_var, message_box and save them in messages.json. Update listbox with new reminders """ if mydate != 'DD/MM/YYYY' and mytime != 'HH:MM' and self.data_entry_var.get() != '' and self.time_entry_var.get() != '': self.messages[mydate.strip()] = { 'time':mytime.strip(), 'message':mymessage.strip(), } # Create json file self.create_json() self.list_box.delete(0, END) self.read_reminders() self.update_listbox() else: messagebox.showerror( 'Incorrect Input', 'Check if you inserted correct data format: "DD/MM/YYYY" or time format: "HH:MM"' ) def read_reminders(self): """Read the data from messages.json file and assign it to self.messages dictionary. """ # Check if messages.json exists, if not, create new empty file. if not JSON_FILE: with open('messages.json', 'w') as f: json.dump(self.messages, f) # load json file to self.messages dict. with open('messages.json', 'r') as f: self.messages = json.load(f) def update_fields(self, num): """Update fields when listbox is clicked """ if self.messages.keys(): data = self.messages.get(num) self.data_entry_var.set(num) self.time_entry_var.set(data['time']) self.message_box.delete('1.0', END) self.message_box.insert('1.0', data['message']) else: print('No reminders detected!') def update_listbox(self): """Create list of reminders inside listbox widget. List is taken from self.messages and is represented by the date of each reminder.""" for i, key in enumerate(sorted(self.messages.keys())): self.list_box.insert(i, key) def delete_record(self, num): """Activate when 'Delete Record' button is clicked. Deletes key from self.messages dictionary and creates new json file with updated/deletes keys Clears and updates listbox """ del self.messages[num] self.list_box.delete(0, END) self.time_entry_var.set('') self.data_entry_var.set('') self.message_box.delete('1.0', END) self.create_json() self.update_listbox() def window_top(self): """Displays the logo """ window_top = Frame(self.container, bg='white', width=660, height=50) window_top.grid(row=0, column=0, sticky='nesw', columnspan=2) label_title = Label(window_top, text=APP_NAME, font=(('Helvetica', 'bold'), '25'), bg='white', bd=2, relief='groove', width=14) label_title.grid(row=0, padx=20, pady=20) def validate_data(self, data): """Validate if user entered correct DATE format: DD/MM/YYYY. """ pattern = re.compile('^(\d{2}/\d{2}/\d{4})$') if pattern.match(data): self.data_entry_var.set(pattern.match(data).group(1)) else: self.data_entry_var.set('DD/MM/YYYY') def validate_time(self, mytime): """Validate if user entered correct TIME format: HH:MM. """ pattern = re.compile(r'^(([01]\d|2[0-3]):([0-5]\d)|24:00)$') if pattern.match(mytime): self.time_entry_var.set(pattern.match(mytime).group(1)) else: self.time_entry_var.set('HH:MM') def window_left(self): """Displays date field, time field, message box field, clear button and Add Notification button. Each field is validated before action is applied. """ window_left = Frame(self.container, bg='white', width=200, height=370) window_left.grid(row=1, column=0, sticky='nesw') # TIME & DATE time_date_window = Frame(window_left, bg='white', width=24) time_date_window.grid(row=0, column=0, sticky='we') time_date_window_title = Label(time_date_window, text='Date & Time:', font=WIDGET_FONT_TITLE, bg='white', bd=2, anchor='w') time_date_window_title.grid(row=0, column=0, padx=20, sticky='w') time_date_fields = Frame(time_date_window, bg='white') time_date_fields.grid(row=1, sticky='we', pady=10) date_field = Label(time_date_fields, text='Date:', font=APP_FONT, bg='white', bd=2, anchor='w') date_field.grid(row=0, column=0, padx=20, pady=5, sticky='w') self.data_entry_var = StringVar() date_entry = Entry(time_date_fields, textvariable=self.data_entry_var,width=14, font=APP_FONT) date_entry.grid(row=1, column=0, sticky='w', padx=20) date_entry.bind('<FocusOut>', lambda x: self.validate_data(self.data_entry_var.get())) time_field = Label(time_date_fields, text='Time:', font=APP_FONT, bg='white', bd=2, anchor='w') time_field.grid(row=0, column=1, padx=20, pady=5, sticky='w') self.time_entry_var = StringVar() time_entry = Entry(time_date_fields, textvariable=self.time_entry_var, width=15, font=APP_FONT) time_entry.grid(row=1, column=1, sticky='w', padx=20) time_entry.bind('<FocusOut>', lambda x: self.validate_time(self.time_entry_var.get())) # MESSAGE BOX message_box_title = Label(window_left, text='Message Box:', font=WIDGET_FONT_TITLE, bg='white', bd=2,anchor='w') message_box_title.grid(row=1, column=0, padx=20, sticky='w') self.message_box = Text(window_left, width=34, height=7, font=APP_FONT) self.message_box.grid(row=2, column=0, padx=(11,0)) # BUTTONS FRAME button_frame = Frame(window_left, bg='white') button_frame.grid(row=3, sticky='we', pady=(5,0)) # Submit button submit_button = Button(button_frame, text='Add Notification', command=lambda: self.write_reminders(self.data_entry_var.get(),self.time_entry_var.get(), self.message_box.get('1.0', END)), width=15) submit_button.pack(side=RIGHT, padx=20, pady=3) # Clear button clear_button = Button(button_frame, text='Clear', command=lambda: self.message_box.delete('1.0', END), width=10) clear_button.pack(side=RIGHT, pady=3) def window_right(self): """Displays reminder listbox widget where all valid reminders can be found. """ window_right = Frame(self.container, bg='white', width=200, height=370) window_right.grid(row=1, column=1, sticky='nesw') reminder_list_title = Label(window_right, text='Reminders:', font=WIDGET_FONT_TITLE, bg='white', bd=2, anchor='w') reminder_list_title.grid(row=0, column=0, padx=(0,20), sticky='w') self.list_box = Listbox(window_right, width=25, height=12, font=APP_FONT) self.list_box.grid(row=2, column=0, sticky='n', padx=(5,0)) self.list_box.bind('<<ListboxSelect>>', lambda x:self.update_fields(self.list_box.selection_get())) self.update_listbox() # Delete delete_record = Button(window_right, text='Delete Record', command=lambda: self.delete_record(self.list_box.selection_get()), width=10) delete_record.grid(row=3, column=0, padx=20, pady=(7,0), sticky='e') def window_bottom(self): window_bottom = Frame(self.container, bg='white', width=660, height=50) window_bottom.grid(row=2, column=0, sticky='nesw', columnspan=2) def run(self): """Starts main loop of the App. """ self.mainloop()
class SpeciesListDialog: def __init__(self, parent): self.parent = parent self.gui = Toplevel(parent.guiRoot) self.gui.grab_set() self.gui.focus() self.gui.columnconfigure(0, weight=1) self.gui.rowconfigure(1, weight=1) Label(self.gui, text="Registered Species:").grid(row=0, column=0, pady=5, padx=5, sticky="w") self.listRegisteredSpecies = Listbox(self.gui, width=70) self.buttonAdd = Button(self.gui, text=" + ") self.buttonDel = Button(self.gui, text=" - ") self.listRegisteredSpecies.grid(row=1, column=0, columnspan=3, sticky="nswe", pady=5, padx=5) self.buttonAdd.grid(row=2, column=1, pady=5, padx=5) self.buttonDel.grid(row=2, column=2, pady=5, padx=5) # Set (minimum + max) Window size self.gui.update() self.gui.minsize(self.gui.winfo_width(), self.gui.winfo_height()) # self.gui.maxsize(self.gui.winfo_width(), self.gui.winfo_height()) self.actionUpdate(None) self.gui.bind("<<Update>>", self.actionUpdate) self.gui.protocol("WM_DELETE_WINDOW", self.actionClose) self.buttonDel.bind("<ButtonRelease>", self.actionDel) self.buttonAdd.bind("<ButtonRelease>", self.actionAdd) self.gui.mainloop() def actionClose(self): self.parent.guiRoot.event_generate("<<Update>>", when="tail") self.gui.destroy() def actionUpdate(self, event): self.listRegisteredSpecies.delete(0, "end") for (taxid, name) in self.parent.optimizer.speciesList: self.listRegisteredSpecies.insert("end", taxid + ": " + name) def actionDel(self, event): try: selection = self.listRegisteredSpecies.selection_get() selectionSplit = selection.split(": ") self.parent.optimizer.speciesList.remove((selectionSplit[0], selectionSplit[1])) self.gui.event_generate("<<Update>>") except tkinter.TclError: # no selection pass def actionAdd(self, Event): SpeciesSearchDialog(self.parent, self)