def build_main_menu(self): """Generic menu bar.""" menu = Menu(self.root) # File dropdown menu file_menu = Menu(menu, tearoff=False) menu.add_cascade(label="File", underline=0, menu=file_menu) file_menu.add_command(label="Exit", underline=1, accelerator='alt+f4', command=lambda: self.root.destroy()) # Help dropdown menu help_menu = Menu(menu, tearoff=False) menu.add_cascade(label="Help", underline=0, menu=help_menu) help_menu.add_command(label="Contents", underline=0, command=self.show_help_contents) help_menu.add_command( label="About", underline=0, command=lambda: showinfo( title="About", message=PROG_TITLE, detail=ABOUT)) # end menu menu.config(bg=BG) self.root.config(menu=menu)
def CrearMenu(masterRoot): global tools ########### menu ############ #Se crea la barra barraDeMenu=Menu(masterRoot, tearoff=0,relief=FLAT, font=("Verdana", 12),activebackground='gray59') barraDeMenu.config(bg='gray21',fg='white') #Se crean los menus que se deseen archivo=Menu(barraDeMenu, tearoff=0,bg='gray21',fg='white',activebackground='gray59') #Crear las opciones de la opción del menú #Se elimino el comando de crear Ventana por problemas con las imagenes archivo.add_command(label="Nueva ventana") archivo.add_command(label="Abrir query",command=abrir) archivo.add_command(label="Abrir un modelo") archivo.add_separator() archivo.add_command(label="Nueva Query",command=lambda: añadir('Nuevo')) archivo.add_command(label="Guardar como...",command=guardarComo) archivo.add_command(label="Guardar",command=guardarArchivo) archivo.add_command(label="Cerrar pestaña actual",command=cerrarPestaña) archivo.add_separator() archivo.add_command(label="Salir",command=cerrarVentana) #creando el Editar editar=Menu(barraDeMenu,tearoff=0,bg='gray21',fg='white',activebackground='gray59') #agregando su lista editar.add_command(label="Cortar") editar.add_command(label="Pegar") editar.add_command(label="Copiar") editar.add_separator() editar.add_command(label="Seleccionar todo") editar.add_command(label="Formato") editar.add_command(label="Preferencias") #se agrega Tools tools=Menu(barraDeMenu, tearoff=0,bg='gray21',fg='white',activebackground='gray59') #se agrega su lista tools.add_command(label="Configuración") tools.add_command(label="Utilidades") tools.add_command(label="Limpiar consola", command = LimpiarConsola) #Temporary tools to test client-server connection tools.add_command(label="GET USERS", command = myGET) tools.add_command(label="CREATE USER", command = crearUsuario) #Log In sera parte de la barra de herramientas tools.add_command(label="LOGIN", command = LogIn) #se agrega ayuda ayuda=Menu(barraDeMenu, tearoff=0,bg='gray21',fg='white',activebackground='gray59') #lista de ayuda ayuda.add_command(label="Documentación de TytuSQL") ayuda.add_command(label="Acerca de TytuSQL") #Se agrgan los menús a la barra barraDeMenu.add_cascade(label="Archivo",menu=archivo) barraDeMenu.add_cascade(label="Editar",menu=editar) barraDeMenu.add_cascade(label="Herramientas",menu=tools) barraDeMenu.add_cascade(label="Ayuda",menu=ayuda) #Se indica que la barra de menú debe estar en la ventana return barraDeMenu
def __init__(self, _master_: Tk): super().__init__(_master_) self._master = _master_ font = ("Courier", 44) menu = Menu(self.master) self.master.config(menu=menu) file = Menu(menu, tearoff=0) file.add_command(label="Exit", command=self._exit) menu.add_cascade(label="File", menu=file) menu.config(font=font) edit = Menu(menu, tearoff=0) edit.add_command(label="Undo") menu.add_cascade(label="Edit", menu=edit) pass
def main(): global root root.title("Online Coloring") root.geometry("1000x800") root.config(bg="purple") menu_bar = Menu(root) file_menu = Menu(menu_bar, tearoff=0) file_menu.add_command(label="Add Image!", command=openFile) file_menu.add_command(label="Save Image!", command=AskSaveasFilename) file_menu.add_command(label="End!", command=root.destroy) file_menu.add_command(label="Change Colour", command=change_colour) menu_bar.add_cascade(label="File", menu=file_menu) root.config(menu=menu_bar) file_menu.config(bg="green") pickColor = Button(root, text='Pick Color', command=getColor) pickColor.grid(row=300, column=300) pickColor.config(bg="gray") root.mainloop()
def initUI(self): self.parent.title("Gas Model") self.fonts = {'fontname' : 'Helvetica', 'color' : 'r', 'fontweight' : 'bold', 'fontsize' : 14} self.npts = 32; self.sounds = 377.9683; self.skip = 4000. # self.dt = 5000.*self.skip/(self.npts * self.sounds) menubar = Menu(self.parent) menubar.config(font=("Helvetica", 14, "italic")) self.parent.config(menu=menubar) fileMenu = Menu(menubar, tearoff=0) fileMenu.config(font=("Helvetica", 14, "italic")) fileMenu.add_command(label="Load", command=self.onLoad) fileMenu.add_command(label="Close", command=self.onClose) fileMenu.add_command(label="Exit", command=self.quit) menubar.add_cascade(label="File", menu=fileMenu) fileMenu2 = Menu(menubar, tearoff=0) fileMenu2.config(font=("Helvetica", 14, "italic")) fileMenu2.add_command(label="Set Parameters", command=self.quit) menubar.add_cascade(label="Parameters", menu=fileMenu2) lbl1=Label(self.parent,text="Gas Network",fg = "black",font=("Helvetica", 14, "bold")) lbl1.grid(sticky="N",pady=4,padx=5,row=0,column=0,columnspan=2) self.f = plt.figure(figsize=(5,4), dpi=80) self.cmap = plt.cm.jet #ok self.a = self.f.add_subplot(111) self.a.axis([-1, 1, -1, 1]) self.a.axis('off') self.canvas = FigureCanvasTkAgg(self.f, master=self.parent) self.G = nx.Graph() nx.draw_networkx(self.G, pos=nx.spring_layout(self.G), ax=self.a) self.canvas.show() self.canvas.get_tk_widget().config(width=800-20, height=600-100) self.canvas.get_tk_widget().grid(sticky="NW", pady=4, padx=5, row=1, column=0, columnspan=6, rowspan=6) self.txt = Text(self.parent, width=54, height=33); self.txt.grid(sticky="NW", pady=4, padx=5, row=1, column=8, columnspan=4, rowspan=6) self.log = Text(self.parent, width=112, height=6); self.log.grid(sticky="NW", pady=4, padx=5, row=7, column=0, columnspan=6,rowspan=2) RunButton = Button(self.parent, text="Run", width=10, command=self.onRun).grid(sticky='SW', pady=4, padx=5, row=7, column=8) DrawButton = Button(self.parent, text="Draw", width=10, command=self.onDraw).grid(sticky='SW', pady=4, padx=5, row=7, column=9) StopButton = Button(self.parent, text="Stop", width=10, command=self.onStop).grid(sticky='SW', pady=4, padx=5, row=8, column=9) QuitButton = Button(self.parent, text="Quit", width=10, command=self.quit ).grid(sticky='SW', pady=4, padx=5, row=7, column=10) self.Loaded = False self.Animate = False
def __init__(self, master): error_msg = "Ensure S3 is configured on your machine:" try: self.s3 = boto3.resource('s3') except Exception as e: print("%s: %s" % (error_msg, e)) exit(1) try: self.s3c = boto3.client('s3') except Exception as err: print("%s: %s" % (error_msg, err)) exit(1) self.colors = { 'light-grey': '#D9D9D9', 'blue': '#2B547E', 'black': '#000000', 'red': '#FF3346', 'grey': '#262626', 'cyan': '#80DFFF' } self.master = master self.master.title("Amazon S3 File Transfer Client") self.master.configure(bg=self.colors['grey']) self.master.geometry("885x645") menu = Menu(self.master) menu.config(background=self.colors['grey'], fg=self.colors['light-grey']) self.master.config(menu=menu) file = Menu(menu) file.add_command(label="Exit", command=self.quit) menu.add_cascade(label="File", menu=file) refresh = Menu(menu) refresh.add_command(label="Local", command=self.refresh_local) refresh.add_command(label="S3", command=self.refresh_s3) menu.add_cascade(label="Refresh", menu=refresh) self.dir, self.drp_sel, self.bucket_name = '', '', '' self.folder_path = StringVar() self.dropdown = StringVar() self.dropdown_data = self.populate_dropdown() if not self.dropdown_data: self.dropdown_data = ['none available'] self.deleted = False self.local_sel, self.s3_sel = ([] for i in range(2)) self.title_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], font="Helvetica 10 bold", width=120) self.local_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="LOCAL FILE SYSTEM", font="Helvetica 10 bold underline", width=60) self.s3_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="AMAZON S3", font="Helvetica 10 bold underline", underline=True, width=60) self.dropdown_box = OptionMenu(master, self.dropdown, *self.dropdown_data, command=self.set_drop_val) self.dropdown_box.configure(fg=self.colors['light-grey'], bg=self.colors['blue'], width=27, highlightbackground=self.colors['black'], highlightthickness=2) self.browse_button = Button(master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="Browse", width=30, highlightbackground=self.colors['black'], highlightthickness=2, command=self.load_dir) self.browse_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="No directory selected", width=37, font="Helvetica 10") self.bucket_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="No bucket selected", width=37, font="Helvetica 10") self.refresh_btn_local = Button( master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="REFRESH", width=30, highlightbackground=self.colors['black'], highlightthickness=2, command=self.refresh_local) self.refresh_btn_s3 = Button(master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="REFRESH", width=30, highlightbackground=self.colors['black'], highlightthickness=2, command=self.refresh_s3) self.explorer_label_local = Label(master, fg=self.colors['light-grey'], bg=self.colors['blue'], width=30, text="Local File System: ") self.explorer_label_s3 = Label(master, fg=self.colors['light-grey'], bg=self.colors['black'], width=30, text="S3 File System") self.ex_loc = Listbox(master, fg=self.colors['cyan'], bg=self.colors['black'], width=49, height=18, highlightcolor=self.colors['black'], selectmode="multiple") self.ex_s3 = Listbox(master, fg=self.colors['cyan'], bg=self.colors['black'], width=49, height=18, highlightcolor=self.colors['black'], selectmode="multiple") self.upload_button = Button(master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="Upload ->", width=20, highlightbackground=self.colors['black'], highlightthickness=2, command=self.upload) self.download_button = Button(master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="<- Download", width=20, highlightbackground=self.colors['black'], highlightthickness=2, command=self.download) self.delete_local = Button(master, fg=self.colors['light-grey'], bg=self.colors['red'], text="DELETE", width=20, highlightbackground=self.colors['black'], command=self.delete_local_records) self.delete_s3 = Button(master, fg=self.colors['light-grey'], bg=self.colors['red'], text="DELETE", width=20, highlightbackground=self.colors['black'], command=self.delete_s3_records) self.found_label_local = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="found local", width=54) self.found_label_s3 = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="found s3", width=54) self.status_label = Label(master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="Hello " + getuser(), width=54) self.create_bucket_label = Label( master, fg=self.colors['light-grey'], bg=self.colors['grey'], text="New Bucket:", ) self.create_bucket_name = Text(master, fg=self.colors['cyan'], bg=self.colors['black'], width=25, height=1) self.create_bucket_button = Button( master, fg=self.colors['light-grey'], bg=self.colors['blue'], text="Create", width=5, highlightbackground=self.colors['black'], highlightthickness=2, command=self.create_bucket) # ####### begin grid placement ####### # self.title_label.grid(row=0, sticky=E + W, padx=20, pady=5) self.local_label.grid(row=0, sticky=W, padx=8, pady=5) self.s3_label.grid(row=0, sticky=E, padx=0, pady=5) self.browse_button.grid(row=1, sticky=W, padx=86, pady=10) self.dropdown_box.grid(row=1, sticky=E, padx=86, pady=5) self.browse_label.grid(row=2, sticky=W, padx=86, pady=5) self.bucket_label.grid(row=2, sticky=E, padx=86, pady=5) self.refresh_btn_local.grid(row=3, sticky=W, padx=86, pady=10) self.refresh_btn_s3.grid(row=3, sticky=E, padx=86, pady=10) self.explorer_label_local.grid(row=4, sticky=W, padx=20) self.explorer_label_s3.grid(row=4, sticky=E, padx=20) self.ex_loc.grid(row=4, sticky=W, padx=20) self.ex_s3.grid(row=4, sticky=E, padx=20) self.upload_button.grid(row=5, sticky=W, padx=224, pady=0) self.download_button.grid(row=5, sticky=E, padx=224, pady=0) self.delete_local.grid(row=5, sticky=W, padx=20, pady=0) self.delete_s3.grid(row=5, sticky=E, padx=20, pady=0) self.found_label_local.grid(row=6, sticky=W, padx=0, pady=20) self.found_label_s3.grid(row=6, sticky=E, padx=0, pady=20) self.status_label.grid(row=7, sticky=W, padx=0, pady=20) self.create_bucket_label.grid(row=7, sticky=E, padx=330, pady=0) self.create_bucket_name.grid(row=7, sticky=E, padx=100, pady=0) self.create_bucket_button.grid(row=7, sticky=E, padx=20, pady=0) n1 = "%s files found" % str(self.ex_loc.size()) self.set_found_local_label(n1) n2 = "%s files found" % str(self.ex_s3.size()) self.set_found_s3_label(n2)
class TkMemobook(Memobook): '''Memobook Tk frontend''' root = None tabs = None menu = None offset = None def __init__(self, **kwargs): dprint(3, "\nTkMemobook::__init__::") Memobook.__init__(self, **kwargs) self.offset = [] if "root" in kwargs.keys(): self.root = kwargs["root"] else: self.root = Tk() ### setting theme is inexplicably only affecting Book and the file-open dialogue, ### nothing else. Setting theme of, e.g., self.menu also isn't working. #self.root.style = Style() #self.root.style.theme_use(self.ctrl["style"]["theme"]) self.root.title("Memobook") # adjust Tk's font sizes according to conf.xml "style" section. # Positive value in conf.xml is an increase in size, negative a decrease for name in font.names(): tk_font = font.nametofont(name) new_size = tk_font["size"] - int(self.ctrl["style"]["font"]["size"]) tk_font.configure(size=new_size) # deal with hidden files for file dialogue by calling a dummy dialogue with nonsense options: (method taken from online forum) # (this is done here and not in binding class because it is a front-end matter, not a back-end one) try: self.root.tk.call('tk_getOpenFile', '-flurpee') except TclError: #catch and discard the TclError that the nonsense option caused pass finally: self.root.tk.call('set', '::tk::dialog::file::showHiddenBtn', '1') self.root.tk.call('set', '::tk::dialog::file::showHiddenVar', '0') if "tabs" in kwargs.keys(): self.tabs = kwargs["tabs"] else: self.tabs = Book(self.root, ruling=self.ctrl, width=self.ctrl["x"], height=self.ctrl["y"]) #self.tabs.ruling(self.ctrl) #if ruling is not specified in constructor call, it must be done so here self.tabs.set_save_hook(lambda:self.save_note()) self.tabs.set_close_hook(lambda:self.close_page()) self.tabs.bind("<Double-Button-1>", lambda e: self.tabs.newpage(None)) self.menu = Menu(self.root) self.set_bindings() dprint(3, "Tk initialization complete. Displaying...") self.tabs.grid_columnconfigure(0, weight=1) self.tabs.grid_rowconfigure(0, weight=1) self.tabs.grid(sticky="nswe") self.populate_menus() self.root.config(menu=self.menu) self.root.grid_columnconfigure(0, weight=1) self.root.grid_rowconfigure(0, weight=1) self.offset = [ self.tabs.winfo_reqwidth()-int(self.ctrl["x"]), self.tabs.winfo_reqheight()-int(self.ctrl["y"]) ] def populate_menus(self): '''Populate menus using Tk library''' dprint(3, "\nTkMemobook::populate_menus:: ") mdict = { Heading.MF:Menu(self.menu, tearoff=0), Heading.ME:Menu(self.menu, tearoff=0), Heading.MS:Menu(self.menu, tearoff=0), Heading.MH:Menu(self.menu, tearoff=0) } for k in mdict: self.menu.add_cascade(label=k.value, menu=mdict[k]) mdict[Heading.MF].add_command(label="New", command=lambda: self.tabs.newpage(None)) mdict[Heading.MF].add_command(label="Open by mark", command=lambda: self.__open_mark()) mdict[Heading.MF].add_command(label="Open from file", command=lambda: self.open_file()) mdict[Heading.MF].add_command(label="Save", command=lambda: self.save_note()) mdict[Heading.MF].add_command(label="Save as", command=lambda: self.save_note_as()) mdict[Heading.MF].add_separator() mdict[Heading.MF].add_command(label="New tab", command=lambda: self.tabs.newpage(None)) mdict[Heading.MF].add_command(label="Close tab", command=lambda: self.close_page()) mdict[Heading.MF].add_command(label="Close all tabs", command=lambda: self.close_all()) mdict[Heading.MF].add_separator() mdict[Heading.MF].add_command(label="Quit", command=lambda: self.exit_all(None)) mdict[Heading.ME].add_command(label="Find/Replace", command=lambda: self.tabs.toggle_search("start")) mdict[Heading.ME].add_command(label="Edit marks", command=lambda: self.mark_dialogue()) mdict[Heading.ME].add_command(label="Font", command=lambda: self.font_dialogue()) mdict[Heading.ME].add_separator() mdict[Heading.ME].add_command(label="Toggle tab wrap", command=lambda: self.tabs.togglewrap()) mdict[Heading.ME].add_checkbutton(label="Toggle global wrap", onvalue="word", offvalue="none", variable=self.ctrl["wrap"], command=lambda: self.tabs.togglewrapall()) mdict[Heading.MS].add_command(label="Scan", command=lambda: self.__get_busy_with(None,self.data.populate)) mdict[Heading.MS].add_command(label="Clear", command=lambda: self.data.clear()) mdict[Heading.MS].add_command(label="Manage locations", command=lambda: self.open_pop(self.__open_pop_remove, self.__open_pop_add, self.__open_pop_apply)) mdict[Heading.MH].add_command(label="About", command=lambda: self.publication_info()) def set_bindings(self): '''Bind methods to keystrokes''' dprint(3, "\nTkMemobook::set_bindings:: ") self.root.protocol("WM_DELETE_WINDOW", lambda: self.exit_all(None)) self.root.bind("<Control-f>", lambda e: self.tabs.toggle_search()) self.root.bind("<Control-q>", lambda e: self.exit_all(None)) self.root.bind("<Control-w>", lambda e: self.close_page()) self.root.bind("<Control-n>", lambda e: self.tabs.newpage(None)) self.root.bind("<Control-s>", lambda e: self.save_note()) self.root.bind("<Alt-m>", lambda e: self.mark_dialogue()) def __open_mark(self): '''Open files by mark: Major dialogue for mark choices and logic''' ### despite using select, invoke, focus_set, event_generate, ### tk wouldn't set the OR radiobutton as default. ### So the following sub-function is a workaround to force the issue. def default_selection(var): var.set("or") def lookup(toc,gl,word): l = len(word) for i, item in enumerate(toc): if item.find(word,0,l) > -1: gl.see(i) break dprint(3, "\nTkMemobook::open_mark:: ") toc = [ item for item in self.data.toc() ] toc.sort(key=lambda x: x.lower()) getter = Toplevel(self.root) getter_list = ListboxHV(getter, selectmode="multiple") for item in toc: getter_list.insert(END, item) getter_list.pack(fill="both", expand="true") quick_var = StringVar() quick_var.trace_add("write", lambda i,j,k: lookup(toc,getter_list,quick_var.get())) quick_frame = Frame(getter) quick_label = Label(quick_frame, text="Quick lookup:") quick_enter = Entry(quick_frame, textvariable=quick_var, width=24) quick_label.pack(side="left") quick_enter.pack(side="left") button_frame = Frame(getter) logic_variable = StringVar(None, "or") radiobutt_OR = Radiobutton(button_frame, text="OR", variable=logic_variable, command=lambda: default_selection(logic_variable), # get tk to give default selection value="or") radiobutt_AND = Radiobutton(button_frame, text="AND", variable=logic_variable, value="and") retbutt = Button(button_frame, text="Apply", command=lambda: self.__open_mark_confirm(getter, [ toc[int(j)] for j in getter_list.curselection() ], logic_variable.get())) cancbutt = Button(button_frame, text="Cancel", command=lambda: getter.destroy()) radiobutt_OR.pack(side="left") radiobutt_AND.pack(side="left") cancbutt.pack(side="left") retbutt.pack(side="left") button_frame.pack(side="bottom") quick_frame.pack(side="bottom") radiobutt_OR.invoke() def __open_mark_confirm(self, win, ls, logic): '''Open files by mark: Minor dialogue for confirming file selection if 2+ files were found''' def launch(choices): if choices: for note in choices: self.tabs.newpage(note) chooser.destroy() win.destroy() dprint(3, "\nTkMemobook::__open_mark_confirm:: ") if ls: if logic == "or": notes = self.__get_busy_with(win, self.data.open_from_toc, ls) elif logic == "and": notes = self.__get_busy_with(win, self.data.open_from_toc_intersection, ls) else: notes = [] if not notes: last = self.data.get_last_error() if last: messagebox.showinfo("Open error", "Unable to open file(s): " + str(last)) else: failure = ", ".join(ls) if logic == "or": messagebox.showinfo("Open failure", "Unable to find files for any of the following marks: " + failure) else: messagebox.showinfo("Open failure", "Unable to find files containing each of the following marks: " + failure) else: if len(notes) == 1: self.tabs.newpage(notes[0]) win.destroy() return notes.sort(key=lambda x: str(os.path.basename(x.ID))) chooser = Toplevel(self.root) chooser_frame = Frame(chooser) chooser_banner = Label(chooser_frame, text="The following files were found.\nPlease select which files to open:", padx=10, pady=5) chooser_list = ListboxHV(chooser_frame,selectmode="multiple") for i,item in enumerate(notes): chooser_list.insert(END, "{:>5}{:<32}".format(str(i+1)+". ", str(os.path.basename(item.ID)) + " (" + str(os.path.dirname(item.ID)) + ")")) chooser_list.pack(fill="both",expand="true") button_frame = Frame(chooser) button_open = Button(button_frame, text="Open", command=lambda: launch([notes[j] for j in map(int,chooser_list.curselection())])) button_open_all = Button(button_frame, text="Open All", command=lambda: launch(notes)) button_cancel = Button(button_frame, text="Cancel", command=lambda: chooser.destroy()) chooser_list.pack(side="bottom") chooser_banner.pack(side="top") chooser_frame.pack(side="top",fill="both",expand="true") button_cancel.pack(side="left") button_open_all.pack(side="left") button_open.pack(side="right") button_frame.pack(side="bottom") def _build_file_types(self): '''Build available file types from config.xml (Parent class method)''' dprint(3, "\nTkMemobook::_build_file_types:: ") return Memobook._build_file_types(self) def open_file(self): '''Open file by name: calls Tk file dialogue''' dprint(3, "\nTkMemobook::open_file:: ") active_dir = self.data.get_active_open() if not active_dir: file_names = filedialog.askopenfilenames(initialdir=self.data.active_base(), title="Choose file(s) to open", filetypes=self._build_file_types()) else: file_names = filedialog.askopenfilenames(initialdir=active_dir, title="Choose file(s) to open", filetypes=self._build_file_types()) if file_names: dprint(3, "File names from dialogue are: " + str(file_names) + ". ") self.data.set_active_open(os.path.dirname(file_names[0])) list_of_notes = self.__get_busy_with(None, self.data.open_note,file_names) for nt in list_of_notes: self.tabs.newpage(nt) def save_note(self): '''Save note to disk, save marks to memobook. Calls _process_save_target.''' dprint(3, "\nTkMemobook::save_note:: ") index = self.tabs.index("current") dprint(3, "Index is " + str(index) + ". ") if self.tabs.changed(index) is False: return save_nt = self.tabs.getnoteref(index) save_nt.body = self.tabs.getpageref(index).plate.get("1.0", "end-1c") ret_val = self._process_save_target(save_nt, callback=lambda c:self.tabs.tab(index,text=c)) if (ret_val > 0): dprint(2, "Unable to process save target. Aborting.\n") messagebox.showinfo("Save target error", "Unable to process save target") return if (ret_val < 0) or save_nt.ID == "": return if self.data.save_note(save_nt) : dprint(2, "Save error in data.save_note. Aborting.\n") messagebox.showinfo("Save error", "Unable to save note: " + str(self.data.get_last_error()) ) return self.tabs.clearchanges(index) def save_note_as(self): '''Save-as functionality: save note to disk, save marks to memobook. Calls _process_save_target.''' dprint(3, "\n TkMemobook::save_note_as:: ") index = self.tabs.index("current") dprint(3, "Index is " + str(index) + ". ") save_nt = self.tabs.getnoteref(index) save_nt.body = self.tabs.getpageref(index).dump() if not save_nt.body: dprint(3, "No note body, returning.") return ret_targ = self._process_save_target(save_nt, saveas=True, callback=lambda c:self.tabs.tab(index,text=c)) if (ret_targ > 0): dprint(2, "Unable to process save target. Aborting.\n") messagebox.showinfo("Save target error", "Unable to process save target") return if (ret_targ < 0): return if self.data.save_note(save_nt): dprint(2, "Save error in data.save_note. Aborting.\n") messagebox.showinfo("Save error", "Unable to save note: " + str(self.data.get_last_error()) ) return self.tabs.clearchanges(index) def _process_save_target(self,note,saveas=False,callback=None): '''Select file name for saving. Calls Tk save dialog.''' dprint(3, "\nTkMemobook::_process_save_target:: Note title is " + note.title + ", saveas=" + str(saveas) + ". " ) if note is None: return 1 if (note.ID == "") or saveas: try: if note.ID == "": if not self.data.get_active_save(): name = filedialog.asksaveasfilename(initialdir=self.data.get_active_base(), title="Save file as...") else: name = filedialog.asksaveasfilename(initialdir=self.data.get_active_save(), title="Save file as...") else: temp_dir = os.path.dirname(note.ID) name = filedialog.asksaveasfilename(initialdir=temp_dir, title="Save file as...") if name: if isinstance(name, str) and name == "": return -1 if isinstance(name, tuple) and name == (): return -1 self.data.set_active_save(os.path.dirname(name)) else: return -1 note.ID = name note.title = os.path.basename(name) except Exception as e: dprint(2, "Exception raised during processing of file name and saving: " + str(e)) return 1 else: if callback: dprint(3, "Calling callback function. ") callback(note.title) return 0 else: return 0 def close_page(self): '''Close current note/tab''' dprint(3, "\nTkMemobook::close_page:: ") current = self.tabs.index("current") if self.tabs.changed(current): finish_nt = self.tabs.getnoteref(current) title = str(finish_nt.title) if title == "": title = self.tabs.tab(current, option="text") ans = messagebox.askyesnocancel(title="Save changes?", message="Save changes before closing " + title + "?", default=messagebox.YES) if ans is None: return -1 if not ans: self.tabs.removepage(current) return 0 if self._process_save_target(finish_nt) > 0: err_ans = messagebox.askyesno(title="Save error", message="Error encountered while preparing save file. Close anyway?", default=messagebox.NO ) if err_ans: self.tabs.removepage(current) return 1 return -1 if finish_nt.ID == "": return -1 to_be_written = self.tabs.removepage(current) if self.data.save_note(to_be_written): err_ans = messagebox.askyesno(title="Save error", message="Error encountered while saving file: " + str(self.data.get_last_error()) + "\nClose anyway?", default=messagebox.NO ) if not err_ans: self.tabs.newpage(to_be_written) return 0 return -1 return 0 else: self.tabs.removepage(current) return 1 def close_all(self): '''Close all notes/tabs''' dprint(3, "\nTkMemobook::close_all:: ") for tb in self.tabs.tabs(): i = self.tabs.index(tb) self.tabs.select(i) if self.tabs.changed(i): ret_int = self.close_page() if ret_int and ret_int < 0: return else: self.__close_page() def exit_all(self, e): '''Exit: Close all notes/tabs and exit.''' dprint(3, "\nTkMemobook::exit_all:: ") for tb in self.tabs.tabs(): i = self.tabs.index(tb) self.tabs.select(i) if self.tabs.changed(i): ret_int = self.close_page() if ret_int and ret_int < 0: return else: self.close_page() self.ctrl["x"] = str(self.root.winfo_width() - self.offset[0]) #I found a mysterious increase in window size, countered it by subtracting an additional amount in the following: self.ctrl["y"] = str(self.root.winfo_height() - self.offset[1] - 19) Memobook.exit_all(self, e) self.root.destroy() def font_dialogue(self): '''Font selection: dialogue for font choices''' dprint(3, "\nTkMemobook::font_dialogue:: ") def set_string_variable(var, val): var.set(val) def set_font(getter, fam, sz, wt): self.ctrl["font"]["family"] = fam self.ctrl["font"]["size"] = sz self.ctrl["font"]["weight"] = wt self.tabs.set_page_font(fam, sz, wt) getter.destroy() getter = Toplevel(self.root) getter.title("Font selection") family_str = StringVar(getter) family_str.set(self.ctrl["font"]["family"]) size_str = StringVar(getter) size_str.set(self.ctrl["font"]["size"]) weight_str = StringVar(getter) weight_str.set(self.ctrl["font"]["weight"]) possible_fams = list(font.families(root=self.root)) possible_fams.sort(key=lambda x: x[0]) display_frame = Frame(getter) instr_frame = Frame(display_frame) instr_instr = Label(instr_frame, text="Please select a font:") instr_examp = Label(instr_frame, text=family_str.get(), font=(family_str.get(),12,"normal")) family_str.trace_add("write", lambda x,y,z: instr_examp.config(text=family_str.get(), font=(family_str.get(), 12, weight_str.get()))) weight_str.trace_add("write", lambda x,y,z: instr_examp.config(text=family_str.get(), font=(family_str.get(), 12, weight_str.get()))) label_frame = Frame(display_frame) label_family = Label(label_frame,text="Family:") label_size = Label(label_frame,text="Size:") label_weight = Label(label_frame,text="Weight:") choice_frame = Frame(display_frame) choice_family = Combobox(choice_frame, textvariable=family_str, values=possible_fams) choice_size = Combobox(choice_frame, textvariable=size_str, values=(6,8,10,12,14,16,18,20,24,28,32,48,64,72), postcommand=lambda: set_string_variable(size_str, self.ctrl["font"]["size"])) choice_weight = Combobox(choice_frame, textvariable=weight_str, values=("normal","bold","italic")) finish_frame = Frame(getter) finish_cancel = Button(finish_frame, text="Cancel", command=lambda: getter.destroy()) finish_apply = Button(finish_frame, text="Apply", command=lambda: set_font(getter, family_str.get(), size_str.get(), weight_str.get())) instr_instr.pack(side="top", anchor="w") instr_examp.pack(side="bottom", anchor="w") instr_frame.pack() label_family.pack(anchor="w") label_size.pack(anchor="w") label_weight.pack(anchor="w") label_frame.pack(side="left") choice_family.pack(anchor="w", fill="x", expand="true") choice_size.pack(anchor="w", fill="x", expand="true") choice_weight.pack(anchor="w", fill="x", expand="true") choice_frame.pack(side="left", expand="true", fill="x") display_frame.pack(side="top", expand="true", fill="both") finish_cancel.pack(side="left") finish_apply.pack(side="right") finish_frame.pack(side="bottom") def mark_dialogue(self): '''Select mark to be added to note from list of current marks''' def add_to_dest(listbox1,listitems,var="", listbox2=None): # subfunction for adding items to the pending list of marks [silent or open] if listbox2 and (var in ("VIS", "INVIS")): if var == "VIS": for item in listitems: listbox1.insert(END, item) else: for item in listitems: listbox2.insert(END, item) else: for item in listitems: listbox1.insert(END, item) def rem_from_dest(listbox): # subfunction for removing items from the pending list of marks orderlist = list(listbox.curselection()) orderlist.sort(reverse=True) for index in orderlist: listbox.delete(index) def process_dest(win, listbox1, listbox2=None): # assert pending list of marks to memobook self.tabs.writetocurrent(listbox1.get(0, END)) if listbox2: self.data.update(focus, listbox2.get(0, END)) else: self.data.update(focus, listbox1.get(0, END)) win.destroy() def default_selection(var): # subfunction to set default silent/open var.set("VIS") dprint(3, "\nTkMemobook::mark_dialogue:: ") getter = None try: focus = self.tabs.getnoteref(self.tabs.index("current")) except TclError: dprint(1, "Error in fetching current tab from .tabs.") messagebox.showinfo("Edit Marks Error:", "A tab must be opened before marks can be managed.") return else: getter = Toplevel(self.root) title_string = "Manage marks for " if len(focus.title) > 32: title_string += focus.title[:32] + "..." else: title_string += focus.title getter.title(title_string) top_frame = Frame(getter) top_left_frame = Frame(top_frame) top_left_label = Label(top_left_frame, text="Marks from open notes:") top_left_getter = ListboxHV(top_left_frame, height=12, width=27, selectmode="multiple") getter_items = self.tabs.marks() getter_items.sort() for item in getter_items: top_left_getter.insert(END, item) top_right_frame = Frame(top_frame) top_cent_frame = Frame(top_frame) bottom_frame = Frame(getter) bottom_middle_frame = Frame(bottom_frame) bottom_middle_label = Label(bottom_middle_frame, text="Additional marks:") bottom_middle_enter = Entry(bottom_middle_frame, width=24) bottom_bottom_frame = Frame(bottom_frame) bottom_bottom_cancel = Button(bottom_bottom_frame, text="Cancel", command=lambda: getter.destroy()) top_left_label.pack(side="top", anchor="n") top_left_getter.pack(side="bottom", anchor="w", expand="true", fill="both") top_left_frame.pack(side="left", expand="true", fill="both") if focus.mime == NoteMime.TEXT: top_right_vis_label = Label(top_right_frame, text="Store in text (append to end):") top_right_vis_dest = ListboxHV(top_right_frame, height=5, width=27, selectmode="multiple") top_right_invis_label = Label(top_right_frame, text="All hidden (not stored in text):") top_right_invis_dest = ListboxHV(top_right_frame, height=5, width=27, selectmode="multiple") if focus.tags: if focus.tags.silent: for st in focus.tags.silent: top_right_invis_dest.insert(END, st) top_cent_add_vis = Button(top_cent_frame, text="→", command=lambda:add_to_dest(top_right_vis_dest, [getter_items[j] for j in top_left_getter.curselection()])) top_cent_remove_vis = Button(top_cent_frame, text="X", command=lambda:rem_from_dest(top_right_vis_dest)) top_cent_upperspacer = Label(top_cent_frame, text="\n\n") top_cent_add_invis = Button(top_cent_frame, text="→", command=lambda:add_to_dest(top_right_invis_dest, [getter_items[j] for j in top_left_getter.curselection()])) top_cent_remove_invis = Button(top_cent_frame, text="X", command=lambda:rem_from_dest(top_right_invis_dest)) storage_variable = StringVar(bottom_middle_frame) storage_variable.set("VIS") bottom_middle_radio_VIS = Radiobutton(bottom_middle_frame, text="Visible", variable=storage_variable, command=lambda: default_selection(storage_variable), # get tk to give default selection value="VIS") bottom_middle_radio_INVIS = Radiobutton(bottom_middle_frame, text="Hidden", variable=storage_variable, value="INVIS") bottom_middle_add = Button(bottom_middle_frame, text="↑", command=lambda:add_to_dest(top_right_vis_dest, parse.split_by_unknown(bottom_middle_enter.get()), storage_variable.get(), top_right_invis_dest)) bottom_bottom_apply = Button(bottom_bottom_frame, text="Apply", command=lambda:process_dest(getter,top_right_vis_dest,top_right_invis_dest)) top_cent_remove_invis.pack(side="bottom") top_cent_add_invis.pack(side="bottom") top_cent_upperspacer.pack(side="bottom") top_cent_remove_vis.pack(side="bottom") top_cent_add_vis.pack(side="bottom") top_right_vis_label.pack(side="top", anchor="n") top_right_vis_dest.pack(side="top", anchor="w", fill="both", expand="true") top_right_invis_label.pack(side="top", anchor="n") top_right_invis_dest.pack(side="top", anchor="w", fill="both", expand="true") bottom_middle_label.pack(side="left", anchor="w") bottom_middle_enter.pack(side="left", anchor="w", fill="x", expand="true") bottom_middle_radio_VIS.pack(side="left", anchor="w") bottom_middle_radio_INVIS.pack(side="left", anchor="w") bottom_middle_add.pack(side="right", anchor="w") else: top_right_invis_label = Label(top_right_frame, text="Hidden and stored outside of text:") top_right_invis_dest = ListboxHV(top_right_frame, height=12, width=27, selectmode="multiple") if focus.tags: for t in focus.tags: top_right_invis_dest.insert(END, t) top_cent_add_invis = Button(top_cent_frame, text="→", command=lambda:add_to_dest(top_right_invis_dest, [getter_items[j] for j in top_left_getter.curselection()])) top_cent_remove_invis = Button(top_cent_frame, text="X", command=lambda:rem_from_dest(top_right_invis_dest)) bottom_middle_add = Button(bottom_middle_frame, text="↑", command=lambda:add_to_dest(top_right_invis_dest, parse.split_by_unknown(bottom_middle_enter.get()))) bottom_bottom_apply = Button(bottom_bottom_frame, text="Apply", command=lambda:process_dest(getter, top_right_invis_dest)) top_cent_remove_invis.pack(side="bottom") top_cent_add_invis.pack(side="bottom") top_right_invis_label.pack(side="top", anchor="n") top_right_invis_dest.pack(side="top", anchor="w", fill="both", expand="true") bottom_middle_label.pack(side="left", anchor="w") bottom_middle_enter.pack(side="left", anchor="w", fill="x", expand="true") bottom_middle_add.pack(side="right", anchor="w") top_cent_frame.pack(side="left") top_right_frame.pack(side="left", fill="both", expand="true") top_frame.pack(side="top",fill="both",expand="true") bottom_bottom_apply.pack(side="left") bottom_bottom_cancel.pack(side="right") bottom_bottom_frame.pack(side="bottom") bottom_middle_frame.pack(side="bottom", anchor="w", fill="x", expand="true") bottom_frame.pack(side="bottom", fill="x", expand="true") def open_pop(self, hook_remove, hook_add, hook_apply): '''Manage bookmark sources: Major dialogue''' dprint(3, "\nTkMemobook::open_pop:: ") manager = Toplevel(self.root) manager_list = ListboxHV(manager, selectmode="multiple") manager_items = self.ctrl["db"]["scan"] if isinstance(manager_items, str): manager_items = [ manager_items ] else: manager_items = list(manager_items) manager_items.sort() for item in manager_items: manager_list.insert(END, item) manager_list.grid_columnconfigure(0, weight=1) manager_list.grid_rowconfigure(0, weight=1) manager_list.grid(sticky="nswe") buttons = Frame(manager) rembutt = Button(buttons, text="Remove", command=lambda: hook_remove(manager_list, manager_items) ) addbutt = Button(buttons, text="Add Other...", command=lambda: hook_add(manager, manager_list, manager_items) ) appbutt = Button(buttons, text="Apply", command=lambda: self.__get_busy_with(None, hook_apply, manager, manager_items) ) rembutt.grid(row=1, column=0) addbutt.grid(row=1, column=1) appbutt.grid(row=1, column=2) buttons.grid_columnconfigure(1, weight=1) buttons.grid_rowconfigure(1, weight=1) buttons.grid(stick="nswe") manager.grid_columnconfigure(0, weight=1) manager.grid_rowconfigure(0, weight=1) def __open_pop_add(self, win, manlist, manitems): '''Manage bookmark sourse: add directory. Calls Tk file dialogue.''' dprint(3, "\nTkMemobook::__open_pop_add:: ") if manitems: new_dir = filedialog.askdirectory(initialdir=manitems[0], title="Choose a scan directory", parent=win ) else: new_dir = filedialog.askdirectory(initialdir=self.ctrl["loc"], title="Choose a scan directory", parent=win ) if new_dir: manitems.append(new_dir) manlist.insert(END, str(new_dir)) def __open_pop_remove(self, manlist, manitems): '''Manage sources: remove directory.''' dprint(3, "\nTkMemobook::__open_pop_remove:: ") index_list = list(manlist.curselection()) index_list.sort(reverse=True) for index in index_list: manitems.pop(index) manlist.delete(index) def __open_pop_apply(self, win, new_scan): '''Manage sources: apply changes to memobook and config object''' dprint(3, "\nTkMemobook::__open_pop_apply:: ") self.data.clear() if new_scan: self.ctrl["db"]["scan"] = list(new_scan) else: self.ctrl["db"]["scan"] = "." self.data.populate() win.destroy() def __get_busy_with(self, optionalwin, fctn, *args): '''Wrapper to invoke mouse busy icon''' ### Example of use: for a call, buff = f(arg1,arg2,arg3), use ### buff = self.__get_busy_with(f,arg1,arg2,arg3) ### The choice was made not to recursively propagate through self.root ### and its descendants: this seems overly broad and might involve ### propagation through too many (out-of-view) tabs or, worse, might not ### reach the visible tab at all. The biggest negative is that if the ### UI is drastically changed, this function must be tailored to those changes. dprint(3, "\nMemobook::__get_busy_with:: ") self.root.config(cursor="watch") self.root.update() self.menu.config(cursor="watch") self.menu.update() self.tabs.config(cursor="watch") self.tabs.update() if optionalwin: optionalwin.config(cursor="watch") optionalwin.update() # the following logic avoids the exception thrown when the current index # is requested but there are no tabs. if self.tabs.tabs(): i = self.tabs.index("current") else: i = -1 if i >= 0: self.tabs.getpageref(i).plate.config(cursor="watch") self.tabs.getpageref(i).plate.update() retval = fctn(*args) self.root.config(cursor="") self.menu.config(cursor="") self.tabs.config(cursor="") if optionalwin: optionalwin.config(cursor="") if i >= 0: self.tabs.getpageref(i).plate.config(cursor="") return retval
def __init__(self, master): self.s3 = boto3.resource('s3') self.s3c = boto3.client('s3') light_gray = '#D9D9D9', blue = '#181B42', red = '#FF0000', black = '#000000', cyan = '#80DFFF' bold = 'Helvetica 10 bold underline' normal = 'Helvetica 10' rpath = realpath(__file__)[:-len(basename(__file__))] self.finish_thread = None self.greeting = 'Hello %s' % getuser() self.master = master self.master.title('Amazon S3 File Transfer Client') self.master.configure(bg=black) if platform != 'win32': desktop = {'plasma': '695x700', 'ubuntu': '625x700'} env = environ.get('DESKTOP_SESSION') if env is None or env not in desktop or env == 'ubunutu': self.master.maxsize('625', '700') self.master.minsize('625', '550') else: self.master.maxsize('695', '700') self.master.minsize('695', '550') self.master.geometry(desktop[env]) self.icon = PhotoImage(file=rpath + 'icon.png') master.iconphoto(False, self.icon) else: self.master.geometry('485x600') self.master.iconbitmap(rpath + 'icon.ico') self.master.maxsize('485', '700') self.master.minsize('485', '550') menu = Menu(self.master) menu.config(background=black, fg=light_gray) self.master.config(menu=menu) file = Menu(menu) file.add_command(label='Exit', command=self.quit_app) menu.add_cascade(label='File', menu=file) refresh = Menu(menu) refresh.add_command(label='Local', command=self.refresh_local) refresh.add_command(label='S3', command=self.refresh_s3) menu.add_cascade(label='Refresh', menu=refresh) self.dir, self.drp_sel, self.bucket_name = ['' for _ in range(3)] self.folder_path = StringVar() self.dropdown = StringVar() self.dropdown_data = self.populate_dropdown() if not self.dropdown_data: self.dropdown_data = ['none available'] self.deleted = False self.local_sel, self.s3_sel = ([] for _ in range(2)) self.local_label = Label(master, fg=light_gray, bg=black, text='LOCAL FILE SYSTEM', font=bold, width=24) self.local_label.grid(row=0, column=0, sticky=E + W, padx=10, pady=20) self.s3_label = Label(master, fg=light_gray, bg=black, text='AMAZON S3', font=bold, underline=True, width=24) self.s3_label.grid(row=0, column=1, sticky=E + W, padx=10, pady=20) self.dropdown_box = OptionMenu(master, self.dropdown, *self.dropdown_data, command=self.set_drop_val) self.dropdown_box.configure(fg=light_gray, bg=blue, width=16, highlightbackground=black, highlightthickness=2) self.dropdown_box.grid(row=1, column=1, sticky=E + W, padx=52, pady=10) self.browse_button = Button(master, fg=light_gray, bg=blue, text='Browse', width=16, highlightbackground=black, highlightthickness=2, command=self.load_dir) self.browse_button.grid(row=1, column=0, sticky=E + W, padx=52, pady=10) self.browse_label = Label(master, fg=light_gray, bg=black, text='No directory selected', width=24, font=normal) self.browse_label.grid(row=2, column=0, sticky=E + W, padx=10, pady=10) self.bucket_label = Label(master, fg=light_gray, bg=black, text='No bucket selected', width=24, font=normal) self.bucket_label.grid(row=2, column=1, sticky=E + W, padx=10, pady=10) self.refresh_btn_local = Button(master, fg=light_gray, bg=blue, text='REFRESH', width=10, highlightbackground=black, highlightthickness=2, command=self.refresh_local) self.refresh_btn_local.grid(row=3, column=0, sticky=E + W, padx=50, pady=10) self.refresh_btn_s3 = Button(master, fg=light_gray, bg=blue, text='REFRESH', width=10, highlightbackground=black, highlightthickness=2, command=self.refresh_s3) self.refresh_btn_s3.grid(row=3, column=1, sticky=E + W, padx=50, pady=10) self.ex_loc = Listbox(master, fg=cyan, bg=black, width=36, height=18, highlightcolor=black, selectmode='multiple') self.ex_loc.grid(row=5, column=0, sticky=E + W, padx=10, pady=10) self.ex_s3 = Listbox(master, fg=cyan, bg=black, width=36, height=18, highlightcolor=black, selectmode='multiple') self.ex_s3.grid(row=5, column=1, sticky=E + W, padx=10, pady=10) self.upload_button = Button(master, fg=light_gray, bg=blue, text='Upload ->', width=14, highlightbackground=black, highlightthickness=2, command=self.upload) self.upload_button.grid(row=6, column=0, sticky=E, padx=10, pady=10) self.download_button = Button(master, fg=light_gray, bg=blue, text='<- Download', width=14, highlightbackground=black, highlightthickness=2, command=self.download) self.download_button.grid(row=6, column=1, sticky=W, padx=10, pady=10) self.delete_local = Button(master, fg=light_gray, bg=blue, text='DELETE', width=14, highlightbackground=red, activebackground=red, command=self.delete_local_records) self.delete_local.grid(row=6, column=0, sticky=W, padx=10, pady=10) self.delete_s3 = Button(master, fg=light_gray, bg=blue, text='DELETE', width=14, highlightbackground=red, activebackground=red, command=self.delete_s3_records) self.delete_s3.grid(row=6, column=1, sticky=E, padx=10, pady=10) self.found_label_local = Label(master, fg=light_gray, bg=black, text='found local', width=16) self.found_label_local.grid(row=7, column=0, sticky=E + W, padx=10, pady=10) self.found_label_s3 = Label(master, fg=light_gray, bg=black, text='found s3', width=16) self.found_label_s3.grid(row=7, column=1, sticky=E + W, padx=10, pady=10) self.status_label = Label(master, fg=light_gray, bg=black, text=self.greeting, width=8) self.status_label.grid(row=8, column=0, sticky=E + W, padx=10, pady=10) self.create_bucket_label = Label(master, fg=light_gray, bg=black, text='New Bucket:', width=10) self.create_bucket_label.grid(row=8, column=1, sticky=W, padx=1, pady=1) if platform != 'win32': self.create_bucket_name = Text(master, fg=cyan, bg=black, width=15, height=1) self.create_bucket_button = Button(master, fg=light_gray, bg=blue, text='Create', width=5, highlightbackground=black, highlightthickness=2, command=self.create_bucket) else: self.create_bucket_name = Text(master, fg=cyan, bg=black, width=11, height=1) self.create_bucket_button = Button(master, fg=light_gray, bg=blue, text='Create', width=7, highlightbackground=black, highlightthickness=2, command=self.create_bucket) self.create_bucket_name.grid(row=8, column=1, padx=1, pady=10) self.create_bucket_button.grid(row=8, column=1, sticky=E, padx=10, pady=10) self.master.grid_columnconfigure(0, weight=1) self.master.grid_columnconfigure(1, weight=1) self.master.grid_rowconfigure(5, weight=1) self.set_found_local_label('%d files found' % self.ex_loc.size()) self.set_found_s3_label('%d files found' % self.ex_s3.size())
menu_file.add_separator() menu_file.add_command(label='Exit', font=("Times", 11)) menu.add_cascade(label='File', menu=menu_file, font=("Times", 11)) menu_documents = Menu(menu) menu_documents.add_command(label='Document', font=("Times", 11)) menu.add_cascade(label='Document', menu=menu_documents, font=("Times", 11)) menu_help = Menu(menu) menu_help.add_command(label='Contact Us', font=("Times", 11)) menu.add_cascade(label='Help', menu=menu_help, font=("Times", 11)) menu.config(bg='#49A') window.config(menu=menu) lbl = Label(window, text="Smart Grid Attack Simulation System ", font=("Times", 18), background="#D6E2F3", foreground="#000280") lbl.grid(column=0, row=0, columnspan=2) lbl_smartgrid_model = Label(window, text=" Smart Grid Model\n", background="#D6E2F3", foreground="#000280")
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)
def create_widgets(self): ''' Long method to create all widgets on the root window ''' # Creating a Menu Bar menu_bar = Menu(root) root.config(menu=menu_bar) menu_bar.config(background = background, foreground = text_color) # Code for the cascading File menu file_menu = Menu(menu_bar, tearoff=0) file_menu.add_command(label='New Ctrl+n', command=self._new) file_menu.add_separator() file_menu.add_command(label='Save Ctrl+s', command=self._save) file_menu.add_separator() file_menu.add_command(label='Quit Ctrl+q', command=self._quit) file_menu.configure(background = background, foreground = text_color) menu_bar.add_cascade(label='File', menu=file_menu) # Code for cascading config menu config_menu = Menu(menu_bar, tearoff=0) config_menu.add_command(label='Set Default Save Path', command=DefaultPath) config_menu.add_separator() config_menu.add_command(label='Use Bullet Points (' + use_bp + ')', command=SetBulletPoints) config_menu.add_separator() config_menu.add_command(label='Format Filename (' + fn_format + ')', command=FilenameFormat) config_menu.configure(background = background, foreground = text_color) config_menu.add_separator() config_menu.add_command(label='Use Dark Mode (' + dark_mode + ')', command=UseDarkMode) config_menu.configure(background = background, foreground = text_color) menu_bar.add_cascade(label='Config', menu=config_menu) # Code for the cascading Help menu help_menu = Menu(menu_bar, tearoff=0) help_menu.add_command(label='Program Help Ctrl+h', command=HelpWindow) help_menu.add_separator() help_menu.add_command(label='About', command=AboutWindow) help_menu.configure(background = background, foreground = text_color) menu_bar.add_cascade(label='Help', menu=help_menu) # Top frame for the recipe name entry nameLabel = ttk.Label(foreground=label_text, background=label_bg, text=' Enter Recipe Title') self.title_frame = ttk.LabelFrame(self.frame, labelwidget=nameLabel) self.title_frame.grid(column=0, row=0, columnspan=2, padx=8, pady=4, sticky='W') # Left frame for the ingredients list ingLabel = ttk.Label(foreground=label_text, background=label_bg, text=' Ingreidents') self.ing_frame = ttk.LabelFrame(self.frame, labelwidget=ingLabel) self.ing_frame.grid(column=0, row=1, padx=8, pady=4, sticky = 'news') self.ing_frame.rowconfigure(0, weight = 1) self.ing_frame.columnconfigure(0, weight = 1) # Right frame for the directions dirLabel = ttk.Label(foreground=label_text, background=label_bg, text=' Directions') self.dir_frame = ttk.LabelFrame(self.frame, labelwidget=dirLabel) self.dir_frame.grid(column=1, row=1, padx=8, pady=4, sticky='nwes') self.dir_frame.rowconfigure(0, weight = 1) self.dir_frame.columnconfigure(0, weight = 1) # Adding a text box entry widget for the recipe title self.title = tk.StringVar() self.title_entered = tk.Entry(self.title_frame, width=75, textvariable=self.title, bd=5, relief=tk.RIDGE) self.title_entered.configure(background = entry_bg, foreground = entry_text, insertbackground='white') self.title_entered.grid(column=0, row=2, padx=8, pady=(3, 8), sticky='W') self.title_entered.bind("<Tab>", self.focus_next_widget) tt.create_ToolTip(self.title_entered, 'Enter the title of the recipe here') # Add a scroll box for ingredients self.ingredients = scrolledtext.ScrolledText(self.ing_frame, width = 30, bd=5,\ wrap=tk.WORD, relief=tk.RIDGE) self.ingredients.configure(background = entry_bg, foreground = entry_text, insertbackground='white') self.ingredients.vbar.configure(troughcolor = scroll_color, background = scroll_bg, activebackground = scrollbar_color) self.ingredients.grid(column=0, row=0, padx=8, pady=(0, 20), sticky=tk.N+tk.S+tk.E+tk.W) self.ingredients.bind("<Tab>", self.focus_next_widget) tt.create_ToolTip(self.ingredients, 'Enter ingredients here, one per line\nBegin line with a period to omit bullet point') # Add a scroll text box for directions self.directions = scrolledtext.ScrolledText(self.dir_frame, bd=5,\ wrap=tk.WORD, relief=tk.RIDGE) self.directions.configure(background = entry_bg, foreground = entry_text, insertbackground='white') self.directions.vbar.configure(troughcolor = scroll_color, background = scroll_bg, activebackground = scrollbar_color) self.directions.grid(column=0, row=0, padx=8, pady=(0, 20), sticky=tk.N+tk.S+tk.E+tk.W) self.directions.bind("<Tab>", self.focus_next_widget) tt.create_ToolTip(self.directions, 'Enter the recipe instructions here') self.title_entered.focus() # Place cursor into the title entry box
class MainFrame(Frame): 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 if self.autosave.get(): self.save_config(self.fpath) return title = self.master.title() if title == _title: title = '{} - {}'.format('Unsaved', title) if '*' not in title: title = '*' + title self.master.title(title) def __init__(self, master): Frame.__init__(self, master) self.master = master self.use_random_org = BooleanVar() self.allow_odd = IntVar() self.always_on_top = BooleanVar() self.autosave = BooleanVar() self.use_random_org.trace('w', self.set_unsaved_title) self.allow_odd.trace('w', self.set_unsaved_title) self.always_on_top.trace('w', self.set_unsaved_title) self.set_defaults() self.menubar = Menu(master) self.filemenu = Menu(self.menubar, tearoff=0, postcommand=maintain_group_indices) self.filemenu.add_command(label='New', underline=0, command=self.reset_default_group, accelerator='Ctrl+N') self.filemenu.add_command(label='Load', underline=3, command=self.load_config, accelerator='Ctrl+D') self.filemenu.add_command( label='Save', underline=1, command=lambda: self.save_config(fpath=self.fpath), accelerator='Ctrl+S') self.filemenu.add_command(label='Save as...', underline=4, command=self.save_config, accelerator='Ctrl+Shift+S') self.editmenu = Menu(self.menubar, tearoff=0) self.editmenu.add_checkbutton(label='Use random.org', underline=0, variable=self.use_random_org) self.editmenu.add_checkbutton(label='Allow odd dice', underline=6, variable=self.allow_odd, command=self.toggle_odd, onvalue=1, offvalue=2) self.editmenu.add_separator() # ------------------ self.editmenu.add_checkbutton(label='Always on top', underline=10, variable=self.always_on_top, command=self.pin) self.editmenu.add_checkbutton(label='Autosave', underline=4, variable=self.autosave, command=self.toggle_autosave) self.editmenu.add_separator() # ------------------ self.editmenu.add_command(label='Repeat last action', underline=0, accelerator='Ctrl+R') self.menubar.add_cascade(label='File', underline=0, menu=self.filemenu) self.menubar.add_cascade(label='Edit', underline=0, menu=self.editmenu) self.menubar.config(relief='flat') master.config(menu=self.menubar) self.reset_default_group() self.bind_all('<Control-n>', lambda e: self.reset_default_group()) self.bind_all('<Control-d>', lambda e: self.load_config()) self.bind_all('<Control-s>', lambda e: self.save_config(fpath=self.fpath)) self.bind_all('<Control-Shift-S>', lambda e: self.save_config()) 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 pin(self): self.master.wm_attributes('-topmost', self.always_on_top.get()) def toggle_odd(self): for group in roller_groups: for roller in group.rollers: roller.die_faces_spin.interval = self.allow_odd.get() num = roller.die_faces.get() if num % 2 != 0: roller.die_faces.set(num - 1) def toggle_autosave(self): if self.autosave.get(): self.save_config(self.fpath) else: self.set_unsaved_title() def set_defaults(self): self.master.title(_title) self.fpath = '' self.use_random_org.set(False) self.allow_odd.set(2) self.always_on_top.set(False) self.autosave.set(False) def reset_default_group(self): if self.ask_proceed(): self.autosave.set(False) self.clear_groups() self.set_defaults() self.create_group(0, 1) @staticmethod def clear_groups(): temp_groups = list(roller_groups) for group in temp_groups: group.remove_group(override=True) def create_group(self, index, rollers): default_group = RollerGroup(self, index) for i in range(rollers): default_group.rollers.append(Roller(default_group, i)) roller_groups.append(default_group) def load_config(self): autosave = False self.autosave.set(autosave) 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(): self.autosave.set(False) 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)
# pygame.mixer.pre_init(44100, -16, 2, 2048) # pygame.mixer.init() # pygame.mixer.music.load("tng_red_alert3.mp3") # pygame.mixer.music.set_volume(10.0) # Set up counter display fnt = font.Font(family='Helvetica', size=300, weight='bold') txt = StringVar() lbl = ttk.Label(root, textvariable=txt, font=fnt, foreground="white", background="black") txt.set(iTotal) lbl.place(relx=0.5, rely=0.5, anchor="center") # Menu menu_pop = Menu(root) menu = Menu(menu_pop, tearoff=0) menu.config(bg="black", fg="white", relief="raised") menu.add_command(label="Start/Stop", accelerator="F1", command=go_stop) menu.add_command(label="Reset", accelerator="F2", command=reset) menu.add_separator() menu.add_command(label="Settings", command=settings) menu.add_separator() menu.add_command(label="Exit", accelerator="X", command=quit_all) menu_pop.add_cascade(label="File", menu=menu) # Start main loop root.mainloop()
if (user_response != ''): if (user_response == 'exit' or user_response == 'quit'): print('NANOSEC TIME STOP: ', time.thread_time_ns() / 1000000000) else: print('\n', end=" ") responsive = (response(user_response)) print(responsive + '\n') sent_tokens.remove(user_response) rejuvinate(1) return responsive #MENU------------------------------------- master_splinter = tk menu = Menu(master_splinter, fg="white") menu.config(bg="black") master_splinter.config(menu=menu) filemenu = Menu(menu) journalMenu = Menu(menu) menu.add_cascade(label="Think", menu=filemenu) #editMenu = Menu(menu) #editMenu.add_command(label="Universe Message", command=donothing) #editMenu.add_command(label="Manifest", command=donothing) #menu.add_cascade(label="Feeling", menu=editMenu) filemenu.add_command(label="Save", command=save) filemenu.add_command(label="about", command=about) filemenu.add_command(label="Close", command=tk.destroy) journalMenu.add_command(label="Launch AI Journal", command=journal) menu.add_cascade(label="My Journal", menu=journalMenu)