class FileChooser: def __init__(self): self.filechooser = Tk() self.filechooser.geometry('500x500+0+0') self.button = Button(self.filechooser,text="Add Directory",command=self.addDir) self.listview = Listbox(self.filechooser) self.closebutton = Button(self.filechooser,text="Scan",command=self.Done) self.listview.pack(fill="both") self.button.pack(fill='x') helptext = """Select directories by pressing the "Add Directory" Button, then press Scan. \n When the file tree appears, red text means the file or folder is a duplicate. \n purple means the folder contains duplicates but itself is not a duplicate. \n Double Click on red text entries to view matches""" self.instructions = Label(self.filechooser, text=helptext) self.instructions.pack(fill='both') self.closebutton.pack() self.filechooser.mainloop() def Done(self): self.filechooser.destroy() def addDir(self): dir = askdirectory() if os.path.isdir(dir): dirlist.append(dir) self.listview.insert('end',str(dir))
class Application(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.grid(sticky=N+S+E+W) self.mainframe() def mainframe(self): self.data = Listbox(self, bg='red') self.scrollbar = Scrollbar(self.data, orient=VERTICAL) self.data.config(yscrollcommand=self.scrollbar.set) self.scrollbar.config(command=self.data.yview) for i in range(1000): self.data.insert(END, str(i)) self.run = Button(self, text="run") self.stop = Button(self, text="stop") self.data.grid(row=0, column=0, rowspan=4, columnspan=2, sticky=N+E+S+W) self.data.columnconfigure(0, weight=1) self.run.grid(row=4,column=0,sticky=EW) self.stop.grid(row=4,column=1,sticky=EW) self.scrollbar.grid(column=2, sticky=N+S)
def insert_list(self, items): frame = self.frame frame.pack(fill="y") lb = Listbox(frame, selectmode="multiple") for i in items: lb.insert("end", i) lb.pack() self.ok_cancel_buttons(call=lambda : self.del_items(lb.curselection()))
def Listatag(self): # Lista de tags * em fase de teste title = ['189.186.63.44.20','123.145.584.55.5', '','',''] titleList = Listbox(self, height=5) for t in title: titleList.insert(END, t) titleList.grid(row=7, column=2, columnspan=2, pady=5, sticky=W+E) titleList.bind("<<ListboxSelect>>", self.newTitle)
class LabeledListBox(Frame): def __init__(self, parent, list_model, label_text): Frame.__init__(self, parent) self._list_model = list_model self._list_objects = [] self._selected_items = [] scrollbar = Scrollbar(self, orient=VERTICAL) Label(self, text=label_text).pack() self.listbox = Listbox(self, selectmode=EXTENDED, exportselection=0, yscrollcommand=scrollbar.set, borderwidth=0, highlightthickness=0) scrollbar.config(command=self.listbox.yview) scrollbar.pack(side=RIGHT, fill=Y) self.listbox.pack(side=LEFT, fill=BOTH, expand=1) self.listbox.bind('<<ListboxSelect>>', self._on_select) self._list_model.list_items_model.add_listener(self._list_items_changed) self._list_model.selected_items_model.add_listener(self._selected_items_changed) self._update_list_items() def _list_items_changed(self, values): self._update_list_items() def _selected_items_changed(self, values): self._update_selected_items() def _update_list_items(self): values, labels = self._list_model.list_items_model.get_list_values() if not values == self._list_objects: self._list_objects = [] self._selected_items = [] self.listbox.delete(0, END) for value, label in zip(values, labels): self._list_objects.append(value) self.listbox.insert(END, label) self._update_selected_items() def _update_selected_items(self): selected_items = self._list_model.selected_items_model.selected_items if not selected_items == self._selected_items: self._selected_items = selected_items for index, list_item in enumerate(self._list_objects): if list_item in selected_items: self.listbox.selection_set(index) def _on_select(self, evt): visible_selected_indices = self.listbox.curselection() for index, list_item in enumerate(self._list_objects): if index in visible_selected_indices: self._list_model.selected_items_model.select(list_item) else: self._list_model.selected_items_model.deselect(list_item)
def initUI(self): self.parent.title("TVstream manager") self.stytle = ttk.Style() self.pack(fill=BOTH, expand=1) self.columnconfigure(0, weight=1, pad=2) self.columnconfigure(2, weight=1, pad=2) self.columnconfigure(4, pad=7) #self.rowconfigure(3, weight=1) #self.rowconfigure(4, weight=1, pad=7) lbll = Label(self, text="Lingua") lbll.grid(row=0,column=0,sticky=W, pady=4, padx=5) lble = Label(self, text="Emittenti") lble.grid(row=0,column=2,sticky=W, pady=1, padx=5) global langlst scrollang = Scrollbar(self) langlst = Listbox(self,font='Arial 9',yscrollcommand=scrollang.set) scrollang.config(command = langlst.yview) for i in lingue: langlst.insert(END, i) langlst.focus_set() langlst.bind("<<ListboxSelect>>", self.onSelectLang) langlst.grid(row=1,column=0, columnspan=2, padx=6,sticky=E+W+S+N) scrollang.grid(row=1,column=1, sticky=E+S+N) global emitlst scrollemit = Scrollbar(self) emitlst = Listbox(self,font='Arial 9',yscrollcommand=scrollemit.set) scrollemit.config(command = emitlst.yview ) emitlst.bind("<<ListboxSelect>>", self.onSelectEmittente) emitlst.grid(row=1,column=2, columnspan=2, padx=5,sticky=E+W+S+N) scrollemit.grid(row=1,column=3,sticky=E+S+N) lbltxt = Label(self, text="Output log") lbltxt.grid(row=2,column=0, columnspan=3, sticky=W, pady=4, padx=5) global area area = Text(self,height=10,font='Arial 9') area.grid(row=3, column=0, columnspan=5, rowspan=1, padx=5, sticky=E+W+S+N) scrolltxt = Scrollbar(self) scrolltxt.config(command = area.yview) scrolltxt.grid(row=3,column=4, columnspan=1, rowspan=1, sticky=E+N+S) play = Button(self, text='Play', command=self.playUrl, bg='gray', fg='black') play.grid(row=1,column=4,padx=4,sticky=E+W)
def _about_creatures(self): lb = Listbox(self.frame, height=15, width=50, selectmode=SINGLE) lb.bind('<<ListboxSelect>>', self._onselect) lb.grid(row=1, column=2) items = self.model.creatures.items() items = sorted(items, key=lambda k: k[0][0] * self.model.width + k[0][1]) for (x, y), creature in items: lb.insert(END, [x, y, creature.life]) self.canvas = NeuroCanvas(self.frame, (2, 2), 400, 300)
class CreateSets(Frame): def __init__(self, parent): # super(createSets,self).__init__(parent) Frame.__init__(self, parent) self.parent = parent self.grid(row=0, column=0) self.parentWindow = 0 self.listBox = Listbox(self, selectmode=EXTENDED) self.listBox.grid(row=1, column=1) for item in ["one", "two", "three", "four"]: self.listBox.insert(END, item) self.buttonDel = Button(self, text="delite selected class", command=self.del_selected) # lambda ld=self.listBox:ld.delete(ANCHOR)) self.buttonDel.grid(row=0, column=0) self.entry = Entry(self, state=NORMAL) # self.entry.focus_set() self.entry.insert(0, "default") self.entry.grid(row=1, column=0) self.buttonInsert = Button(self, text="add new class", command=self.add) self.buttonInsert.grid(row=0, column=1) self.buttonDone = Button(self, text="done", command=self.done) self.buttonDone.grid(row=2, column=0) def done(self): self.parentWindow.childResultList = self.listBox.get(0, END) # print(self.listBox.get(0, END)) self.parent.destroy() def add(self): text = self.entry.get() self.listBox.insert(END, text) def del_selected(self): lb = self.listBox items = map(int, lb.curselection()) for item in items: lb.delete(item)
class ShapesMenu(object): """ """ def __init__(self, master, line_collection): try: self.width_of_entry = len(line_collection[0]) except IndexError: self.width_of_entry = 0 self.top = Toplevel(master) self.current_lines_listbox = Listbox(self.top) self.removed_lines_listbox = Listbox(self.top) self.submit = Button(self.top, text = "Ok", command=self.submit) self.remove_button = Button(self.top, text = "Remove", command=self.remove_line) self.cancel = Button(self.top, text = "Cancel", command=self.top.destroy) self.top.bind("<Return>", func=self.submit) self.current_lines = line_collection self.removed_lines = [] self.ids_internal = [] self.ids = [] for index, line in enumerate(self.current_lines): #removes the point data and converts the rest to strings id = line[1] if id not in self.ids_internal: self.ids_internal.append(id) self.ids.append(id) line = [str(element) for element in line[1:]] #put into the list self.current_lines_listbox.insert(index, " ".join(line)) self.current_lines_listbox.grid(row=0, column=0, columnspan=3) self.submit.grid(row=1, column=1) self.cancel.grid(row=1, column=2) self.remove_button.grid(row=1, column=0) def submit(self): #expose the internal IDs to remove to the exterior methods self.ids = self.ids_internal self.top.destroy() def remove_line(self): """Take the active line and remove it""" line_to_remove = self.current_lines_listbox.get(ANCHOR) id_to_remove = int(line_to_remove.split(" ")[0]) #remove it from the ID list self.ids_internal.remove(id_to_remove) #remove it from the listbox self.current_lines_listbox = self.current_lines_listbox.delete(ANCHOR)
class PRGListBox(Frame): def __init__(self, master=None,**args): Frame.__init__(self, master,**args) scrollbar = Scrollbar(self, orient=VERTICAL) #нужен для отображения длинных списков scrollbar.unbind("<Key-Up>") scrollbar.unbind("<Key-Down>") scrollbar.unbind("<Key-Left>") scrollbar.unbind("<Key-Right>") scrollbar.pack(side=RIGHT, fill=Y) self.lst = Listbox(self, yscrollcommand=scrollbar.set, bg="grey", selectmode=SINGLE) self.lst.insert(END,"Hide All") self.lst.insert(END,"Show All") self.lst.select_set(0) self.lst.pack(side=LEFT, fill=BOTH, expand=1) scrollbar.config(command=self.lst.yview)
def initUI(self): self.parent.title("Listbox") self.pack(fill=BOTH, expand=1) IP_list = ['IP Address 1', 'IP Address 2', 'IP Address 3', 'IP Address 4', 'IP Address 5', 'IP Address 6', 'IP Address 7', 'IP Address 8', 'IP Address 9', 'IP Address 10', 'IP Address 11', 'IP Address 12', 'IP Address 13', 'IP Address 14', 'IP Address 15', 'IP Address 16'] IP_numbers = ['150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1', '150.0.0.1'] lb = Listbox(self) for i in IP_list: lb.insert(END, i) lb.bind("<<ListboxSelect>>", self.onSelect) lb.place(x=20, y=20) self.var = StringVar() self.label = Label(self, text=0, textvariable=self.var) self.label.place(x=20, y=270) # self.columnconfigure(1, weight=1) self.columnconfigure(3, pad=7) self.rowconfigure(3, weight=1) self.rowconfigure(5, pad=7) #lbl = Label(self, text="Windows") lb.grid(sticky=W, pady=40, padx=50) #lb = Text(self) lb.grid(row=1, column=0, columnspan=2, rowspan=4, padx=50, sticky=E+W+S+N) abtn = Button(self, text="Activate") abtn.grid(row=1, column=3) cbtn = Button(self, text="Close") cbtn.grid(row=2, column=3, pady=4) hbtn = Button(self, text="Help") hbtn.grid(row=5, column=0, padx=5) obtn = Button(self, text="OK") obtn.grid(row=5, column=3)
def initUI(self): self.parent.title("Listbox") self.pack(fill=BOTH, expand=1) acts = ['Scarlett Johansson', 'Rachel Weiss', 'Natalie Portman', 'Jessica Alba'] lb = Listbox(self) for i in acts: lb.insert(END, i) lb.bind("<<ListboxSelect>>", self.onSelect) lb.place(x=20, y=20) self.var = StringVar() self.label = Label(self, text=0, textvariable=self.var) self.label.place(x=20, y=210)
def initUI(self): self.parent.title("Listbox") self.pack(fill=BOTH, expand=1) acts = ["Scarlett Johansson", "Rachel Weiss", "Natalie Portman", "Jessica Alba", "Angelina jolie", "Emma Stone", "Sandra Bullock", "Julia Roberts", "Jennifer Lawrence", "Mila Kunis", "Jennifer Aniston", "Charlize Theron", "Cameron Diaz", "Nicole Kidman", "Meryl Streep", "Reese Witherspoon"] lb = Listbox(self, selectmode="multiple") for i in acts: lb.insert(END, i) lb.bind("<<ListboxSelect>>", self.onSelect) lb.pack(pady=15) self.var = StringVar() self.label = Label(self, text=0, textvariable=self.var) self.label.pack()
class MiniWindow: def __init__(self,root,list): self.list = list self.mini = Toplevel(root) self.mini.wm_title("Matches") print (root.winfo_screenwidth()) self.mini.geometry("%dx%d+%d+%d" %(500,200,root.winfo_x()+root.winfo_width(),root.winfo_y())) self.filelist = Listbox(self.mini) for item in self.list: self.filelist.insert('end',str(item)) self.filelist.bind("<<ListboxSelect>>",self.onClick) self.filelist.pack(fill="both") def onClick(self,event): print(self.filelist.curselection()) index = int(self.filelist.curselection()[0]) link = self.list[index] filedir = os.path.dirname(link) if os.name == 'nt': os.startfile(filedir) elif os.name == 'posix': subprocess.Popen(["xdg-open",filedir])
class Tenacity2(KRCCModule): def __init__(self, root): super().__init__() self.arbitrary_list = [ ('bla', random.uniform(0, 500)), ('blub', random.randint(1, 10)), ('hurrz', 'yolo'), 'sploink', ] self.listbox = Listbox(root) self.canvas = Canvas(root) self.load() def __del__(self): self.canvas.destroy() self.listbox.destroy() def run(self): while not self.terminate: pass def name(self): return 'Tenacity 2' def load(self): for item in self.arbitrary_list: insert_item = 'error' if type(item) == type(''): insert_item = item elif type(item) == type(()): key = item[0] value = '%s' % item[1] if type(item[1]) == float: value = '%8.3f' % item[1] insert_item = '%s: %s' % (key, value) self.listbox.insert(END, insert_item) self.listbox.pack(side=LEFT, fill=Y) self.canvas.pack(side=RIGHT, fill=BOTH, expand=True)
class MemoryWatcher(): def __init__(self, parent): # Window stuff self.parent = parent self.parent.geometry("200x300") self.frame = Frame(parent) # List box stuff self.index = 2 self.memory_listener = MemoryListener(self.action) self.listbox = Listbox(self.frame) # Initialize the UI self.initUI() def action(self, data): mem = data[0] val = data[1] self.listbox.insert(hex(self.index), ("[" + hex(mem) + "]: " + hex(val))) self.index += 1 def handle_close(self): self.memory_listener.unregister() self.parent.destroy() def initUI(self): # Deal with the UI self.parent.title("Memory Watcher") self.frame.pack(fill=BOTH, expand=1) self.listbox.insert(1, "Memory changed: ") self.listbox.pack(fill=BOTH, expand=1) # Handle the closing event (unregister the event listener) self.parent.protocol("WM_DELETE_WINDOW", self.handle_close)
class SelectDeviceFrame(CopilotInnerFrame): def __init__(self, master, config, state): super(SelectDeviceFrame, self).__init__(master, config) self._state = state if self._state.action == 'copy': self._frame_lbl['text'] = 'Copy To Device' elif self._state.action == 'delete': self._frame_lbl['text'] = 'Delete From Device' self._next_btn['command'] = self._next_cmd self._dev_list = Listbox(self._master, font=self._config.item_font) self._dev_list.grid(row=1, column=0, columnspan=3, sticky='nsew') self._dev_list.configure(yscrollcommand=self._sb.set) self._sb['command'] = self._dev_list.yview self._refresh_drives() def _next_cmd(self): if len(self._dev_list.curselection()) > 0: item_idx = int(self._dev_list.curselection()[0]) self._state.to_device = self._parts[item_idx] if self._state.action == 'copy': self._new_state_window(DeviceToFrame, self._state) elif self._state.action == 'delete': self._new_state_window(CopyFileFrame, self._state) def _refresh_drives(self): self._parts = [] for drive in usb_drives(): for part in drive.partitions(): drive_opt = DriveOption(drive, part) self._parts.append(drive_opt) self._dev_list.insert('end', drive_opt)
def get_users(): scroll_y_listbox = Frame(window) scrollbar = Scrollbar(scroll_y_listbox, orient=VERTICAL) listbox = Listbox(scroll_y_listbox, yscrollcommand=scrollbar.set, borderwidth=0) scrollbar.config(command=listbox.yview) def process_login(e=None): username = listbox.get(ACTIVE) password = simpledialog.askstring( title="User Password", prompt=f"Please enter password for {listbox.get(ACTIVE)}", show="*") login = self.user_management.login(username, password) if login: messagebox.showinfo( title="Success", message=f"{login['username']} is now logged in") window.destroy() else: messagebox.showerror( title="Failed", message=f"Failed to login, wrong password.") def process_delete(e=None): confirm = messagebox.askyesnocancel( title=f"Delete {listbox.get(ACTIVE)}", message= f"Are you sure you want to remove account {listbox.get(ACTIVE)}" ) if confirm: self.user_management.delete(listbox.get(ACTIVE)) window.destroy() listbox.pack(side=LEFT, fill=BOTH, expand=1) listbox.bind("<Double-1>", process_login) listbox.bind("<Return>", process_login) listbox.focus() scrollbar.pack(side=RIGHT, fill=Y) scroll_y_listbox.pack(fill=BOTH, expand=1) options = Frame(window, bg="grey", pady=7, padx=7) select = Button(options, text="Login...", pady=5, padx=25, command=process_login) select.grid(row=0, column=0, pady=2) delete = Button(options, text="Delete", pady=5, padx=25, bg="red", fg="white", command=process_delete) delete.grid(row=0, column=1, padx=5) close = Button(options, text="Close", pady=5, padx=25, command=lambda: window.destroy()) close.grid(row=0, column=2, pady=2) options.pack(fill=X) for users in self.user_management.get_all_accounts(): listbox.insert(END, users[0]) wait.pack_forget()
class StaffFrame(LabelFrame): """Contains data of staffmeeteng""" def __init__(self, window, base, **kwargs): LabelFrame.__init__(self, window, **kwargs) self.base = base self.staff_id = None self.all_staff = [x[0] for x in self.base.get_all_staff()] 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_all_staff(self): return [x[0] for x in self.base.get_all_staff()] 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): if not isinstance(self.table.selection(), str): self.table.selection_remove(self.table.selection()[0]) def on_treeview_selected(self, event): self.another_staff.select_clear(0, 'end') def tables_tidying(self): self.another_staff.delete(0, 'end') used_staff = [x[0] for x in self.get_staff_from_table()] for member in self.get_all_staff(): if member not in used_staff: self.another_staff.insert('end', member) def add_member(self): if not self.another_staff.curselection(): pass else: self.table.insert( '', 'end', values=( self.another_staff.selection_get(), self.base.what_speciality( self.another_staff.selection_get() )[1] ) ) self.tables_tidying() def remove_member(self): 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 S_LT(): def __init__(self,File_geom,File_prop,Run_Name): self.File_geom = File_geom self.File_prop = File_prop self.Run_Name = Run_Name self.initialize() def initialize(self): self.get_available_scaling_laws() self.windows_nd_ScL() # structure of branch : [model,ScL,use_all_data,dimentio_used,µ,bmin_bmax,bg_hyp] self.branches = [] for self.model_i in self.selected_Model: self.nb_mfd_hyp() self.bmin_hyp = [] self.bmax_hyp = [] for self.i in range(self.nb_of_mfd): self.nb_b_hyp() self.bmin_hyp.append(self.bmin_hyp_i) self.bmax_hyp.append(self.bmax_hyp_i) self.nb_sc_hyp() self.nb_bg_hyp() for ScL_i,use_all_i,dim_i in zip(self.selected_ScL,self.use_all_ScL_data,self.dimention_used) : index_mfd = 0 for mfd_i in self.mfd_hyp: for bmin_i,bmax_i in zip(self.bmin_hyp[index_mfd],self.bmax_hyp[index_mfd]): for bg_hyp_i in self.bg_names: for sc_name in self.sc_names: branch_i = [self.model_i,ScL_i,use_all_i,dim_i,mfd_i,str(bmin_i)+'_'+str(bmax_i),bg_hyp_i,sc_name] self.branches.append(branch_i) index_mfd += 1 # file containing the branches names in the logic tree LT_log_name = str(self.Run_Name)+'/LT_log.txt' LT_log = open(LT_log_name, 'w') LT_log.write('Models\n') for self.model_i in self.selected_Model: LT_log.write(self.model_i+'\t') LT_log.write('\nSaling Laws\n') for ScL_i,use_all_i,dim_i in zip(self.selected_ScL,self.use_all_ScL_data,self.dimention_used) : if use_all_i == True : str_all_data = 'a' # ' a ' is for 'all data is used' else : str_all_data = 'm' # ' m ' is for 'mechanic specific data only' LT_log.write(ScL_i+' '+dim_i+' '+str_all_data+'\t') LT_log.write('\nMFD\tb value\n') index_mfd = 0 for mfd_i in self.mfd_hyp: LT_log.write('MFD_'+mfd_i+'\t') for bmin_i,bmax_i in zip(self.bmin_hyp[index_mfd],self.bmax_hyp[index_mfd]): LT_log.write('bmin_'+str(bmin_i)+'_bmax_'+bmax_i+'\t') LT_log.write('\n') index_mfd += 1 LT_log.write('Background\n') for bg_hyp_i in self.bg_names: LT_log.write('bg_'+bg_hyp_i+'\t') LT_log.write('\nscenario set\n') for sc_name in self.sc_names: LT_log.write('sc_'+sc_name+'\t') LT_log.close() '''#####################''' def windows_nd_ScL(self): self.w_ScL_nb = tk.Tk() self.w_ScL_nb.title('Number of scaling laws') label = Label(self.w_ScL_nb, text="\nHow many Scaling laws do you want to use?") label.pack() self.nb_of_scl = Entry(self.w_ScL_nb) self.nb_of_scl.pack() self.nb_of_scl.insert(INSERT,1) bou_ok_ScL = Button(self.w_ScL_nb, text=u'OK', command = self.OK_nb_Scl) bou_ok_ScL.pack() self.w_ScL_nb.mainloop() def OK_nb_Scl(self) : self.nb_of_scl = int(self.nb_of_scl.get()) self.w_ScL_nb.destroy() self.windows_ScL() def windows_ScL(self): self.var = {} self.dimention_used_box = {} self.ScLSelect_dim_used = {} self.ScLname_used = {} self.ScL_name = {} self.w_ScL = tk.Tk() self.w_ScL.title('Scaling laws') self.w_ScL.grid() row_i = 1 for i in range(self.nb_of_scl): self.ScLname_used["ScLname{0}".format(i)] = StringVar() self.ScL_name["ScLname{0}".format(i)] = Combobox(self.w_ScL, textvariable=self.ScLname_used["ScLname{0}".format(i)], values=self.available_scaling_laws,state = 'readonly', height = 5, width = 30) self.ScL_name["ScLname{0}".format(i)].current(0) self.ScL_name["ScLname{0}".format(i)].grid(column=0,row=row_i) self.var["use_all_ScL_data_{0}".format(i)] = StringVar() self.use_all_ScL_data_button = Checkbutton(self.w_ScL, text="Respect fault kinematic", variable=self.var["use_all_ScL_data_{0}".format(i)],onvalue="False", offvalue="True") self.use_all_ScL_data_button.grid(column=4,row= row_i) self.ScLSelect_dim_used["dimention_used_{0}".format(i)] = StringVar() self.dimention_used_box["dimention_used_{0}".format(i)] = Combobox(self.w_ScL, textvariable=self.ScLSelect_dim_used["dimention_used_{0}".format(i)], values=['Area','Length'],state = 'readonly', height = 5, width = 30) self.dimention_used_box["dimention_used_{0}".format(i)].current(0) self.dimention_used_box["dimention_used_{0}".format(i)].grid(column=8,row= row_i) row_i += 1 bou_ok_ScL = Button(self.w_ScL, text=u'OK', command = self.OK_Scl) bou_ok_ScL.grid(column=8,row= row_i ) self.w_ScL.mainloop() def OK_Scl(self) : self.dimention_used = [] self.use_all_ScL_data = [] self.selected_ScL = [] for i in range(self.nb_of_scl): self.selected_ScL.append(self.ScL_name["ScLname{0}".format(i)].get()) if self.var["use_all_ScL_data_{0}".format(i)].get() == 'False': self.use_all_ScL_data.append(False) else : self.use_all_ScL_data.append(True) self.dimention_used.append(self.dimention_used_box["dimention_used_{0}".format(i)].get()) self.w_ScL.destroy() check_ScL = [] for selected_ScL_i,use_all_ScL_data,dimention_used in zip(self.selected_ScL,self.use_all_ScL_data,self.dimention_used): line = str(selected_ScL_i)+str(use_all_ScL_data)+str(dimention_used) if not line in check_ScL: check_ScL.append(line) else: messagebox.showerror('Error','One scaling law has been selected twice\n please start again') self.win_model() '''#####################''' def win_model(self): self.get_available_models() self.w_model = tk.Tk() self.ModelSelect = StringVar() label = Label(self.w_model, text="\nWhich model do you want to use?") label.pack() self.Box_Model = Combobox(self.w_model, values=self.available_models,state = 'readonly', height = 5, width = 30) self.Box_Model.current(0) self.Box_Model.pack() bou_add_Model = Button(self.w_model, text=u'Add Model', command = self.Add_Model) bou_add_Model.pack() self.list_Model = Listbox(self.w_model, height = 5, width = 30) self.list_Model.pack() bou_del_Model = Button(self.w_model, text=u'Delete Selected Model', command = self.del_Model) bou_del_Model.pack() label = Label(self.w_model, text="\n\n\nWhen ready click \"OK\"") label.pack() bou_ok_Model = Button(self.w_model, text=u'OK', command = self.ok_Model) bou_ok_Model.pack() self.w_model.mainloop() def Add_Model(self): len_list = self.list_Model.size() compteur = 0 for i in range(len_list): if self.Box_Model.get() == self.list_Model.get(i): compteur = compteur + 1 if compteur == 0: self.list_Model.insert(END, self.Box_Model.get()) else: messagebox.showerror('Error','Model already selected') def del_Model(self): items = self.list_Model.curselection() pos=0 for i in items: idx = int(i) - pos self.list_Model.delete(idx,idx) pos = pos + 1 def ok_Model(self): self.selected_Model = [] longueur_liste = self.list_Model.size() for i in range(longueur_liste): if len(self.list_Model.get(i))!=0: self.selected_Model.append(self.list_Model.get(i)) if len(self.selected_Model)==0: messagebox.showerror('Error','Select at least one model') self.w_model.destroy() '''#####################''' def nb_mfd_hyp(self): self.w_mfd_nb = tk.Tk() self.w_mfd_nb.title('Number of MFD hypothesis for model : '+str(self.model_i)) label = Label(self.w_mfd_nb, text='\nHow many MFD hypothesis for model : '+str(self.model_i)+' do you want to use?') label.pack() self.nb_of_mfd = Entry(self.w_mfd_nb) self.nb_of_mfd.pack() self.nb_of_mfd.insert(INSERT,1) bou_ok = Button(self.w_mfd_nb, text=u'OK', command = self.OK_nb_mfd_hyp) bou_ok.pack() self.w_mfd_nb.mainloop() def OK_nb_mfd_hyp(self) : self.nb_of_mfd = int(self.nb_of_mfd.get()) self.w_mfd_nb.destroy() self.mfd_hyp() def mfd_hyp(self): self.mfd = {} self.w_mfd = tk.Tk() self.w_mfd.grid() self.w_mfd.title('Hypothesis on MFD for '+str(self.model_i)) row_i = 1 for i in range(self.nb_of_mfd): label = Label(self.w_mfd, text="Hypothesis "+str(i+1)) label.grid(column=0,row=row_i) self.mfd["nb_mfd_{0}".format(i)] = Entry(self.w_mfd) self.mfd["nb_mfd_{0}".format(i)].grid(column=1,row= row_i) if i == 0: self.mfd["nb_mfd_{0}".format(i)].insert(INSERT,'GR') elif i == 1: self.mfd["nb_mfd_{0}".format(i)].insert(INSERT,'YC') row_i +=1 bou_ok = Button(self.w_mfd, text=u'OK', command = self.OK_mfd_hyp) bou_ok.grid(column=4,row=row_i+1) #self.w_shear_mod.mainloop() def OK_mfd_hyp(self) : self.mfd_hyp = [] for i in range(self.nb_of_mfd): self.mfd_hyp.append(self.mfd["nb_mfd_{0}".format(i)].get()) self.w_mfd.destroy() '''#####################''' def nb_b_hyp(self): self.w_b_nb = tk.Tk() self.w_b_nb.title('Number of b value distribution for model : '+str(self.model_i) +'\nand MFD : ' + str(self.mfd_hyp[self.i])) label = Label(self.w_b_nb, text='\nHow many b value distribution hypothesis for model : '+str(self.model_i)+'\nand MFD : ' + str(self.mfd_hyp[self.i])+' do you want to use?') label.pack() self.nb_of_b = Entry(self.w_b_nb) self.nb_of_b.pack() self.nb_of_b.insert(INSERT,1) bou_ok = Button(self.w_b_nb, text=u'OK', command = self.OK_nb_b_hyp) bou_ok.pack() self.w_b_nb.mainloop() def OK_nb_b_hyp(self) : self.nb_of_b = int(self.nb_of_b.get()) self.w_b_nb.destroy() self.b_hyp() def b_hyp(self): self.bmin = {} self.bmax = {} self.w_b = tk.Tk() self.w_b.grid() self.w_b.title('Hypothesis on b value') row_i = 0 label = Label(self.w_b, text='\nHypothesis on b value for model '+str(self.model_i)+' and MFD : ' + str(self.mfd_hyp[self.i])) label.grid(column=0,row=row_i) row_i +=1 for i in range(self.nb_of_b): label = Label(self.w_b, text="Hypothesis "+str(i+1)+" for b min and b max") label.grid(column=0,row=row_i) self.bmin["nb_bmin_{0}".format(i)] = Entry(self.w_b) self.bmin["nb_bmin_{0}".format(i)].grid(column=4,row= row_i) self.bmin["nb_bmin_{0}".format(i)].insert(INSERT,0.9) self.bmax["nb_bmax_{0}".format(i)] = Entry(self.w_b) self.bmax["nb_bmax_{0}".format(i)].grid(column=6,row= row_i) self.bmax["nb_bmax_{0}".format(i)].insert(INSERT,1.1) row_i +=1 bou_ok = Button(self.w_b, text=u'OK', command = self.OK_b_hyp) bou_ok.grid(column=4,row=row_i+1) self.w_b.mainloop() def OK_b_hyp(self) : self.bmin_hyp_i = [] self.bmax_hyp_i = [] for i in range(self.nb_of_b): self.bmin_hyp_i.append(self.bmin["nb_bmin_{0}".format(i)].get()) self.bmax_hyp_i.append(self.bmax["nb_bmax_{0}".format(i)].get()) self.w_b.destroy() '''#####################''' def nb_sc_hyp(self): self.w_sc_nb = tk.Tk() self.w_sc_nb.title('Number of scenario sets for model : '+str(self.model_i)) label = Label(self.w_sc_nb, text='\nHow many scenario sets for model : '+str(self.model_i)+' do you want to use?') label.pack() self.nb_of_sc = Entry(self.w_sc_nb) self.nb_of_sc.pack() self.nb_of_sc.insert(INSERT,1) bou_ok = Button(self.w_sc_nb, text=u'OK', command = self.OK_nb_sc_hyp) bou_ok.pack() self.w_sc_nb.mainloop() def OK_nb_sc_hyp(self) : self.nb_of_sc = int(self.nb_of_sc.get()) self.w_sc_nb.destroy() self.sc_hyp() def sc_hyp(self): self.sc = {} self.w_sc = tk.Tk() self.w_sc.grid() self.w_sc.title('Hypothesis on scenario sets for '+str(self.model_i)) row_i = 0 for i in range(self.nb_of_sc): label = Label(self.w_sc, text="Hypothesis "+str(i+1)) label.grid(column=0,row=row_i) self.sc["sc_{0}".format(i)] = Entry(self.w_sc) self.sc["sc_{0}".format(i)].grid(column=6,row= row_i) self.sc["sc_{0}".format(i)].insert(INSERT,'Set_'+str(row_i+1)) row_i +=1 bou_ok = Button(self.w_sc, text=u'OK', command = self.OK_sc_hyp) bou_ok.grid(column=4,row=row_i+1) self.w_sc.mainloop() def OK_sc_hyp(self) : self.sc_names = [] for i in range(self.nb_of_sc): self.sc_names.append(self.sc["sc_{0}".format(i)].get()) self.w_sc.destroy() '''#####################''' def nb_bg_hyp(self): self.w_bg_nb = tk.Tk() self.w_bg_nb.title('Number of background hypothesis for model '+str(self.model_i)) label = Label(self.w_bg_nb, text='\nHow many background hypothesis for model '+str(self.model_i)+' do you want to use?') label.pack() self.nb_of_bg = Entry(self.w_bg_nb) self.nb_of_bg.pack() self.nb_of_bg.insert(INSERT,1) bou_ok = Button(self.w_bg_nb, text=u'OK', command = self.OK_nb_bg_hyp) bou_ok.pack() self.w_bg_nb.mainloop() def OK_nb_bg_hyp(self) : self.nb_of_bg = int(self.nb_of_bg.get()) self.w_bg_nb.destroy() self.bg_hyp() def bg_hyp(self): self.bg = {} self.w_bg = tk.Tk() self.w_bg.grid() self.w_bg.title('Hypothesis on background hypothesis for '+str(self.model_i)) row_i = 0 label = Label(self.w_bg, text='\nHypothesis on background hypothesis for '+str(self.model_i)) label.grid(column=0,row=row_i) row_i +=1 for i in range(self.nb_of_bg): label = Label(self.w_bg, text="Hypothesis "+str(i+1)) label.grid(column=0,row=row_i) self.bg["bg_{0}".format(i)] = Entry(self.w_bg) self.bg["bg_{0}".format(i)].grid(column=6,row= row_i) self.bg["bg_{0}".format(i)].insert(INSERT,'BG_'+str(row_i)) row_i +=1 bou_ok = Button(self.w_bg, text=u'OK', command = self.OK_bg_hyp) bou_ok.grid(column=4,row=row_i+1) self.w_bg.mainloop() def OK_bg_hyp(self) : self.bg_names = [] for i in range(self.nb_of_bg): self.bg_names.append(self.bg["bg_{0}".format(i)].get()) self.w_bg.destroy() '''#####################''' def get_available_models(self): NomFichier_InfosZonage = self.File_geom InfosZonage = np.genfromtxt(NomFichier_InfosZonage,dtype=[('U100'),('U100'),('f8'),('f8')],skip_header = 1) Column_model_name = list(map(lambda i : InfosZonage[i][0],range(len(InfosZonage)))) self.available_models = list(np.unique(np.array(Column_model_name))) def get_available_scaling_laws(self): self.available_scaling_laws = ['WC1994','Le2010','HB08','TMG2017']
inicio = Frame(root) label_inicio = Label(inicio, text="Variables de ejecución") label_inicio.grid(row=0, column=0, pady=10) label_inicio.config(font=('Verdana', 15)) inicio.pack() global listbox listbox = Listbox(root, font=("Verdana", 9), width=40, height=5) listbox.pack() for item in [ "Número de pruebas a realizar: ", "Datos de entrada: ", "Número de clústeres: ", "Criterio de parada: ", "Número de iteraciones: " ]: listbox.insert(END, item) botones = Frame(root) f_automatica = tk.Button(botones, font=("Verdana", 10), text="Inicialización Automática", command=clustering_automatico).grid(row=0, column=0, pady=10, padx=10) f_manual = tk.Button( botones, font=("Verdana", 10), text="Inicialización Manual", command=lambda: [reset_contador(), clustering_manual()]).grid(row=0, column=1, pady=10)
def second_window(root, info): def next_step(): idxs = lbox.curselection() for blogger in idxs: name = bloggers()[blogger] if name not in info['bloggers']: info['bloggers'].append(name) if 'Blogs' in info['platforms']: blog_posts(root, info) else: third_window(root, info) def cantfind(info=info): idxs = lbox.curselection() for blogger in idxs: name = bloggers()[blogger] if name not in info['bloggers']: info['bloggers'].append(name) add_blogger(info=info) def active_next(*args): send.state(['!disabled', 'active']) def back(): idxs = lbox.curselection() for blogger in idxs: name = bloggers()[blogger] if name not in info['bloggers']: info['bloggers'].append(name) first_window(root, info=info) c = ttk.Frame(root, padding=(5, 0, 0, 0)) c.grid(column=0, row=0, sticky=(N, W, E, S)) background_image = tkinter.PhotoImage(file='%s/Desktop/natappy/images/moon.gif' % home) background_label = tkinter.Label(c, image=background_image) background_label.image = background_image background_label.place(x=0, y=0, relwidth=1, relheight=1) root.grid_columnconfigure(0, weight=3) root.grid_rowconfigure(0, weight=3) lbox = Listbox(c, selectmode=MULTIPLE) lbox.grid(column=0, row=1, rowspan=11, columnspan=7, sticky=( N, W, S), padx=(10, 10), pady=(1, 1), ipadx=75) yscroll = ttk.Scrollbar(command=lbox.yview, orient=VERTICAL) yscroll.grid(row=0, column=0, padx=(0, 10), sticky=(N, W, S)) lbox.configure(yscrollcommand=yscroll.set) for blogger in bloggers(): lbox.insert(END, blogger) lbox.bind("<<ListboxSelect>>") lbox.yview_scroll(40, 'units') cantfind = ttk.Button(c, text='Add new bloggers', command=cantfind) cantfind.grid(column=4, row=1, padx=(10, 0), sticky=(N, S, E, W), pady=(20, 10)) send = ttk.Button(c, text='Next', command=next_step, default='active', state='disabled') send.grid(column=6, row=11, sticky=E, pady=20, padx=(2, 20)) close = ttk.Button(c, text='Back', command=back, default='active') close.grid(column=5, row=11, sticky=S + E, pady=20, padx=2) lbox.bind('<<ListboxSelect>>', active_next) if info['bloggers']: for blogger in info['bloggers']: i = bloggers().index(blogger) lbox.selection_set(i) active_next() for i in range(len(bloggers()), 2): lbox.itemconfigure(i, background='#f0f0ff') c.grid_columnconfigure(0, weight=1) c.grid_rowconfigure(5, weight=1) root.title('2/5 Select bloggers') root.geometry('680x550+300+40')
class MemberChecker(PanedWindow): def __init__(self, parent): PanedWindow.__init__(self, parent, background="white") self.parent = parent self.init_data() self.init_log() self.init_ui() self.update_status() def init_data(self): self.data_store = api.DataStore() def init_log(self): self.entrance_log = entrance_log.EntranceLog() def init_ui(self): self.parent.title("Member Checker") self.columnconfigure(3, weight=3) self.pack(fill=BOTH, expand=True) self.input = StringVar() self.input_entry = Entry(self, textvariable=self.input) self.input_entry.bind('<Return>', self.submit) self.input_entry.grid(row=0, column=0, columnspan=3, sticky=E + W) self.result = StringVar() self.result_label = Label(self, textvariable=self.result) self.result_label.grid(row=3, column=0, columnspan=3, sticky=E + W) self.name = StringVar() name_label = Label(self, textvariable=self.name) name_label.grid(row=2, column=0, columnspan=3, sticky=E + W) self.status = StringVar() status_label = Label(self, textvariable=self.status) status_label.grid(row=4, column=0, columnspan=4, sticky=E + W) submit_button = Button(self, text="Submit", command=self.submit) submit_button.grid(row=1, column=2) enter_without_card_button = Button(self, text="Enter without card", command=self.enter_without_card) enter_without_card_button.grid(row=1, column=0) enter_member_without_card_button = Button(self, text="Enter member without card", command=self.enter_member_without_card) enter_member_without_card_button.grid(row=1, column=1) self.entrance_log_list = Listbox(self) self.entrance_log_list.grid(row=0, column=3, rowspan=4, sticky=E + W + S + N) self.input_entry.focus() def load_data(self): if messagebox.askyesno("Load new API Data", "Are you sure you want to load the new API data? All previous data will be removed. The program might be unresponsive for a few seconds, but don't kill it, please! It has feelings too."): self.data_store.load_api_data() def enter_by_identification(self, identification): member = self.data_store.find_member_by_identification(identification) if member is None: if messagebox.askyesno("Not a member", "This university identification is not registered as a member. Do you want to let them in as a non-member?"): self.enter_non_member_by_identification(identification) else: self.enter_member(member) def enter_by_barcode(self, barcode): member = self.data_store.find_member_by_barcode(barcode) if member is None: if messagebox.askyesno("Not a member", "This barcode is not registered as a member. Do you want to let them in as a non-member?"): self.enter_non_member_by_barcode(barcode) else: self.enter_member(member) def enter_non_member_by_identification(self, identification): self.entrance_log.enter_non_member_by_identification(identification) self.enter_non_member() def enter_non_member_by_barcode(self, barcode): self.entrance_log.enter_non_member_by_barcode(barcode) self.enter_non_member() def enter_without_card(self): self.clear_result() self.entrance_log.enter_without_card() self.enter_non_member() self.input_entry.focus() def enter_member(self, member): inside_result = self.entrance_log.is_member_inside(member) if inside_result[0]: if not messagebox.askyesno("Already inside", "This membership card has already been used to enter at {}. Are you sure you want to register it again? Normally you should let this person enter without card (and bill them accordingly).".format( inside_result[1])): return self.entrance_log.enter_member(member) self.result.set('Member!') self.result_label.configure(background='green') self.name.set(member['firstName'] + ' ' + member['lastName']) self.update_status() def enter_non_member(self): self.result.set('Not a member!') self.result_label.configure(background='red') self.name.set('Not in the database') self.update_status() def enter_member_without_card(self): name = self.input.get() if len(name) == 0: messagebox.showinfo('Name required', 'Please enter the name of this person!') return self.entrance_log.enter_member_without_card(name) self.result.set('Member without card!') self.result_label.configure(background="orange") self.name.set('') self.input.set('') self.update_status() def clear_result(self): self.result.set('') self.result_label.configure(background='white') self.name.set('') def submit(self, event=None): self.clear_result() entry = self.input.get() if helpers.is_valid_identification(entry): self.enter_by_identification(entry) elif helpers.is_valid_barcode(entry): self.enter_by_barcode(entry) else: messagebox.showinfo('Invalid entry', 'The data entered was not recognized as a valid bar code or a valid university identification. You should click \'enter without card\' to let this person in.') return self.input.set('') self.input_entry.focus() def clear_log(self): if messagebox.askyesno("Clear log", "Are you sure you want to clear the log of all people who entered?"): self.entrance_log.clear_log() self.update_status() def update_status(self): self.status.set("{} members inside. Total: {}".format(self.entrance_log.members_inside_count(), self.entrance_log.inside_count())) logs = self.entrance_log.get_latest_logs(15) self.entrance_log_list.delete(0, 15) for l in logs: s = l['timestamp'] + ": " data = l['data'] if 'member_id' in data: member = self.data_store.find_member(data['member_id']) s += member['firstName'] + " " + member['lastName'] elif 'barcode' in data: s += data['barcode'] elif 'identification' in data: s += data['identification'] elif 'name' in data: s += '[no card]' + data['name'] else: s += "-" self.entrance_log_list.insert(0, s)
class ChoixEcole: def __init__(self): # Initialise l'application change le titre et la positionne self.root = Tk() self.root.title("ChoixEcole") """Ouvre la base de données""" basededonne = filedialog.askopenfilename( title="Ouvrir un fichier", filetypes=[("db file", ".db")] ) model.connec(basededonne) """Ajoute un menu""" menubar = Menu(self.root) self.root.config(menu=menubar) menufichier = Menu(menubar, tearoff=0) menubar.add_cascade(label="Fichier", menu=menufichier) menufichier.add_command(label="Enregistrer ", command=self.save_file) menufichier.add_command(label="Enregistrer sous", command=self.save_file_as) self.filename = () self.root.resizable(False, False) self.entry_ecole = tkscrolled.ScrolledText(self.root, width=40, height=10,) self.button = [] self.ecolesselect = {} ######################################################################## # NOTES # ######################################################################## # On considère les notes entrées par l'utilisateur (sous forme de # "StringVar"). À chaque modification d'une de ces variables, on met # tout à jour. self.notes_vars = { "maths": StringVar(self.root), "physique": StringVar(self.root), "si": StringVar(self.root), "informatique": StringVar(self.root), "anglais": StringVar(self.root), "francais": StringVar(self.root), } for var in self.notes_vars.values(): var.trace("w", self.update) # self.notes représente soit une erreur de saisie des notes (avec None) # soit un dictionnaire "matière -> note(float)". self.notes = None ######################################################################## # CHOIX # ######################################################################## # On crée un dictonnaire modifié a chaque clique sur la ListeBox. self.choix = { "regions": None, "specialites": None, "alternance": None, "concours": None, "annee": None, } self.varsbuttons = { "specialites": IntVar(self.root), "regions": IntVar(self.root), "concours": IntVar(self.root), "alternance": IntVar(self.root), "annee": IntVar(self.root), "ecole": IntVar(self.root), } ######################################################################## # RENDU FORMULAIRE NOTES # ######################################################################## self.scale = Scale( self.root, orient="horizontal", from_=0, to=100, resolution=1, tickinterval=25, length=100, label="Augmentation %", command=self.update, ) Label(self.root, text="Maths").grid(row=2, column=1) Entry(self.root, textvariable=self.notes_vars["maths"]).grid(row=3, column=1) Label(self.root, text="Physique").grid(row=4, column=1) Entry(self.root, textvariable=self.notes_vars["physique"]).grid(row=5, column=1) Label(self.root, text="Si").grid(row=6, column=1) Entry(self.root, textvariable=self.notes_vars["si"]).grid(row=7, column=1) Label(self.root, text="Informatique").grid(row=8, column=1) Entry(self.root, textvariable=self.notes_vars["informatique"]).grid( row=9, column=1 ) Label(self.root, text="Anglais").grid(row=10, column=1) Entry(self.root, textvariable=self.notes_vars["anglais"]).grid(row=11, column=1) Label(self.root, text="Francais").grid(row=12, column=1) Entry(self.root, textvariable=self.notes_vars["francais"]).grid( row=13, column=1 ) ######################################################################## # RENDU FORMULAIRE choix # ######################################################################## self.specialites = Listbox( self.root, selectmode="multiple", exportselection=0, width=20, height=10 ) Label(self.root, text="Specialite").grid(row=0, column=6) self.specialites = Listbox( self.root, selectmode="multiple", exportselection=0, width=20, height=10 ) Label(self.root, text="Specialite").grid(row=0, column=6) self.regions = Listbox( self.root, selectmode="multiple", exportselection=0, width=20, height=10 ) Label(self.root, text="Region").grid(row=0, column=7) self.alternance = Listbox(self.root, exportselection=0, width=6, height=3) Label(self.root, text="Alternance").grid(row=11, column=6) self.concours = Listbox( self.root, selectmode="multiple", exportselection=0, width=20, height=10 ) Label(self.root, text="Admission").grid(row=0, column=9) self.annee = Listbox(self.root, exportselection=0, width=6, height=3) Label(self.root, text="Année").grid(row=11, column=7) self.specialites.grid(row=2, column=6, rowspan=10, padx=10) self.regions.grid(row=2, column=7, rowspan=10, padx=10) self.alternance.grid(row=13, column=6, rowspan=10, padx=10) self.concours.grid(row=2, column=9, rowspan=10, padx=10) self.annee.grid(row=13, column=7, rowspan=10, padx=10) ######################################################################## # Insertion des Bouton Peu importe # ######################################################################## Checkbutton( self.root, variable=self.varsbuttons["specialites"], text="Peu importe", command=self.update, ).grid(row=1, column=6) Checkbutton( self.root, variable=self.varsbuttons["regions"], text="Peu importe", command=self.update, ).grid(row=1, column=7) Checkbutton( self.root, variable=self.varsbuttons["alternance"], text="Peu importe", command=self.update, ).grid(row=12, column=6) Checkbutton( self.root, variable=self.varsbuttons["concours"], text="Peu importe", command=self.update, ).grid(row=1, column=9) Button( self.root, text="Plus d'information", command=self.information, width=15 ).grid(row=2, column=31) Button(self.root, text="Prix", command=self.calculprix, width=15).grid( row=2, column=32 ) ######################################################################## # Insertion des données # ######################################################################## for specialite in model.renvoie_specialites(): self.specialites.insert("end", specialite) for region in model.renvoie_regions(): self.regions.insert("end", region) for alternance in ["Oui", "Non"]: self.alternance.insert("end", alternance) for concours in model.renvoie_admission(): self.concours.insert("end", concours) for annee in ["3/2", "5/2"]: self.annee.insert("end", annee) ######################################################################## # On bind les ListBox # ######################################################################## self.entry_ecole.grid(row=2, column=20, rowspan=10) self.scale.grid(row=0, column=1, rowspan=2) self.specialites.bind("<<ListboxSelect>>", self.update) self.regions.bind("<<ListboxSelect>>", self.update) self.alternance.bind("<<ListboxSelect>>", self.update) self.concours.bind("<<ListboxSelect>>", self.update) self.annee.bind("<<ListboxSelect>>", self.update) self.update() self.root.mainloop() def valide_maj_notes(self): ######################################################################## # NOTES # ######################################################################## # On récupere la note entrée et on la vérifie try: notes = {} for nom_matiere, note_var in self.notes_vars.items(): note_float = float(note_var.get()) if note_float > 20 or note_float < 0: raise ValueError() else: if len(note_var.get()) in (2, 1): pass elif note_var.get()[2] == "." and len(note_var.get()) < 6: pass elif note_var.get()[1] == "." and len(note_var.get()) < 5: pass else: raise ValueError note_float += (self.scale.get() * note_float) / 100 notes[nom_matiere] = min(20,note_float) notes["modelisation"] = (notes["maths"] + notes["si"]) / 2 self.notes = notes except ValueError: # Une erreur est survenue lors de la conversion des notes self.notes = None def maj_choix(self): ######################################################################## # NOTES # ######################################################################## # On récupere l'index de la spécialite et le texte coché pour les autres variables # Et en fonction de certains cas on dit que self.choix=None self.choix = { "specialites": model.renvoie_idspe( self.specialites.get(i) for i in self.specialites.curselection() ), "regions": tuple(self.regions.get(i) for i in self.regions.curselection()), "concours": tuple( self.concours.get(i) for i in self.concours.curselection() ), "alternance": tuple( self.alternance.get(i) for i in self.alternance.curselection() ), "annee": tuple(self.annee.get(i) for i in self.annee.curselection()), } for cle in self.varsbuttons: if self.varsbuttons[cle].get() == 1: eval('self.'+cle+'.selection_clear(0, "end")') for cle in self.choix: if not self.choix[cle] or self.varsbuttons[cle].get() == 1: self.choix[cle] = None def update(self, *inutile): self.valide_maj_notes() self.maj_choix() self.construit_ecoles() self.affichage() def construit_ecoles(self): """On récupere les écoles disponibles dans la bdd et on les stocke """ self.ecolesselect = {} if self.notes != None: for j, ecoles in enumerate(model.filtre(self.choix, self.notes)): self.ecolesselect[j] = { "var": IntVar(self.root), "id": ecoles[0], "nom": ecoles[1], "admission": ecoles[2], "region": ecoles[3], "Alternance": ecoles[4], "Acronyme": ecoles[5], "Spe": ecoles[6], } def information(self): ######################################################################## # Information # ######################################################################## # Renvoie les spécialite offerte par l'école en fonction du choix de l'utilisateur window = Toplevel(self.root) window.resizable(True, True) vsb = Scrollbar(window, orient="vertical") vsb.grid(row=0, column=1, sticky="ns") hsb = Scrollbar(window, orient="horizontal") hsb.grid(row=1, column=0, sticky="ew") ca = Canvas(window, yscrollcommand=vsb.set, xscrollcommand=hsb.set) ca.grid(row=0, column=0, sticky="news") vsb.config(command=ca.yview) hsb.config(command=ca.xview) window.grid_rowconfigure(0, weight=1) window.grid_columnconfigure(0, weight=1) fr = Frame(ca) i=1 for a in ["Nom","Admission","Region","Alternance","Specialite"]: Label(fr, text=a).grid(row=0, column=i) i+=2 if self.choix["specialites"] == None: ListeSpe = list(self.specialites.get(0, "end")) else: ListeSpe = [ self.specialites.get(i) for i in self.specialites.curselection() ] if self.choix["alternance"] == None: alternance = ["Oui", "Non"] else: alternance = [self.choix["alternance"][0]] ligne = 1 for ecole in self.ecolesselect.values(): if ecole["var"].get() == 1: for i in [value for (key,value) in self.ecolesselect.items() if value['nom']==ecole['nom'] and value["Spe"] in ListeSpe and value["Alternance"] in alternance ]: j=1 for texte in [i["nom"],i["admission"],i["region"],i["Alternance"],i["Spe"]] : a = Entry(fr,width=60) a.insert(0,texte) a.grid(row=ligne, column=j) j+=2 a.config(state="disabled") ligne += 1 ca.create_window(0, 0, window=fr) fr.update_idletasks() ca.config(scrollregion=ca.bbox("all")) def calculprix(self): ecoles = [ecole["admission"] for ecole in self.ecolesselect.values() if ecole["var"].get()==1] prixboursier = model.prix_ecole(ecoles, "Boursier") prixnonboursier = model.prix_ecole(ecoles, "NonBoursier") Label(self.root, text=f"Prix Boursier \n {prixboursier}").grid(row=3, column=32) Label(self.root, text=f"Prix Non Boursier\n {prixnonboursier}").grid( row=4, column=32 ) def convertpdf(self, spacing=2): """Converti en PDF """ pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) data = [["Nom", "Résultat"]] admission, listeecoles = self.returntext() data += [[listeecoles[i], admission[i]] for i in range(len(admission))] col_width = pdf.w / 2.5 row_height = pdf.font_size for row in data: for item in row: pdf.cell(col_width, row_height * spacing, txt=item, border=1) pdf.ln(row_height * spacing) pdf.output(self.filename) def returntext(self): """Affiche le nom de l'école et a cote Refuse ou admis""" ecoleamoi = list( set( [ ecoles[5] for ecoles in model.filtre( {choix: None for choix in self.choix}, self.notes ) ] ) ) listeecoles = list( set( [ ecoles[5] for ecoles in model.filtre( {choix: None for choix in self.choix}, {Note: 20 for Note in self.notes}, ) ] ) ) admission = ["Admis"] * len(listeecoles) for i in range(len(listeecoles)): if listeecoles[i] not in ecoleamoi: admission[i] = "Refuse" return admission, listeecoles def save_file(self, whatever=None): if self.filename == (): self.save_file_as() self.convertpdf() def save_file_as(self, whatever=None): self.filename = filedialog.asksaveasfilename( defaultextension=".pdf", filetypes=[("PDF", "*.pdf"),] ) self.convertpdf() def affichage(self): """Affiche les écoles auquel on est admissible """ for i in self.button: i.destroy() self.entry_ecole.configure(state="normal") self.entry_ecole.delete(0.7, "end") if self.notes: textverification = [] for ecole in self.ecolesselect.values(): if ecole["Acronyme"] not in textverification: check = Checkbutton(text=ecole["Acronyme"], variable=ecole["var"]) self.entry_ecole.window_create(0.7, window=check) self.entry_ecole.insert(0.7, "\n") self.button.append(check) textverification.append(ecole["Acronyme"]) else: self.entry_ecole.insert(0.7, "Erreur lors de la saisie des notes.") self.entry_ecole.configure(state="disabled")
def append_commands(cls, commands: List[str], listbox: tk.Listbox, to_add: List[str]): for cmd in to_add: commands.append(cmd) listbox.insert(tk.END, cmd)
class UpdatePrompt: def __init__(self, tk_overlay, latest_version, changelog, download_version): print("Update Prompt > Started") self.download_version = download_version self.latest_version = latest_version["version"] tk_overlay.generate_frames() tk_overlay.generate_title() self.tk_overlay = tk_overlay self.root = tk_overlay.root self.back_frame = tk_overlay.back_frame self.front_frame = tk_overlay.front_frame self.root.attributes("-alpha", 1) self.root.bind("<Key>", self.key_press) width, height = 450, 400 monitor_info = win32api.GetMonitorInfo( win32api.MonitorFromPoint((0, 0))) work_area = monitor_info["Work"] self.root.minsize(width, height) self.root.geometry('%dx%d+%d+%d' % (width, height, work_area[2] - (width + 13), work_area[3] - (height + 36))) self.version_label = Label(self.front_frame, text=f"Version: {self.latest_version}", font=("Courier", 12), bg="#212121", fg="white") self.version_label.pack(side=TOP) self.date_label = Label(self.front_frame, text=changelog["date"], font=("Courier", 8), bg="#212121", fg="white") self.date_label.pack(side=TOP, pady=(0, 10)) self.changelog_frame = Frame(self.front_frame, bg="#212121") self.changelog_frame.pack(side=TOP, pady=(0, 5)) self.changelog_scrollbar_x = Scrollbar(self.changelog_frame, orient=HORIZONTAL) self.changelog_scrollbar_x.pack(side=BOTTOM, fill=X) self.changelog_scrollbar_y = Scrollbar(self.changelog_frame) self.changelog_scrollbar_y.pack(side=RIGHT, fill=Y) self.changelog_listbox = Listbox( self.changelog_frame, font=("Courier", 8), bg="#212121", fg="white", width=50, height=8, xscrollcommand=self.changelog_scrollbar_x.set, yscrollcommand=self.changelog_scrollbar_y.set, relief=FLAT) self.changelog_listbox.pack(side=TOP) self.changelog_scrollbar_x.config(command=self.changelog_listbox.xview) self.changelog_scrollbar_y.config(command=self.changelog_listbox.yview) for change in changelog["changes"]: self.changelog_listbox.insert(END, f"{change}\n") self.button_label = Label( self.front_frame, text=f"An update is available\nWould you like to install it?", font=("Courier", 16), bg="#212121", fg="white") self.button_label.pack(side=TOP, pady=10) self.divider_frame = Frame(self.front_frame, bg="white", width=120, height=1) self.divider_frame.pack(side=TOP, pady=(0, 10)) self.button_frame = Label(self.front_frame, bg="#212121") self.button_frame.pack(side=TOP) self.generate_button("Update", self.update) self.generate_button("Cancel", self.destroy_root) self.root.after(1, self.root.focus_force) self.root.mainloop() def generate_button(self, name, command): Button(self.button_frame, text=name, font=("Courier", 12), command=command, cursor="hand2", bd=0, bg="#212121", fg="white").pack(side=LEFT, padx=10) def destroy_root(self): self.destroy_back_frame() self.root.destroy() print("Root > Destroyed") def destroy_back_frame(self): self.back_frame.destroy() print("Update Prompt > Destroyed") def update(self): self.button_label.config(text="Downloading update...") self.button_frame.destroy() self.button_label.update() self.download_version(self.latest_version, self.on_download_finish) def on_download_finish(self): self.destroy_root() def key_press(self, event): key_events = {27: self.destroy_root} try: key_events[event.keycode]() except: pass
class TkApp(Tk): """ The main Tk class for the gui of simplebackup """ def __init__(self, **kwargs): super().__init__() title = "Simple Backup | V" + __version__ self.wm_title(title) self.protocol("WM_DELETE_WINDOW", self.on_closing) self.__thread = None self.__files_found = 0 self.__files_copied = 0 config_fn = kwargs.get("config_fn", user_config_filepath()) self.__app_config = Config_Handler(config_fn) self.__curr_config = self.__app_config.default_config_i self.__menu = Menu(self) self.__menu_file = Menu(self.__menu, tearoff=0) self.__menu_file.add_command(label="Quit", command=self.quit) self.__menu_config = Menu(self.__menu, tearoff=0) self.__menu_config.add_command(label="New", command=self.new_config) self.__menu_config.add_command(label="Load", command=self.switch_config) self.__menu_config.add_command(label="Change Default", command=self.change_default_config) self.__menu_config.add_command(label="Rename Current", command=self.rename_curr_conf) self.__menu_config.add_separator() self.__menu_config.add_command(label="Delete Current", command=self.delete_current_config) self.__menu_config.add_command(label="Delete All", command=self.reset_config) self.__menu_help = Menu(self.__menu, tearoff=0) self.__menu_help.add_command(label="Check for Updates", command=self.show_update_popup) self.__menu_help.add_command(label="About", command=self.show_about_popup) self.__menu.add_cascade(label="File", menu=self.__menu_file) self.__menu.add_cascade(label="Config", menu=self.__menu_config) self.__menu.add_cascade(label="Help", menu=self.__menu_help) self.__title_l = Label(self, text=title, font=(16)) self.__curr_config_name_l = Label(self) self.__last_backup_l = Label(self) self.__set_versions_to_keep = Button( self, text="Set Versions To Keep", command=self.update_versions_to_keep) self.__versions_to_keep_l = Label(self) self.__inc_folder_bnt = Button(self, text="Include Another Folder", command=self.add_included_folder) self.__included_folders_lb = Listbox(self, height=4) self.__included_folders_lb.bind("<<ListboxSelect>>", self.remove_selected_included_folder) self.__included_folders_lb.bind('<FocusOut>', self.deselect_included_folder) self.__excl_folder_bnt = Button(self, text="Exclude Another Folder", command=self.add_excluded_folder) self.__excluded_folders_lb = Listbox(self, height=4) self.__excluded_folders_lb.bind("<<ListboxSelect>>", self.remove_selected_excluded_folder) self.__excluded_folders_lb.bind('<FocusOut>', self.deselect_excluded_folder) self.__backup_to_bnt = Button(self, text="Backup Folder", command=self.set_backup_folder) self.__backup_folder_l = Label(self) self.__use_tar_l = Label(self, text="Use Tar") self.__use_tar_var = BooleanVar(self) self.__use_tar_var.trace_add("write", self.use_tar_changed) self.__use_tar = Checkbutton(self, variable=self.__use_tar_var) self.__backup_start_bnt = Button(self, text="Start Backup", command=self.start_backup) self.__progress = Progressbar(self) self.__statusbar = Label(self, text="ok", relief=SUNKEN, anchor=W) self._load_display() self._layout() if self.__app_config.show_help: self.show_help_popup() def on_closing(self): """ called on window close """ if self.__files_found != self.__files_copied: if messagebox.askyesno("Backup Running", "Do you want to stop the backup?"): self.destroy() else: self.destroy() def _load_display(self): """ load the widgets with data from the current backup config, should be run after loading a config from file and at app launch """ self.__versions_to_keep = self.__app_config.get_versions_to_keep( self.__curr_config) self.__included_folders = self.__app_config.get_included_folders( self.__curr_config) self.__excluded_folders = self.__app_config.get_excluded_folders( self.__curr_config) self.__backup_location = self.__app_config.get_backup_path( self.__curr_config) curr_conf_name = self.__app_config.get_config_name(self.__curr_config) self.__curr_config_name_l.config(text=f"Config Name: {curr_conf_name}") self.__last_backup_l.config( text= f"Last Known Backup: {self.__app_config.get_human_last_backup(self.__curr_config)}" ) self.__versions_to_keep_l.config(text=self.__versions_to_keep) self.__included_folders_lb.delete(0, END) self.__included_folders_lb.insert(0, *self.__included_folders) self.__excluded_folders_lb.delete(0, END) self.__excluded_folders_lb.insert(0, *self.__excluded_folders) self.__backup_folder_l.config(text=str(self.__backup_location)) self.__use_tar_var.set( self.__app_config.get_use_tar(self.__curr_config)) def switch_config(self): """ switches what config to use for backup, asks the user for a config to load, then loads the display """ next_combo = ask_combobox("Load Config", "Config Name", self.__app_config.get_config_names()) if next_combo != None: self.__curr_config = next_combo self._load_display() def change_default_config(self): """ switches what config to use for the default backup, asks the user for a config to load """ next_combo = ask_combobox("Default Config", "Config Name", self.__app_config.get_config_names()) if next_combo != None: self.__app_config.default_config_i = next_combo def rename_curr_conf(self): """ rename a existing config, will ask the user in a popup string input """ new_name = simpledialog.askstring("Rename Config", "New Name") if new_name: self.__app_config.rename_config(self.__curr_config, new_name) self._load_display() def new_config(self): """ creates a new empty backup config, asks the user for config name """ name = simpledialog.askstring("New Config", "Config Name") if name: self.__app_config.create_config(name) def delete_current_config(self): """ deletes the current selected config, asks the user to confirm """ if messagebox.askyesno( "Confirm Delete", "Are you sure you want to delete the current config?"): self.__app_config.remove_config(self.__curr_config) self.__curr_config = self.__app_config.default_config_i self._load_display() def reset_config(self): """ resets all the user configs, asks the user to confirm """ if messagebox.askyesno( "Confirm Reset", "Are you sure you want to reset the all configurations?"): self.__app_config.reset_config() self.__curr_config = self.__app_config.default_config_i self._load_display() def use_tar_changed(self, *args): """ called each time the __use_tar_var is called """ self.__app_config.set_use_tar(self.__curr_config, self.__use_tar_var.get()) def update_versions_to_keep(self): """ update the number of versions to keep, asks the user for a integer """ new_val = simpledialog.askinteger( "Versions To Keep", "How many backups do you want to keep", minvalue=0) if new_val != self.__versions_to_keep and new_val != None: self.__versions_to_keep = new_val self.__app_config.set_versions_to_keep(self.__curr_config, self.__versions_to_keep) self.__versions_to_keep_l.config(text=self.__versions_to_keep) def deselect_included_folder(self, *args): """ deselects the selected element in included folder """ self.__included_folders_lb.selection_clear(0, END) def deselect_excluded_folder(self, *args): """ deselects the selected element in excluded folder """ self.__excluded_folders_lb.selection_clear(0, END) def add_included_folder(self): """ add a folder to include in the backup, will ask user for a directory """ folder = filedialog.askdirectory(initialdir="/", title="Select Folder To Backup") if folder: folder_path = Path(folder) if folder_path != self.__backup_location: self.__included_folders.append(folder_path) self.__included_folders_lb.insert(END, folder_path) self.__app_config.set_included_folders(self.__curr_config, self.__included_folders) else: messagebox.showwarning( title="Folder Same As Backup Path", message= "You selected a folder that was the same as the backup path!" ) def remove_selected_included_folder(self, *args): """ remove the currently selected item in the included folders ListBox, will ask the user to confirm """ curr_selection = self.__included_folders_lb.curselection() # check if there is a selection if curr_selection: if messagebox.askyesno("Confirm Delete", "Are you want to delete this folder?"): index_to_del = curr_selection[0] self.__included_folders.pop(index_to_del) self.__app_config.set_included_folders(self.__curr_config, self.__included_folders) self.__included_folders_lb.delete(index_to_del) self.deselect_included_folder() def add_excluded_folder(self): """ add a folder to exclude in the backup, will ask user for a directory """ folder = filedialog.askdirectory(initialdir="/", title="Select Folder To Exclude") if folder: folder_path = Path(folder) self.__excluded_folders.append(folder_path) self.__excluded_folders_lb.insert(END, folder_path) self.__app_config.set_excluded_folders(self.__curr_config, self.__excluded_folders) def remove_selected_excluded_folder(self, *args): """ remove the currently selected item in the excluded folders ListBox, will ask the user to confirm """ curr_selection = self.__excluded_folders_lb.curselection() # check if there is a selection if curr_selection: if messagebox.askyesno("Confirm Delete", "Are you want to delete this folder?"): index_to_del = curr_selection[0] self.__excluded_folders.pop(index_to_del) self.__app_config.set_excluded_folders(self.__curr_config, self.__excluded_folders) self.__excluded_folders_lb.delete(index_to_del) self.deselect_excluded_folder() def set_backup_folder(self): """ sets the backup folder by asking the user for a base directory """ folder = filedialog.askdirectory(initialdir="/", title="Select Where To Backup To") if folder: self.__backup_location = Path(folder) self.__backup_folder_l.config(text=folder) self.__app_config.set_backup_path(self.__curr_config, self.__backup_location) def enable_gui(self): """ enable the gui buttons, run when a backup has completed """ self.__set_versions_to_keep.config(state=NORMAL) self.__inc_folder_bnt.config(state=NORMAL) self.__included_folders_lb.config(state=NORMAL) self.__excl_folder_bnt.config(state=NORMAL) self.__excluded_folders_lb.config(state=NORMAL) self.__backup_to_bnt.config(state=NORMAL) self.__use_tar.config(state=NORMAL) self.__backup_start_bnt.config(state=NORMAL) def disable_gui(self): """ disable the gui buttons, run when a backup is started """ self.__set_versions_to_keep.config(state=DISABLED) self.__inc_folder_bnt.config(state=DISABLED) self.__included_folders_lb.config(state=DISABLED) self.__excl_folder_bnt.config(state=DISABLED) self.__excluded_folders_lb.config(state=DISABLED) self.__backup_to_bnt.config(state=DISABLED) self.__use_tar.config(state=DISABLED) self.__backup_start_bnt.config(state=DISABLED) def progress_find_incr(self, finished=False): """ increment the progress bar for finding files by 1 or mark as finished :param finished: mark the progressbar as finished """ if finished: self.__progress.config(mode="determinate") self.__progress.config(value=0, maximum=self.__files_found) self.__statusbar.config(text=f"Found {self.__files_found} Files") else: self.__files_found += 1 self.__progress.config(value=self.__files_found) self.__statusbar.config( text=f"Searching For Files, Found {self.__files_found} Files") def progress_copy_incr(self): """ increment the progress bar for copying files by 1 or mark as finished """ self.__files_copied += 1 self.__progress.config(value=self.__files_copied) self.__statusbar.config( text=f"Copying Files {self.__files_copied} of {self.__files_found}" ) if self.__files_copied == self.__files_found: self.__app_config.set_last_backup(self.__curr_config, datetime.utcnow()) self.__last_backup_l.config( text= f"Last Known Backup: {self.__app_config.get_human_last_backup(self.__curr_config)}" ) self.__statusbar.config(text=f"Finished Copying Files") messagebox.showinfo(title="Finished Copying Files", message="Finished copying all found files") # reset counters self.__files_found = 0 self.__files_copied = 0 self.__progress.config(value=0, maximum=100) self.enable_gui() def start_backup(self): """ starts the backup """ if not self.__backup_location: # no backup location was selected messagebox.showwarning( title="Backup Location Not Selected", message="You did not select a backup location!") elif not self.__included_folders: # no folders where found to backup messagebox.showwarning( title="No Folders To Backup", message="You did not add any folders to backup!") else: # basic checks passed self.disable_gui() # prep for search of files self.__progress.config(mode="indeterminate") self.__statusbar.config(text=f"Searching For Files") self.__thread = BackupThread( self.__included_folders, self.__excluded_folders, self.__backup_location, self.__versions_to_keep, self.progress_find_incr, self.progress_copy_incr, self.handle_error_message, self.__use_tar_var.get()) # start the background backup thread so GUI wont appear frozen self.__thread.start() def show_about_popup(self): """ show the about popup """ messagebox.showinfo( "About", "simplebackup V" + __version__ + """ is cross-platform backup program written in python. This app was made by enchant97/Leo Spratt. It is licenced under GPL-3.0""") def show_update_popup(self): """ open the default webbrowser to the update url """ webbrowser.open(UPDATE_URL) def show_help_popup(self): messagebox.showinfo( "Welcome", """Welcome to simplebackup, here is some help to get you started: \nIncluding a folder to backup - Press the 'Include Folder' button to add a folder to backup - Remove a entry by clicking on the list below \nExcluding a folder from the backup - Press the 'Exclude Folder' button to skip a folder to backup - Remove a entry by clicking on the list below \nSetting where backups are stored - Click the 'Backup Folder' button to set where backups should be placed \nMultiple backup configs Use the 'Config' button in the titlebar to change varius settings like creating a new config \nVersions to keep This will be the number of backup to keep in the backup folder """) self.__app_config.show_help = False def handle_error_message(self, error_type: ERROR_TYPES): self.__statusbar.config(text="Failed") if error_type is ERROR_TYPES.NO_BACKUP_WRITE_PERMISION: messagebox.showerror("No Write Permission", ERROR_TYPES.NO_BACKUP_WRITE_PERMISION.value) elif error_type is ERROR_TYPES.NO_BACKUP_READ_PERMISION: messagebox.showerror("No Read Permission", ERROR_TYPES.NO_BACKUP_READ_PERMISION.value) elif error_type is ERROR_TYPES.NO_FILES_FOUND_TO_BACKUP: messagebox.showerror("No Files Found", ERROR_TYPES.NO_FILES_FOUND_TO_BACKUP.value) elif error_type is ERROR_TYPES.NO_BACKUP_PATH_FOUND: messagebox.showerror("No Backup Path Found", ERROR_TYPES.NO_BACKUP_PATH_FOUND.value) self.__progress.config(mode="determinate") self.enable_gui() def _layout(self): self.config(menu=self.__menu) self.__title_l.pack(fill=X, pady=10, padx=5) self.__curr_config_name_l.pack(fill=X, padx=5) self.__last_backup_l.pack(fill=X, padx=5) self.__set_versions_to_keep.pack(fill=X, padx=5) self.__versions_to_keep_l.pack(fill=X, padx=5) self.__inc_folder_bnt.pack(fill=X, padx=5) self.__included_folders_lb.pack(fill=X, padx=5) self.__excl_folder_bnt.pack(fill=X, padx=5) self.__excluded_folders_lb.pack(fill=X, padx=5) self.__backup_to_bnt.pack(fill=X, padx=5) self.__backup_folder_l.pack(fill=X, padx=5) self.__use_tar_l.pack(fill=X, padx=5) self.__use_tar.pack(fill=X, padx=5) self.__backup_start_bnt.pack(fill=X, padx=5) self.__progress.pack(fill=X) self.__statusbar.pack(side=BOTTOM, fill=X) self.wm_minsize(300, self.winfo_height()) self.wm_resizable(True, False)
acceleration_x = Queue(queuelen) acceleration_y = Queue(queuelen) acceleration_z = Queue(queuelen) ax, bx, cx, dx, ex, fx = [0], [0], [0], [0], [0], [0] ay, by, cy, dy, ey, fy, fy1, fy2 = [0], [0], [0], [0], [0], [0], [0], [0] top = Tk() top.geometry("300x450") # tkinter界面长宽,根据像素点来的,每个不同的分辨率电脑上显示不一样 top.title("监控") # 设置tkinter界面名字 mpluser('TkAgg') devices = find_all_serial_devices() mlistbox = Listbox(top, height=3) for item in devices: mlistbox.insert("end", item) mlistbox.pack() Button(top, text='打开串口', command=serial_toggle).pack() Button(top, text='全部记录表', command=SerialAll).pack() Button(top, text='湿度记录表', command=SerialHumidity).pack() Button(top, text='温度记录表', command=SerialTemp).pack() Button(top, text='人体红外记录表', command=SerialHumenboey).pack() Button(top, text='超声波测距记录表', command=SerialUltrasonic).pack() Button(top, text='光敏电阻记录表', command=SerialPhotoresistance).pack() Button(top, text='三轴加速度记录表', command=Serialxyx).pack() mtext = Text(top) mtext.pack() start_time = get_time() top.mainloop()
class GUI(Frame): def __init__(self, master=None, val=0): super().__init__(master) self.master = master self.val = val self.parametros = [] self.master.title("EDD - TytusDB") self.master.iconbitmap('img/logo.ico') self.master.deiconify() self.initComp(val) def initComp(self, val): self.centrar(val) if val == 1: self.agregarComp() elif val == 2: self.agregarComp2() elif val == 3: self.agregarComp3() def ventanaFunciones(self): self.master.iconify() v2 = Toplevel() image = Image.open('img/function.png') background_image = ImageTk.PhotoImage(image.resize((1060, 660))) background_label = Label(v2, image=background_image) background_label.place(x=0, y=0, relwidth=1, relheight=1) v2.protocol("WM_DELETE_WINDOW", lambda: self.on_closing(v2, self.master)) app2 = GUI(master=v2, val=2) app2.mainloop() def ventanaReporte(self): self.master.iconify() v3 = Tk() v3['bg'] = "#0f1319" v3.protocol("WM_DELETE_WINDOW", lambda: self.on_closing(v3, self.master)) app3 = GUI(master=v3, val=3) app3.mainloop() def on_closing(self, win, root): if messagebox.askokcancel("Salir", "¿Seguro que quieres salir?"): win.destroy() root.deiconify() def centrar(self, val): if val == 1: ancho = 500 alto = 500 elif val == 2: ancho = 1060 alto = 660 else: ancho = 1150 alto = 650 x_ventana = self.winfo_screenwidth() // 2 - ancho // 2 y_ventana = self.winfo_screenheight() // 2 - alto // 2 posicion = str(ancho) + "x" + str(alto) + "+" + str( x_ventana) + "+" + str(y_ventana - 35) self.master.resizable(width=False, height=False) self.master.geometry(posicion) # Menu principal def agregarComp(self): # self.titulo = Label(self.master, text="Tytus DB", bg="#5d6d7e", font="System 42 bold", fg="white", pady=12) # self.titulo.pack(fill=X) self.btn2 = Button(self.master, text="FUNCIONES", bg="#33868a", activebackground="#225b5e", bd=0, font="Arial 18", pady=12, width=14, command=lambda: self.ventanaFunciones()) self.btn2.pack(side=TOP, pady=(150, 25)) self.btn3 = Button(self.master, text="REPORTES", bg="#33868a", activebackground="#225b5e", font="Arial 18", bd=0, pady=12, width=14, command=lambda: self.ventanaReporte()) self.btn3.pack(side=TOP, pady=(0, 25)) self.btnSalir = Button(self.master, text="SALIR", bg="#bf4040", activebackground="#924040", font="Arial 18", bd=0, pady=0, width=14, command=exit) self.btnSalir.pack(side=TOP, pady=(0, 25)) # Ventana de funciones def agregarComp2(self): # self.titulo2 = Label(self.master, text="FUNCIONALIDAD", bg="#0f1319", fg="#45c2c5", # font=("Century Gothic", 40), pady=2) # self.titulo2.grid(row=0, column=0, sticky='ew', columnspan=3, pady=(0, 0)) lbl1 = Label(self.master, text="Bases de datos", font=("Century Gothic", 21), bg="#0f1319", fg="#ffffff") lbl1.grid(row=1, column=0, padx=(55, 150), pady=(100, 25)) lbl2 = Label(self.master, text="Tablas", font=("Century Gothic", 21), bg="#0f1319", fg="#ffffff") lbl2.grid(row=1, column=1, padx=(65, 150), pady=(100, 25)) lbl3 = Label(self.master, text="Tuplas", font=("Century Gothic", 21), bg="#0f1319", fg="#ffffff") lbl3.grid(row=1, column=2, padx=(120, 150), pady=(100, 25)) # Bases de datos btnCreateDB = Button( self.master, text="Create database", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog(["database"], "Create DB")) btnCreateDB.grid(row=2, column=0, sticky=W, padx=(65, 0), pady=(0, 25)) btnshowDBS = Button( self.master, text="Show databases", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: print("Método para mostrar bases de datos")) btnshowDBS.grid(row=3, column=0, sticky=W, padx=(65, 0), pady=(0, 25)) btnAlterDB = Button( self.master, text="Alter database", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog(["databaseOld", "databaseNew"], "Alter database")) btnAlterDB.grid(row=4, column=0, sticky=W, padx=(65, 0), pady=(0, 25)) btnDropDB = Button( self.master, text="Drop database", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog(["database"], "Drop DB")) btnDropDB.grid(row=5, column=0, sticky=W, padx=(65, 0), pady=(0, 25)) btnLoadfile = Button(self.master, text="Load CSV", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog( ["file", "database", "table"], "Load file")) btnLoadfile.grid(row=6, column=0, sticky=W, padx=(65, 0), pady=(0, 25)) # Tablas btnCreateTb = Button( self.master, text="Create table", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog( ["database", "tableName", "numberColumns"], "Create table")) btnCreateTb.grid(row=2, column=1, sticky=W, padx=(20, 0), pady=(0, 25)) btnShowTb = Button( self.master, text="Show tables", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog(["database"], "Show tables")) btnShowTb.grid(row=3, column=1, sticky=W, padx=(20, 0), pady=(0, 25)) btnAlterTb = Button( self.master, text="Alter table", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog( ["database", "tableOld", "tableNew"], "Alter table")) btnAlterTb.grid(row=4, column=1, sticky=W, padx=(20, 0), pady=(0, 25)) btnDropTb = Button(self.master, text="Drop table", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog( ["database", "tableName"], "Drop table")) btnDropTb.grid(row=5, column=1, sticky=W, padx=(20, 0), pady=(0, 25)) btnAlterAdd = Button( self.master, text="Alter add", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog( ["database", "tableName", "columnName"], "Alter add")) btnAlterAdd.grid(row=6, column=1, sticky=W, padx=(20, 0), pady=(0, 25)) btnAlterDrop = Button( self.master, text="Alter drop", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog( ["database", "tableName", "columnNumber"], "Alter drop")) btnAlterDrop.grid(row=7, column=1, sticky=W, padx=(20, 0), pady=(0, 25)) btnExtractTb = Button(self.master, text="Extract table", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=16, command=lambda: self.simpleDialog( ["database", "table"], "Extract table")) btnExtractTb.grid(row=8, column=1, sticky=W, padx=(20, 0), pady=(0, 25)) # Tuplas: btnInsertTp = Button(self.master, text="Insert", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=12, command=lambda: self.simpleDialog( ["database", "table", "columns"], "Insertar")) btnInsertTp.grid(row=2, column=2, sticky=W, padx=(100, 0), pady=(0, 25)) btnUpdateTp = Button( self.master, text="Update", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=12, command=lambda: self.simpleDialog([ "database", "table", "id", "columnNumber", "value" ], "Actualizar valor")) btnUpdateTp.grid(row=3, column=2, sticky=W, padx=(100, 0), pady=(0, 25)) btnDeleteTp = Button( self.master, text="Delete", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=12, command=lambda: self.simpleDialog(["database", "tableName", "id"], "Eliminar registro")) btnDeleteTp.grid(row=4, column=2, sticky=W, padx=(100, 0), pady=(0, 25)) btnTruncateTp = Button(self.master, text="Truncate", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=12, command=lambda: self.simpleDialog( ["database", "tableName"], "Vaciar tabla")) btnTruncateTp.grid(row=5, column=2, sticky=W, padx=(100, 0), pady=(0, 25)) btnExtractTp = Button( self.master, text="Extract", bg="#abb2b9", font=("Courier New", 14), borderwidth=0.5, pady=6, width=12, command=lambda: self.simpleDialog(["database", "table", "id"], "Extraer tupla")) btnExtractTp.grid(row=6, column=2, sticky=W, padx=(100, 0), pady=(0, 25)) # Digitador def simpleDialog(self, params, fun): self.parametros.clear() tmp = [] dialog = Tk() dialog['bg'] = "#0f1319" dialog.title(fun) dim = len(params) for i in range(dim): Label(dialog, text=params[i] + ":", bg="#0f1319", fg="#ffffff", font=("Century Gothic", 12)).grid(row=i, padx=(12, 1), pady=(2, 2), sticky=SW) if params[0] == "file": btnFile = Button(dialog, text="Examinar...", command=lambda: self.cargarArchivo(btnFile)) btnFile.grid(row=0, column=1, pady=(15, 2), padx=(0, 18), sticky="ew") for j in range(dim - 1): entry = Entry(dialog) entry.grid(row=j + 1, column=1, padx=(0, 18)) tmp.append(entry) else: for j in range(dim): entry = Entry(dialog) entry.grid(row=j, column=1, padx=(0, 18)) tmp.append(entry) submit = Button(dialog, text="OK", bg="#45c2c5", borderwidth=0.5, pady=6, width=10, command=lambda: self.getParams(tmp, dialog)) submit.grid(row=dim + 1, columnspan=2, pady=(8, 10)) dialog.mainloop() def getParams(self, params, dialog): for param in params: self.parametros.append(param.get()) dialog.destroy() print(self.parametros) def cargarArchivo(self, btn): filename = filedialog.askopenfilename(filetypes=[("csv files", "*.csv")]) self.parametros.append(filename) btn.configure(text=filename[filename.rfind('/') + 1:]) # Ventana de reporte def agregarComp3(self): self.titulo3 = Label(self.master, text="Árbol AVL", bg="#0f1319", fg="#45c2c5", font=("Century Gothic", 42), pady=12) self.titulo3.pack(fill=X) self.scrollbar = Scrollbar(self.master) self.scrollbar.pack(side=RIGHT, fill=Y) self.listbox = Listbox(self.master, yscrollcommand=self.scrollbar.set, height=21, width=20, bg="#ecf0f1", font=("Century Gothic", 12)) self.listbox.pack(side=LEFT, padx=(60, 0)) self.scrollbar.config(command=self.listbox.yview) self.panel = Label(self.master, bg="#ecf0f1", height=31, width=110) self.panel.pack(side=TOP, pady=(40, 0)) self.desplegarDB() self.listbox.bind("<<ListboxSelect>>", self.displayData) def desplegarDB(self): for i in range(1, 26, 1): self.listbox.insert(END, "Base de datos " + str(i)) def displayData(self, event): selection = event.widget.curselection() if selection: index = selection[0] data = event.widget.get(index) self.titulo3.configure(text=data)
class ProblemBrowser(object): def __init__(self): self.action = None self.root = root = Tk() root.title('Never gonna fold you up') root.protocol("WM_DELETE_WINDOW", self.close) root.pack_propagate(True) scrollbar = Scrollbar(root, orient=tkinter.VERTICAL) self.problem_list = Listbox(root, exportselection=False, yscrollcommand=scrollbar.set) self.problem_list.pack(expand=True, fill=tkinter.BOTH, side=tkinter.LEFT) scrollbar.config(command=self.problem_list.yview) scrollbar.pack(side=tkinter.LEFT, fill=tkinter.Y) self.problem_list.bind('<<ListboxSelect>>', lambda evt: self.populate_problem_canvas()) self.problem_canvas = Canvas(root, bd=1, relief=tkinter.SUNKEN, width=500, height=500) self.problem_canvas.pack(expand=True, fill=tkinter.BOTH, side=tkinter.LEFT) self.problem_canvas.bind("<Configure>", lambda evt: self.populate_problem_canvas()) button_frame = Frame(root) button_frame.pack(fill=tkinter.Y, side=tkinter.LEFT) # Reposition the figure so it's center of mass is at 0.5, 0.5 v = IntVar() self.center_cb = Checkbutton(button_frame, text="center", variable=v, command=lambda: self.populate_problem_canvas()) self.center_cb.var = v self.center_cb.pack(side=tkinter.TOP) # Use meshes.reconstruct_facets instead of polygon/hole logic. v = IntVar() self.reconstruct_cb = Checkbutton(button_frame, text="reconstruct", variable=v, command=lambda: self.populate_problem_canvas()) self.reconstruct_cb.var = v self.reconstruct_cb.pack(side=tkinter.TOP) self.populate_problems() self.current_problem_name = None self.current_problem = None def populate_problems(self): self.problem_list.delete(0, tkinter.END) for file in sorted((get_root() / 'problems').iterdir()): self.problem_list.insert(tkinter.END, file.stem) def populate_problem_canvas(self): sel = self.problem_list.curselection() if not sel: return assert len(sel) == 1 name = self.problem_list.get(sel[0]) if name != self.current_problem_name: self.current_problem_name = name self.current_problem = load_problem(name) if self.current_problem: p = self.current_problem if self.center_cb.var.get(): p = center_problem(p) if self.reconstruct_cb.var.get(): facets = meshes.reconstruct_facets(p) facets = meshes.keep_real_facets(facets, p) skeleton = [e for f in facets for e in edges_of_a_facet(f)] p = Problem(facets, skeleton) draw_problem(self.problem_canvas, p) def run(self): self.root.mainloop() def close(self): if self.root: self.root.destroy() self.root = None
class CopyToMoveTo: """ Minimalist file manager intended to be used independently or alongside Windows Explorer """ def __init__(self, root): """ Setup window geometry, init settings, define widgets + layout """ self.master = root self.master.title("CopyTo-MoveTo") self.master.iconbitmap(f"{dirname(__file__)}/icon.ico") if system() != "Windows": self.master.withdraw() messagebox.showwarning( "Incompatible platform", "CopyTo-MoveTo currently supports Windows platforms only.") raise SystemExit #Settings: self.settings_show_hidden = BooleanVar() self.settings_include_files = BooleanVar(value=True) self.settings_ask_overwrite = BooleanVar() self.settings_ask_overwrite.trace("w", self.settings_exclusives) self.settings_rename_dupes = BooleanVar(value=True) self.settings_rename_dupes.trace("w", self.settings_exclusives) self.settings_multiselect = BooleanVar(value=True) self.settings_select_dirs = BooleanVar(value=True) self.settings_select_dirs.trace("w", self.settings_mutuals) self.settings_select_files = BooleanVar(value=True) self.settings_select_files.trace("w", self.settings_mutuals) self.settings_geometry = None self.appdata_dir = getenv("APPDATA") + "/CopyTo-MoveTo" self.appdata_path = self.appdata_dir + "/settings.json" self.settings = self.init_settings() if self.settings: self.settings_geometry = self.settings["geometry"] self.settings_show_hidden.set(self.settings["show_hidden"]) self.settings_include_files.set(self.settings["include_files"]) self.settings_ask_overwrite.set(self.settings["ask_overwrite"]) self.settings_rename_dupes.set(self.settings["rename_dupes"]) self.settings_multiselect.set(self.settings["multiselect"]) self.settings_select_dirs.set(self.settings["select_dirs"]) self.settings_select_files.set(self.settings["select_files"]) self.dialog_showing = BooleanVar() self.help_showing = BooleanVar() self.about_showing = BooleanVar() self.master.protocol("WM_DELETE_WINDOW", self.master_close) self.master.bind("<Control-w>", self.master_close) #Geometry: self.master.minsize(width=450, height=200) if self.settings_geometry: self.master.geometry(self.settings_geometry) self.master.update() else: self.master.geometry("600x400") self.master.update_idletasks() (width_offset, height_offset) = Ufd.get_offset(self.master) self.master.geometry(f"+{width_offset}+{height_offset}") self.master.update_idletasks() # Menu: self.main_menu = Menu(self.master) self.master.config(menu=self.main_menu) self.file_menu = Menu(self.main_menu, tearoff=0) self.settings_menu = Menu(self.main_menu, tearoff=0) self.main_menu.add_cascade(label="File", menu=self.file_menu) self.main_menu.add_cascade(label="Settings", menu=self.settings_menu) self.file_menu.add_command(label="Open Source(s)", accelerator="Ctrl+O", command=lambda: self.show_ufd(source=True)) self.master.bind("<Control-o>", lambda event: self.show_ufd(source=True)) self.file_menu.add_command(label="Open Destination(s)", accelerator="Ctrl+K+O", command=lambda: self.show_ufd(source=False)) self.master.bind("<Control-k>o", lambda event: self.show_ufd(source=False)) self.file_menu.add_separator() self.file_menu.add_command(label="Help / Commands", command=self.show_help) self.file_menu.add_command(label="About", command=self.show_about) #Settings menu: self.settings_menu.add_checkbutton(label="Show Hidden Files & Folders", variable=self.settings_show_hidden, onvalue=True, offvalue=False) self.settings_menu.add_checkbutton( label="Include Files in Tree", variable=self.settings_include_files, onvalue=True, offvalue=False) self.settings_menu.add_separator() self.settings_menu.add_checkbutton( label="Ask Overwrite", variable=self.settings_ask_overwrite, onvalue=True, offvalue=False) self.settings_menu.add_checkbutton(label="Rename Duplicates", variable=self.settings_rename_dupes, onvalue=True, offvalue=False) self.settings_menu.add_separator() self.settings_menu.add_checkbutton(label="Multiselect", variable=self.settings_multiselect, onvalue=True, offvalue=False) self.settings_menu.add_checkbutton(label="Select Folders", variable=self.settings_select_dirs, onvalue=True, offvalue=False) self.settings_menu.add_checkbutton(label="Select Files", variable=self.settings_select_files, onvalue=True, offvalue=False) self.main_menu.add_separator() #Menu commands: self.main_menu.add_command(label="Swap Selected", command=self.swap_selected) self.master.bind("<Control-s>", lambda event: self.swap_selected()) self.main_menu.add_command(label="Clear Selected", command=self.clear_selected) self.master.bind("<Control-x>", lambda event: self.clear_selected()) self.main_menu.add_command(label="Clear All", command=self.clear_all) self.master.bind("<Control-Shift-X>", lambda event: self.clear_all()) self.main_menu.add_separator() self.main_menu.add_command(label="COPY", command=lambda: self._submit(copy=True)) self.master.bind("<Control-Shift-Return>", lambda event: self._submit(copy=True)) self.main_menu.add_command(label="MOVE", command=lambda: self._submit(copy=False)) self.master.bind("<Control-Return>", lambda event: self._submit(copy=False)) # Body: self.paneview = PanedWindow(self.master, sashwidth=7, bg="#cccccc", bd=0, orient="vertical") self.top_pane = PanedWindow(self.paneview) self.bottom_pane = PanedWindow(self.paneview) self.paneview.add(self.top_pane) self.paneview.add(self.bottom_pane) self.label_source = Label(self.top_pane, text="Source(s):") self.label_dest = Label(self.bottom_pane, text="Destination(s):") self.y_scrollbar_source = Scrollbar(self.top_pane, orient="vertical") self.x_scrollbar_source = Scrollbar(self.top_pane, orient="horizontal") self.y_scrollbar_dest = Scrollbar(self.bottom_pane, orient="vertical") self.x_scrollbar_dest = Scrollbar(self.bottom_pane, orient="horizontal") self.list_box_source = Listbox( self.top_pane, selectmode="extended", yscrollcommand=self.y_scrollbar_source.set, xscrollcommand=self.x_scrollbar_source.set) self.list_box_dest = Listbox(self.bottom_pane, selectmode="extended", yscrollcommand=self.y_scrollbar_dest.set, xscrollcommand=self.x_scrollbar_dest.set) self.x_scrollbar_source.config(command=self.list_box_source.xview) self.y_scrollbar_source.config(command=self.list_box_source.yview) self.x_scrollbar_dest.config(command=self.list_box_dest.xview) self.y_scrollbar_dest.config(command=self.list_box_dest.yview) # Layout: self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=1) self.top_pane.rowconfigure(1, weight=1) self.top_pane.columnconfigure(0, weight=1) self.bottom_pane.rowconfigure(1, weight=1) self.bottom_pane.columnconfigure(0, weight=1) self.paneview.paneconfigure(self.top_pane, minsize=100) self.paneview.paneconfigure(self.bottom_pane, minsize=100) self.paneview.grid(row=0, column=0, sticky="nsew") self.label_source.grid(row=0, column=0, sticky="w") self.list_box_source.grid(row=1, column=0, sticky="nsew") self.y_scrollbar_source.grid(row=1, column=1, sticky="ns") self.x_scrollbar_source.grid(row=2, column=0, sticky="ew") self.label_dest.grid(row=0, column=0, sticky="w", columnspan=2) self.list_box_dest.grid(row=1, column=0, sticky="nsew") self.y_scrollbar_dest.grid(row=1, column=1, sticky="ns") self.x_scrollbar_dest.grid(row=2, column=0, sticky="ew") def __str__(self): """Return own address""" return f"CopyTo-MoveTo @ {hex(id(self))}" def init_settings(self): """Called on startup, loads, parses, and returns json settings.""" if exists(self.appdata_path): with open(self.appdata_path, "r") as settings_file: settings_json = settings_file.read() settings = loads(settings_json) return settings else: return None def settings_exclusives(self, *args): """ Callback assigned to settings that are mutually exclusive, to prevent logical/runtime errors or unexpected behavior. """ if args[0] == "PY_VAR2": if self.settings_ask_overwrite.get() == 1: self.settings_rename_dupes.set(0) return elif args[0] == "PY_VAR3": if self.settings_rename_dupes.get() == 1: self.settings_ask_overwrite.set(0) return def settings_mutuals(self, *args): """ Prevent select folders & select files from being disabled concurrently If both are unselected, reselect the one we didn't just deselect on. """ if self.settings_select_dirs.get() == 0 \ and self.settings_select_files.get() == 0: if args[0] == "PY_VAR5": self.settings_select_files.set(1) elif args[0] == "PY_VAR6": self.settings_select_dirs.set(1) def master_close(self, event=None): """ Similar to utils.toplevel_close(). writes settings to the disk as json. """ settings = { "geometry": self.master.geometry(), "show_hidden": self.settings_show_hidden.get(), "include_files": self.settings_include_files.get(), "ask_overwrite": self.settings_ask_overwrite.get(), "rename_dupes": self.settings_rename_dupes.get(), "multiselect": self.settings_multiselect.get(), "select_dirs": self.settings_select_dirs.get(), "select_files": self.settings_select_files.get(), } settings_json = dumps(settings) if not exists(self.appdata_dir): mkdir(self.appdata_dir) with open(self.appdata_path, "w+") as settings_file: settings_file.write(settings_json) if self.dialog_showing.get() == 1: self.ufd.cancel() self.master.destroy() def toplevel_close(self, dialog, boolean): """ This callback flips the value for a given toplevel_showing boolean to false, before disposing of the toplevel. """ boolean.set(0) dialog.destroy() def swap_selected(self): """Swap list entries between source & destination""" source_selection = list(self.list_box_source.curselection()) dest_selection = list(self.list_box_dest.curselection()) for i in reversed(source_selection): item = self.list_box_source.get(i) self.list_box_source.delete(i) self.list_box_dest.insert("0", item) for i in reversed(dest_selection): item = self.list_box_dest.get(i) self.list_box_dest.delete(i) self.list_box_source.insert("0", item) def clear_selected(self): """Removes selected (highlighted) item(s) from a given listbox""" source_selection = list(self.list_box_source.curselection()) dest_selection = list(self.list_box_dest.curselection()) if source_selection: for i in reversed(source_selection): self.list_box_source.delete(i) self.list_box_source.selection_set(source_selection[0]) if dest_selection: for i in reversed(dest_selection): self.list_box_dest.delete(i) self.list_box_dest.selection_set(dest_selection[0]) def clear_all(self): """Clears both listboxes in the main UI, resetting the form.""" self.list_box_source.delete(0, "end") self.list_box_dest.delete(0, "end") def handled(fn): """Filesystem operations are wrapped here for error handling""" @wraps(fn) def inner(self, *args, **kwargs): try: fn(self, *args, **kwargs) return True except (PermissionError, FileNotFoundError) as err: self.skipped_err.append(f"{err.args[1]}:\n" + (" => ".join(args))) return False return inner @handled def _copy(self, path, destination): """Wrapper for shutil.copy2() || shutil.copytree()""" if isfile(path): copy2(path, destination) else: copytree(path, destination) @handled def _move(self, path, destination): """Wrapper for shutil.move()""" move(path, destination) @handled def _delete(self, path): """Wrapper for os.remove() || shutil.rmtree()""" if isfile(path): remove(path) elif isdir(path): rmtree(path) def disabled_ui(fn): """Menubar is disabled during operations""" @wraps(fn) def inner(self, *args, **kwargs): self.main_menu.entryconfig("File", state="disabled") self.main_menu.entryconfig("Settings", state="disabled") self.main_menu.entryconfig("Clear Selected", state="disabled") self.main_menu.entryconfig("Clear All", state="disabled") self.main_menu.entryconfig("COPY", state="disabled") self.main_menu.entryconfig("MOVE", state="disabled") fn(self, *args, **kwargs) self.main_menu.entryconfig("File", state="normal") self.main_menu.entryconfig("Settings", state="normal") self.main_menu.entryconfig("Clear Selected", state="normal") self.main_menu.entryconfig("Clear All", state="normal") self.main_menu.entryconfig("COPY", state="normal") self.main_menu.entryconfig("MOVE", state="normal") return inner def _submit(self, copy): """Thread/wrapper for submit() so we don't block the UI during operations""" self.thread = Thread(target=self.submit, args=(copy, ), daemon=True) self.thread.start() @disabled_ui def submit(self, copy): """ Move or copy each item in the origin list to the path in the destination list. Supports no more than one destination directory where copy == False. Ask Overwrite and Rename Dupes will alter the way we handle existing data standing in the way. By default, duplicates are renamed with an index. A messagebox can complain to the user if shutil raises a PermissionError, and the operation is skipped. """ if (self.list_box_dest.size() > 1) and not copy: messagebox.showwarning( "Invalid Operation", "Move operation only supports a single destination directory.") return sources = self.list_box_source.get(0, "end") destinations = self.list_box_dest.get(0, "end") self.skipped_err = [] for j, destination in enumerate(destinations): if isfile(destination): self.skipped_err.append(f"Invalid destination: {destination}") continue for i, source in enumerate(sources): self.progress(i, j) (_, filename) = split(source) future_destination = join(destination + sep, filename) if exists(future_destination): if not self.settings_ask_overwrite.get() \ and not self.settings_rename_dupes.get(): if not self._delete(future_destination): continue if self.settings_ask_overwrite.get(): if self.ask_overwrite(future_destination): if not self._delete(future_destination): continue else: continue if self.settings_rename_dupes.get(): future_destination = self.name_dupe(future_destination) if copy: if not self._copy(source, future_destination): continue else: if not self._move(source, future_destination): continue self.list_box_source.delete(0, "end") self.list_box_dest.delete(0, "end") if self.skipped_err: messagebox.showerror(title="Error(s)", message="\n\n".join(self.skipped_err)) @staticmethod def name_dupe(path): """ Renames the file or directory until it doesn't exist in the destination with that name anymore, by appending the filename with an index wrapped in parenthesis. (Windows platforms) file.txt => file (1).txt => file (2).txt """ if system() != "Windows": raise OSError("For use with Windows filesystems.") path_ = path (root, filename) = split(path_) if isdir(path_): title = filename ext = None else: (title, ext) = splitext(filename) filecount = 0 while exists(path_): filecount += 1 new_title = title + " (" + str(filecount) + ")" if ext: new_title = new_title + ext path_ = join(root, new_title) return path_ def ask_overwrite(self, future_destination): """Messagebox result returned as truth value""" return messagebox.askyesno( title="Path Conflict", message=f"Overwrite:\n\n{future_destination}?\n\n" \ f"YES - Overwrite\nNO - Skip" ) def progress(self, i, j): """ Visualize operands in GUI during operations i = current source operand index j = current destination operand index """ for y, _ in enumerate(self.list_box_source.get(0, "end")): if y != i: self.list_box_source.itemconfigure(y, bg="#FFFFFF", fg="#000000") else: self.list_box_source.itemconfigure(y, bg="#cccccc", fg="#000000") for x, _ in enumerate(self.list_box_dest.get(0, "end")): if x != j: self.list_box_dest.itemconfigure(x, bg="#FFFFFF", fg="#000000") else: self.list_box_dest.itemconfigure(x, bg="#cccccc", fg="#000000") self.master.update() #Toplevels: def show_about(self): """ Displays a static dialog that doesn't allow additional instances of itself to be created while showing. """ if self.about_showing.get() == 0: self.about_showing.set(1) try: with open(f"{dirname(__file__)}/about.txt", "r") as aboutfile: about_info = aboutfile.read() except FileNotFoundError: messagebox.showerror("Error", "File not found") self.about_showing.set(0) return else: self.about = Toplevel() self.about.title("About") self.about.iconbitmap(f"{dirname(__file__)}/icon.ico") self.about.geometry("600x400") self.about.resizable(0, 0) self.about.update_idletasks() (width_offset, height_offset) = Ufd.get_offset(self.about) self.about.geometry(f"+{width_offset-75}+{height_offset-75}") self.about.update_idletasks() self.about_message = Label( self.about, text=about_info, justify="left", wraplength=(self.about.winfo_width() - 25)) self.about_message.grid(sticky="nsew") self.about.protocol( "WM_DELETE_WINDOW", lambda: self.toplevel_close( self.about, self.about_showing)) def show_help(self): """ Displays a scrollable dialog that doesn't allow additional instances of itself to be created while showing. """ if self.help_showing.get() == 0: self.help_showing.set(1) try: with open(f"{dirname(__file__)}/help.txt", "r") as helpfile: help_info = helpfile.read() except FileNotFoundError: messagebox.showerror("Error", "File not found") self.help_showing.set(0) return else: self.help_window = Toplevel() self.help_window.title("Help") self.help_window.iconbitmap(f"{dirname(__file__)}/icon.ico") self.help_window.geometry("500x300") self.help_window.update_idletasks() (width_offset, height_offset) = Ufd.get_offset(self.help_window) self.help_window.geometry( f"+{width_offset+75}+{height_offset-75}") self.help_window.update_idletasks() self.message_y_scrollbar = Scrollbar(self.help_window, orient="vertical") self.help_text = Text( self.help_window, wrap="word", yscrollcommand=self.message_y_scrollbar.set) self.help_window.rowconfigure(0, weight=1) self.help_window.columnconfigure(0, weight=1) self.help_text.grid(row=0, column=0, sticky="nsew") self.message_y_scrollbar.grid(row=0, column=1, sticky="nse") self.message_y_scrollbar.config(command=self.help_text.yview) self.help_text.insert("end", help_info) self.help_text.config(state="disabled") self.help_window.protocol( "WM_DELETE_WINDOW", lambda: self.toplevel_close( self.help_window, self.help_showing)) def show_ufd(self, source=True): """ Display Ufd w/ appropriate kwargs => Populate GUI w/ result""" if self.dialog_showing.get() == 0: self.dialog_showing.set(1) self.ufd = Ufd(title="Add Items", show_hidden=self.settings_show_hidden.get(), include_files=self.settings_include_files.get(), multiselect=self.settings_multiselect.get(), select_dirs=self.settings_select_dirs.get(), select_files=self.settings_select_files.get(), unix_delimiter=False, stdout=False) for result in self.ufd(): if source: self.list_box_source.insert("end", result) else: self.list_box_dest.insert("end", result) self.dialog_showing.set(0)
class EntryOptionsWindow: instanciated: bool = False def __init__(self, ls: str, tk: Tk, select_path=False) -> None: if not EntryOptionsWindow.instanciated: self.select_path = select_path self.List = ls self.Tk = tk self.Root = Toplevel(self.Tk) self.Root.withdraw() self.Root.protocol("WM_DELETE_WINDOW", self.__close) self.ListFrame = Frame(self.Root) self.Box = Listbox(self.ListFrame, selectmode='extended', width=54, height=24) for i in globals()[self.List]: self.Box.insert(END, i) self.Scroll = Scrollbar(self.ListFrame, command=self.Box.yview) self.ButtonsFrame = Frame(self.Root) self.Scroll2 = Scrollbar(self.ButtonsFrame, command=self.Box.xview, orient='horizontal') self.Entry = Entry(self.ButtonsFrame) self.ButtonAdd = Button(self.ButtonsFrame, text='Добавить', command=self.__add_item) self.ButtonDel = Button(self.ButtonsFrame, text='Удалить', command=self.__del_item) self.ButtonDone = Button(self.ButtonsFrame, text='Готово', command=self.__save_list) self.ButtonExit = Button(self.ButtonsFrame, text='Отмена', command=self.__close) EntryOptionsWindow.instanciated = True self.main() def __add_item(self) -> None: if self.select_path: text = filedialog.askdirectory() else: text = self.Entry.get() if text: self.Box.insert(END, text) self.Entry.delete(0, END) def __del_item(self) -> None: select = list(self.Box.curselection()) select.reverse() for i in select: self.Box.delete(i) def __save_list(self) -> None: globals()[self.List] = list(self.Box.get(0, END)) self.__close() def __close(self) -> None: EntryOptionsWindow.instanciated = False self.Root.destroy() def main(self) -> None: self.Root.deiconify() center_win(self.Root, '500x405' if self.select_path else '500x430') self.Root.resizable(False, False) self.Root.title(f'Editing {self.List}') self.ListFrame.pack(side='top', fill='both', padx=2, pady=2) self.Box.pack(side='left', fill='both', expand=True, padx=2, pady=2) self.Scroll.pack(side='right', fill='y', padx=2, pady=2) self.Scroll2.pack(side='top', fill='x', padx=2, pady=2) self.Box.config(yscrollcommand=self.Scroll.set, xscrollcommand=self.Scroll2.set) self.ButtonsFrame.pack(side='top', padx=2, pady=2, fill='x') if not self.select_path: self.Entry.pack(fill='both', expand=True, anchor='w', side='top', padx=2, pady=6) self.ButtonAdd.pack(fill='x', side='left', padx=2, pady=2) self.ButtonDel.pack(fill='x', side='left', padx=2, pady=2) self.ButtonDone.pack(fill='x', side='left', padx=2, pady=2) self.ButtonExit.pack(fill='x', side='left', padx=2, pady=2) self.Root.mainloop()
class ShiftReduceApp(object): """ A graphical tool for exploring the shift-reduce parser. The tool displays the parser's stack and the remaining text, and allows the user to control the parser's operation. In particular, the user can shift tokens onto the stack, and can perform reductions on the top elements of the stack. A "step" button simply steps through the parsing process, performing the operations that ``nltk.parse.ShiftReduceParser`` would use. """ def __init__(self, grammar, sent, trace=0): self._sent = sent self._parser = SteppingShiftReduceParser(grammar, trace) # Set up the main window. self._top = Tk() self._top.title('Shift Reduce Parser Application') # Animations. animating_lock is a lock to prevent the demo # from performing new operations while it's animating. self._animating_lock = 0 self._animate = IntVar(self._top) self._animate.set(10) # = medium # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Initialize fonts. self._init_fonts(self._top) # Set up key bindings. self._init_bindings() # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_feedback(self._top) self._init_grammar(self._top) self._init_canvas(self._top) # A popup menu for reducing. self._reduce_menu = Menu(self._canvas, tearoff=0) # Reset the demo, and set the feedback frame to empty. self.reset() self._lastoper1['text'] = '' ######################################### ## Initialization Helpers ######################################### def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = tkinter.font.Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget('size')) self._boldfont = tkinter.font.Font(family='helvetica', weight='bold', size=self._size.get()) self._font = tkinter.font.Font(family='helvetica', size=self._size.get()) def _init_grammar(self, parent): # Grammar view. self._prodframe = listframe = Frame(parent) self._prodframe.pack(fill='both', side='left', padx=2) self._prodlist_label = Label(self._prodframe, font=self._boldfont, text='Available Reductions') self._prodlist_label.pack() self._prodlist = Listbox(self._prodframe, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._prodlist.pack(side='right', fill='both', expand=1) self._productions = list(self._parser.grammar().productions()) for production in self._productions: self._prodlist.insert('end', (' %s' % production)) self._prodlist.config(height=min(len(self._productions), 25)) # Add a scrollbar if there are more than 25 productions. if 1:#len(self._productions) > 25: listscroll = Scrollbar(self._prodframe, orient='vertical') self._prodlist.config(yscrollcommand = listscroll.set) listscroll.config(command=self._prodlist.yview) listscroll.pack(side='left', fill='y') # If they select a production, apply it. self._prodlist.bind('<<ListboxSelect>>', self._prodlist_select) # When they hover over a production, highlight it. self._hover = -1 self._prodlist.bind('<Motion>', self._highlight_hover) self._prodlist.bind('<Leave>', self._clear_hover) def _init_bindings(self): # Quit self._top.bind('<Control-q>', self.destroy) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Alt-q>', self.destroy) self._top.bind('<Alt-x>', self.destroy) # Ops (step, shift, reduce, undo) self._top.bind('<space>', self.step) self._top.bind('<s>', self.shift) self._top.bind('<Alt-s>', self.shift) self._top.bind('<Control-s>', self.shift) self._top.bind('<r>', self.reduce) self._top.bind('<Alt-r>', self.reduce) self._top.bind('<Control-r>', self.reduce) self._top.bind('<Delete>', self.reset) self._top.bind('<u>', self.undo) self._top.bind('<Alt-u>', self.undo) self._top.bind('<Control-u>', self.undo) self._top.bind('<Control-z>', self.undo) self._top.bind('<BackSpace>', self.undo) # Misc self._top.bind('<Control-p>', self.postscript) self._top.bind('<Control-h>', self.help) self._top.bind('<F1>', self.help) self._top.bind('<Control-g>', self.edit_grammar) self._top.bind('<Control-t>', self.edit_sentence) # Animation speed control self._top.bind('-', lambda e,a=self._animate:a.set(20)) self._top.bind('=', lambda e,a=self._animate:a.set(10)) self._top.bind('+', lambda e,a=self._animate:a.set(4)) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill='none', side='bottom') Button(buttonframe, text='Step', background='#90c0d0', foreground='black', command=self.step,).pack(side='left') Button(buttonframe, text='Shift', underline=0, background='#90f090', foreground='black', command=self.shift).pack(side='left') Button(buttonframe, text='Reduce', underline=0, background='#90f090', foreground='black', command=self.reduce).pack(side='left') Button(buttonframe, text='Undo', underline=0, background='#f0a0a0', foreground='black', command=self.undo).pack(side='left') def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Reset Parser', underline=0, command=self.reset, accelerator='Del') filemenu.add_command(label='Print to Postscript', underline=0, command=self.postscript, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label='Edit Grammar', underline=5, command=self.edit_grammar, accelerator='Ctrl-g') editmenu.add_command(label='Edit Text', underline=5, command=self.edit_sentence, accelerator='Ctrl-t') menubar.add_cascade(label='Edit', underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label='Step', underline=1, command=self.step, accelerator='Space') rulemenu.add_separator() rulemenu.add_command(label='Shift', underline=0, command=self.shift, accelerator='Ctrl-s') rulemenu.add_command(label='Reduce', underline=0, command=self.reduce, accelerator='Ctrl-r') rulemenu.add_separator() rulemenu.add_command(label='Undo', underline=0, command=self.undo, accelerator='Ctrl-u') menubar.add_cascade(label='Apply', underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton(label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar) viewmenu.add_separator() viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animate, value=0) animatemenu.add_radiobutton(label="Slow Animation", underline=0, variable=self._animate, value=20, accelerator='-') animatemenu.add_radiobutton(label="Normal Animation", underline=0, variable=self._animate, value=10, accelerator='=') animatemenu.add_radiobutton(label="Fast Animation", underline=0, variable=self._animate, value=4, accelerator='+') menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) helpmenu.add_command(label='Instructions', underline=0, command=self.help, accelerator='F1') menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar) def _init_feedback(self, parent): self._feedbackframe = feedbackframe = Frame(parent) feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3) self._lastoper_label = Label(feedbackframe, text='Last Operation:', font=self._font) self._lastoper_label.pack(side='left') lastoperframe = Frame(feedbackframe, relief='sunken', border=1) lastoperframe.pack(fill='x', side='right', expand=1, padx=5) self._lastoper1 = Label(lastoperframe, foreground='#007070', background='#f0f0f0', font=self._font) self._lastoper2 = Label(lastoperframe, anchor='w', width=30, foreground='#004040', background='#f0f0f0', font=self._font) self._lastoper1.pack(side='left') self._lastoper2.pack(side='left', fill='x', expand=1) def _init_canvas(self, parent): self._cframe = CanvasFrame(parent, background='white', width=525, closeenough=10, border=2, relief='sunken') self._cframe.pack(expand=1, fill='both', side='top', pady=2) canvas = self._canvas = self._cframe.canvas() self._stackwidgets = [] self._rtextwidgets = [] self._titlebar = canvas.create_rectangle(0,0,0,0, fill='#c0f0f0', outline='black') self._exprline = canvas.create_line(0,0,0,0, dash='.') self._stacktop = canvas.create_line(0,0,0,0, fill='#408080') size = self._size.get()+4 self._stacklabel = TextWidget(canvas, 'Stack', color='#004040', font=self._boldfont) self._rtextlabel = TextWidget(canvas, 'Remaining Text', color='#004040', font=self._boldfont) self._cframe.add_widget(self._stacklabel) self._cframe.add_widget(self._rtextlabel) ######################################### ## Main draw procedure ######################################### def _redraw(self): scrollregion = self._canvas['scrollregion'].split() (cx1, cy1, cx2, cy2) = [int(c) for c in scrollregion] # Delete the old stack & rtext widgets. for stackwidget in self._stackwidgets: self._cframe.destroy_widget(stackwidget) self._stackwidgets = [] for rtextwidget in self._rtextwidgets: self._cframe.destroy_widget(rtextwidget) self._rtextwidgets = [] # Position the titlebar & exprline (x1, y1, x2, y2) = self._stacklabel.bbox() y = y2-y1+10 self._canvas.coords(self._titlebar, -5000, 0, 5000, y-4) self._canvas.coords(self._exprline, 0, y*2-10, 5000, y*2-10) # Position the titlebar labels.. (x1, y1, x2, y2) = self._stacklabel.bbox() self._stacklabel.move(5-x1, 3-y1) (x1, y1, x2, y2) = self._rtextlabel.bbox() self._rtextlabel.move(cx2-x2-5, 3-y1) # Draw the stack. stackx = 5 for tok in self._parser.stack(): if isinstance(tok, Tree): attribs = {'tree_color': '#4080a0', 'tree_width': 2, 'node_font': self._boldfont, 'node_color': '#006060', 'leaf_color': '#006060', 'leaf_font':self._font} widget = tree_to_treesegment(self._canvas, tok, **attribs) widget.label()['color'] = '#000000' else: widget = TextWidget(self._canvas, tok, color='#000000', font=self._font) widget.bind_click(self._popup_reduce) self._stackwidgets.append(widget) self._cframe.add_widget(widget, stackx, y) stackx = widget.bbox()[2] + 10 # Draw the remaining text. rtextwidth = 0 for tok in self._parser.remaining_text(): widget = TextWidget(self._canvas, tok, color='#000000', font=self._font) self._rtextwidgets.append(widget) self._cframe.add_widget(widget, rtextwidth, y) rtextwidth = widget.bbox()[2] + 4 # Allow enough room to shift the next token (for animations) if len(self._rtextwidgets) > 0: stackx += self._rtextwidgets[0].width() # Move the remaining text to the correct location (keep it # right-justified, when possible); and move the remaining text # label, if necessary. stackx = max(stackx, self._stacklabel.width()+25) rlabelwidth = self._rtextlabel.width()+10 if stackx >= cx2-max(rtextwidth, rlabelwidth): cx2 = stackx + max(rtextwidth, rlabelwidth) for rtextwidget in self._rtextwidgets: rtextwidget.move(4+cx2-rtextwidth, 0) self._rtextlabel.move(cx2-self._rtextlabel.bbox()[2]-5, 0) midx = (stackx + cx2-max(rtextwidth, rlabelwidth))/2 self._canvas.coords(self._stacktop, midx, 0, midx, 5000) (x1, y1, x2, y2) = self._stacklabel.bbox() # Set up binding to allow them to shift a token by dragging it. if len(self._rtextwidgets) > 0: def drag_shift(widget, midx=midx, self=self): if widget.bbox()[0] < midx: self.shift() else: self._redraw() self._rtextwidgets[0].bind_drag(drag_shift) self._rtextwidgets[0].bind_click(self.shift) # Draw the stack top. self._highlight_productions() def _draw_stack_top(self, widget): # hack.. midx = widget.bbox()[2]+50 self._canvas.coords(self._stacktop, midx, 0, midx, 5000) def _highlight_productions(self): # Highlight the productions that can be reduced. self._prodlist.selection_clear(0, 'end') for prod in self._parser.reducible_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) ######################################### ## Button Callbacks ######################################### def destroy(self, *e): if self._top is None: return self._top.destroy() self._top = None def reset(self, *e): self._parser.initialize(self._sent) self._lastoper1['text'] = 'Reset App' self._lastoper2['text'] = '' self._redraw() def step(self, *e): if self.reduce(): return True elif self.shift(): return True else: if list(self._parser.parses()): self._lastoper1['text'] = 'Finished:' self._lastoper2['text'] = 'Success' else: self._lastoper1['text'] = 'Finished:' self._lastoper2['text'] = 'Failure' def shift(self, *e): if self._animating_lock: return if self._parser.shift(): tok = self._parser.stack()[-1] self._lastoper1['text'] = 'Shift:' self._lastoper2['text'] = '%r' % tok if self._animate.get(): self._animate_shift() else: self._redraw() return True return False def reduce(self, *e): if self._animating_lock: return production = self._parser.reduce() if production: self._lastoper1['text'] = 'Reduce:' self._lastoper2['text'] = '%s' % production if self._animate.get(): self._animate_reduce() else: self._redraw() return production def undo(self, *e): if self._animating_lock: return if self._parser.undo(): self._redraw() def postscript(self, *e): self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) ######################################### ## Menubar callbacks ######################################### def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) #self._stacklabel['font'] = ('helvetica', -size-4, 'bold') #self._rtextlabel['font'] = ('helvetica', -size-4, 'bold') #self._lastoper_label['font'] = ('helvetica', -size) #self._lastoper1['font'] = ('helvetica', -size) #self._lastoper2['font'] = ('helvetica', -size) #self._prodlist['font'] = ('helvetica', -size) #self._prodlist_label['font'] = ('helvetica', -size-2, 'bold') self._redraw() def help(self, *e): # The default font's not very legible; try using 'fixed' instead. try: ShowText(self._top, 'Help: Shift-Reduce Parser Application', (__doc__ or '').strip(), width=75, font='fixed') except: ShowText(self._top, 'Help: Shift-Reduce Parser Application', (__doc__ or '').strip(), width=75) def about(self, *e): ABOUT = ("NLTK Shift-Reduce Parser Application\n"+ "Written by Edward Loper") TITLE = 'About: Shift-Reduce Parser Application' try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def edit_grammar(self, *e): CFGEditor(self._top, self._parser.grammar(), self.set_grammar) def set_grammar(self, grammar): self._parser.set_grammar(grammar) self._productions = list(grammar.productions()) self._prodlist.delete(0, 'end') for production in self._productions: self._prodlist.insert('end', (' %s' % production)) def edit_sentence(self, *e): sentence = " ".join(self._sent) title = 'Edit Text' instr = 'Enter a new sentence to parse.' EntryDialog(self._top, sentence, instr, self.set_sentence, title) def set_sentence(self, sent): self._sent = sent.split() #[XX] use tagged? self.reset() ######################################### ## Reduce Production Selection ######################################### def _toggle_grammar(self, *e): if self._show_grammar.get(): self._prodframe.pack(fill='both', side='left', padx=2, after=self._feedbackframe) self._lastoper1['text'] = 'Show Grammar' else: self._prodframe.pack_forget() self._lastoper1['text'] = 'Hide Grammar' self._lastoper2['text'] = '' def _prodlist_select(self, event): selection = self._prodlist.curselection() if len(selection) != 1: return index = int(selection[0]) production = self._parser.reduce(self._productions[index]) if production: self._lastoper1['text'] = 'Reduce:' self._lastoper2['text'] = '%s' % production if self._animate.get(): self._animate_reduce() else: self._redraw() else: # Reset the production selections. self._prodlist.selection_clear(0, 'end') for prod in self._parser.reducible_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) def _popup_reduce(self, widget): # Remove old commands. productions = self._parser.reducible_productions() if len(productions) == 0: return self._reduce_menu.delete(0, 'end') for production in productions: self._reduce_menu.add_command(label=str(production), command=self.reduce) self._reduce_menu.post(self._canvas.winfo_pointerx(), self._canvas.winfo_pointery()) ######################################### ## Animations ######################################### def _animate_shift(self): # What widget are we shifting? widget = self._rtextwidgets[0] # Where are we shifting from & to? right = widget.bbox()[0] if len(self._stackwidgets) == 0: left = 5 else: left = self._stackwidgets[-1].bbox()[2]+10 # Start animating. dt = self._animate.get() dx = (left-right)*1.0/dt self._animate_shift_frame(dt, widget, dx) def _animate_shift_frame(self, frame, widget, dx): if frame > 0: self._animating_lock = 1 widget.move(dx, 0) self._top.after(10, self._animate_shift_frame, frame-1, widget, dx) else: # but: stacktop?? # Shift the widget to the stack. del self._rtextwidgets[0] self._stackwidgets.append(widget) self._animating_lock = 0 # Display the available productions. self._draw_stack_top(widget) self._highlight_productions() def _animate_reduce(self): # What widgets are we shifting? numwidgets = len(self._parser.stack()[-1]) # number of children widgets = self._stackwidgets[-numwidgets:] # How far are we moving? if isinstance(widgets[0], TreeSegmentWidget): ydist = 15 + widgets[0].label().height() else: ydist = 15 + widgets[0].height() # Start animating. dt = self._animate.get() dy = ydist*2.0/dt self._animate_reduce_frame(dt/2, widgets, dy) def _animate_reduce_frame(self, frame, widgets, dy): if frame > 0: self._animating_lock = 1 for widget in widgets: widget.move(0, dy) self._top.after(10, self._animate_reduce_frame, frame-1, widgets, dy) else: del self._stackwidgets[-len(widgets):] for widget in widgets: self._cframe.remove_widget(widget) tok = self._parser.stack()[-1] if not isinstance(tok, Tree): raise ValueError() label = TextWidget(self._canvas, str(tok.label()), color='#006060', font=self._boldfont) widget = TreeSegmentWidget(self._canvas, label, widgets, width=2) (x1, y1, x2, y2) = self._stacklabel.bbox() y = y2-y1+10 if not self._stackwidgets: x = 5 else: x = self._stackwidgets[-1].bbox()[2] + 10 self._cframe.add_widget(widget, x, y) self._stackwidgets.append(widget) # Display the available productions. self._draw_stack_top(widget) self._highlight_productions() # # Delete the old widgets.. # del self._stackwidgets[-len(widgets):] # for widget in widgets: # self._cframe.destroy_widget(widget) # # # Make a new one. # tok = self._parser.stack()[-1] # if isinstance(tok, Tree): # attribs = {'tree_color': '#4080a0', 'tree_width': 2, # 'node_font': bold, 'node_color': '#006060', # 'leaf_color': '#006060', 'leaf_font':self._font} # widget = tree_to_treesegment(self._canvas, tok.type(), # **attribs) # widget.node()['color'] = '#000000' # else: # widget = TextWidget(self._canvas, tok.type(), # color='#000000', font=self._font) # widget.bind_click(self._popup_reduce) # (x1, y1, x2, y2) = self._stacklabel.bbox() # y = y2-y1+10 # if not self._stackwidgets: x = 5 # else: x = self._stackwidgets[-1].bbox()[2] + 10 # self._cframe.add_widget(widget, x, y) # self._stackwidgets.append(widget) #self._redraw() self._animating_lock = 0 ######################################### ## Hovering. ######################################### def _highlight_hover(self, event): # What production are we hovering over? index = self._prodlist.nearest(event.y) if self._hover == index: return # Clear any previous hover highlighting. self._clear_hover() # If the production corresponds to an available reduction, # highlight the stack. selection = [int(s) for s in self._prodlist.curselection()] if index in selection: rhslen = len(self._productions[index].rhs()) for stackwidget in self._stackwidgets[-rhslen:]: if isinstance(stackwidget, TreeSegmentWidget): stackwidget.label()['color'] = '#00a000' else: stackwidget['color'] = '#00a000' # Remember what production we're hovering over. self._hover = index def _clear_hover(self, *event): # Clear any previous hover highlighting. if self._hover == -1: return self._hover = -1 for stackwidget in self._stackwidgets: if isinstance(stackwidget, TreeSegmentWidget): stackwidget.label()['color'] = 'black' else: stackwidget['color'] = 'black'
def openCalculator(handler): global conversionresulttext, fromCurrencyInput, toCurrencyInput, amountInput, calculatorWindow currencyapi = get("https://api.exchangeratesapi.io/latest", data=None) if currencyapi.status_code == 200: #Check for reponse exchangerates = loads(currencyapi.content.decode()) exchangerates["rates"]["DUCO"] = float(ducofiat) calculatorWindow = Toplevel() #calculatorWindow.geometry("420x420") calculatorWindow.resizable(False, False) calculatorWindow.title("Duino-Coin Wallet - Calculator") calculatorWindow.configure(background = backgroundColor) calculatorWindow.transient([root]) textFont2 = Font(calculatorWindow, size=12,weight="bold") textFont3 = Font(calculatorWindow, size=14,weight="bold") textFont = Font(calculatorWindow, size=12,weight="normal") Label(calculatorWindow, text="CURRENCY CONVERTER", background = backgroundColor, foreground = foregroundColor, font = textFont3).grid(row=0, column=0) Label(calculatorWindow, text="FROM", background = backgroundColor, foreground = foregroundColor, font = textFont2).grid(row=1, column=0) fromCurrencyInput = Listbox(calculatorWindow, exportselection=False, background = backgroundColor, foreground = foregroundColor, selectbackground = "#7bed9f", border="0", font=textFont, width="20", height="13") fromCurrencyInput.grid(row=2, column=0) i=0 for currency in exchangerates["rates"]: fromCurrencyInput.insert(i, currency) i = i+1 Label(calculatorWindow, text="TO", background = backgroundColor, foreground = foregroundColor, font = textFont2).grid(row=1, column=1) toCurrencyInput = Listbox(calculatorWindow, exportselection=False, foreground = foregroundColor, background = backgroundColor, selectbackground = "#7bed9f", border="0", font=textFont, width="20", height="13") toCurrencyInput.grid(row=2, column=1) i=0 for currency in exchangerates["rates"]: toCurrencyInput.insert(i, currency) i = i+1 toCurrencyInput.select_set(0) toCurrencyInput.event_generate("<<ListboxSelect>>") fromCurrencyInput.select_set(32) fromCurrencyInput.event_generate("<<ListboxSelect>>") Label(calculatorWindow, text="AMOUNT", background = backgroundColor, foreground = foregroundColor, font = textFont2).grid(row=3, column=0) def clear_ccamount_placeholder(self): amountInput.delete("0", "100") amountInput = Entry(calculatorWindow, background = "#7bed9f", foreground=foregroundColor, border="0", font=textFont, width="20") amountInput.grid(row=4, column=0) amountInput.insert("0", str(getBalance())) amountInput.bind("<FocusIn>", clear_ccamount_placeholder) Button(calculatorWindow, text="Convert", background = "#FEEEDA", foreground=foregroundColor, command=currencyConvert, width="22").grid(row=3, column=1, pady=(5, 0)) conversionresulttext = StringVar(calculatorWindow) conversionresulttext.set("RESULT: 0.0") conversionresultLabel = Label(calculatorWindow, textvariable=conversionresulttext, background = backgroundColor, foreground = foregroundColor, font = textFont2) conversionresultLabel.grid(row=4, column=1) Label(calculatorWindow, text=" ", background = backgroundColor, foreground = foregroundColor, font = textFont2).grid(row=5, column=0) calculatorWindow.mainloop()
class Searcher(Frame): """ Keyword Searcher This is a very simple python program, which is designed for finding specified key-word in files. Just for fun! """ def __init__(self, master=None, cnf={}, **kwargs): super(Searcher, self).__init__(master, cnf, **kwargs) self._root_path_var = StringVar() self._keyword_var = StringVar(self) self._listbox = None self._result_queue = None self.pack(fill=BOTH, expand=YES, padx=5, pady=5) self.make_widgets() self._consumer() # config for main window self.master.title('Keyword Searcher') def make_widgets(self): frm1 = Frame(self) frm1.pack(side=TOP, fill=X) Entry(frm1, textvariable=self._root_path_var, font=DEFAULT_FONT).pack(side=LEFT, fill=X, expand=YES) Button(frm1, text='Add directory', font=DEFAULT_FONT, command=lambda: self._root_path_var.set(askdirectory(title='Add directory'))).pack(side=RIGHT) frm2 = Frame(self) frm2.pack(side=TOP, fill=X) keyword_ent = Entry(frm2, textvariable=self._keyword_var, font=DEFAULT_FONT) keyword_ent.pack(side=LEFT, fill=X, expand=YES) Button(frm2, text='Find', font=DEFAULT_FONT, command=self.find).pack(side=RIGHT) vs = Scrollbar(self) hs = Scrollbar(self) self._listbox = Listbox(self) vs.pack(side=RIGHT, fill=Y) vs.config(command=self._listbox.yview) hs.pack(side=BOTTOM, fill=X) hs.config(command=self._listbox.xview, orient='horizontal') self._listbox.config(yscrollcommand=vs.set, xscrollcommand=hs.set, font=DEFAULT_FONT) self._listbox.pack(fill=BOTH, expand=YES) self._listbox.bind('<Double-1>', self._navigate_to) def find(self): self._result_queue = queue.Queue() self._listbox.delete('0', 'end') Thread(target=self._find, args=(self._root_path_var.get(), self._keyword_var.get()), daemon=True).start() def _find(self, path, keyword): if not os.path.exists(path): return None for this_dir, sub_dirs, files in os.walk(path): for file in files: file_type = guess_type(file)[0] if file_type and 'text' in file_type: fp = os.path.join(this_dir, file) self._result_queue.put(fp) if keyword in open(fp).read() else None def _consumer(self): if self._result_queue: try: fp = self._result_queue.get(block=False) except queue.Empty: pass else: self._listbox.insert('end', fp) # auto scroll. self._listbox.yview('end') self.after(100, self._consumer) def _navigate_to(self, event): """ Only works on Ubuntu platform currently. Double click to navigate to selected path. It's a very convenient function. :return: None """ print(event) # get active item from listbox path = self._listbox.get('active') print(path) # open nautilus with param path, before that, check your platform. if 'ubuntu' in (os.popen('uname -a').read()).lower(): os.system('/usr/bin/nautilus {}'.format(path)) else: pass
class AlteraVeiculo(Toplevel): '''Classe interface cadastrar veiculo''' def __init__(self, master=None): Toplevel.__init__(self, master=master) self.veiculo = Veiculo() self.dao = VeiculoDAO() self.geometry('1500x850+0+0') self.title('Cadastro de veiculos') self.resizable(0, 0) # impede de maximizar self.configure(background='#c9c9ff') self.id = None self.heading = Label(self, text="Alteração dos dados de um Veiculos", bg='#c9c9ff', fg='white', font=( 'Verdana 20 bold')) self.heading.place(x=650, y=0) # marca ========================================================================= self.marca = Label(self, text="Marca do veículo :", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.marca.place(x=10, y=70) self.marca_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.marca_entry.place(x=300, y=70) # modelo ========================================================================= self.modelo = Label(self, text="Modelo:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.modelo.place(x=10, y=120) self.modelo_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.modelo_entry.place(x=300, y=120) # ano ========================================================================= self.ano = Label(self, text="Ano:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.ano.place(x=10, y=170) self.ano_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.ano_entry.place(x=300, y=170) # cor ========================================================================= self.cor = Label(self, text="Cor:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.cor.place(x=10, y=220) self.cor_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.cor_entry.place(x=300, y=220) # self.cor_entry.insert(END, datetime.date.today()) # tanque ========================================================================= self.tanque = Label(self, text="Capacidade do tanque:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.tanque.place(x=10, y=270) self.tanque_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.tanque_entry.place(x=300, y=270) self.tanque_entry.insert(END, "litros") # combustivel ========================================================================= self.combustivel = Label(self, text="Tipo de Combustível:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.combustivel.place(x=10, y=320) self.combustivel_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.combustivel_entry.place(x=300, y=320) # consumo cidade ========================================================================= self.consumo_cidade = Label(self, text="Consumo na cidade:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.consumo_cidade.place(x=10, y=370) self.consumo_cidade_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.consumo_cidade_entry.place(x=300, y=370) self.consumo_cidade_entry.insert(END, "l/km") self.consumo_estrada = Label(self, text="Consumo na estrada:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.consumo_estrada.place(x=10, y=420) self.consumo_estrada_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.consumo_estrada_entry.place(x=300, y=420) self.consumo_estrada_entry.insert(END, "l/km") self.tempo_0_100 = Label(self, text="Tempo de 0km/h a 100km/h:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.tempo_0_100.place(x=10, y=470) self.tempo_0_100_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.tempo_0_100_entry.place(x=300, y=470) self.chassi = Label(self, text="Chassi:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.chassi.place(x=10, y=520) self.chassi_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.chassi_entry.place(x=300, y=520) self.placa = Label(self, text="Placa:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.placa.place(x=10, y=570) self.placa_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.placa_entry.place(x=300, y=570) self.tamanho_pneu = Label(self, text="Tamanho do pneu:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.tamanho_pneu.place(x=10, y=620) self.tamanho_pneu_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.tamanho_pneu_entry.place(x=300, y=620) self.som = Label(self, text="Som:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.som.place(x=10, y=670) self.som_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.som_entry.place(x=300, y=670) self.valor_diaria = Label(self, text="valor da diária:", bg='#c9c9ff', fg='white', font=( 'Verdana 15 bold')) self.valor_diaria.place(x=10, y=720) self.valor_diaria_entry = Entry(self, width=20, font=( 'Verdana 15 bold')) self.valor_diaria_entry.place(x=300, y=720) self.valor_diaria_entry.insert(END, 'R$ ') # BOTAO LIMPAR ========================================================================= self.botao_limpar = Button(self, text="Limpar", width=31, height=1, bg='#ffdfba', fg='black', font=( 'Verdana 15 bold'), command=self.clear_all) self.botao_limpar.place(x=600, y=700) self.botao_cadastrar = Button(self, text="Editar dados", width=62, height=1, bg='#baffc9', fg='black', font=( 'Verdana 15 bold'), command=self.get_items) self.botao_cadastrar.place(x=600, y=650) self.botao_sair = Button(self, text="Sair", width=30, height=1, bg='#ffb3ba', fg='black', font=( 'Verdana 15 bold'), command=self.close) self.botao_sair.place(x=1048, y=700) self.veiculo_box = Listbox(self, width=63, height=20, font=( 'Verdana 15 bold')) self.veiculo_box.place(x=600, y=120) self.scrollbar_veiculo = Scrollbar(self) self.veiculo_box.configure(yscrollcommand=self.scrollbar_veiculo.set) self.scrollbar_veiculo.configure(command=self.veiculo_box.yview) self.scrollbar_veiculo.place( x=1485, y=120, relheight=0.62, anchor='ne') self.pesquisar_veiculo = Label(self, text="Lista de veiculos Cadastrados:", bg='#c9c9ff', font=( 'Verdana 15 bold')) self.pesquisar_veiculo.place(x=900, y=65) self.view_command() self.veiculo_box.bind('<<ListboxSelect>>', self.selecionar_list_box) def view_command(self): "método para visualização dos resultados" try: rows = self.dao.view() self.veiculo_box.delete(0, END) for r in rows: self.veiculo_box.insert(END, r) except Exception as e: print(e) def selecionar_list_box(self, event): if self.veiculo_box.curselection(): self.clear_all() indice = self.veiculo_box.curselection()[0] self.selecionado = self.veiculo_box.get(indice) self.id = self.selecionado[0] self.marca_entry.insert(END,self.selecionado[1]) self.modelo_entry.insert(END,self.selecionado[2]) self.ano_entry.insert(END,self.selecionado[3]) self.cor_entry.insert(END,self.selecionado[4]) self.tanque_entry.insert(END,self.selecionado[5]) self.combustivel_entry.insert(END,self.selecionado[6]) self.consumo_cidade_entry.insert(END,self.selecionado[7]) self.consumo_estrada_entry.insert(END,self.selecionado[8]) self.tempo_0_100_entry.insert(END,self.selecionado[9]) self.chassi_entry.insert(END,self.selecionado[10]) self.placa_entry.insert(END,self.selecionado[11]) self.tamanho_pneu_entry.insert(END,self.selecionado[12]) self.som_entry.insert(END,self.selecionado[13]) self.valor_diaria_entry.insert(END,self.selecionado[14]) def get_items(self): self.veiculo.marca = self.marca_entry.get() self.veiculo.modelo = self.modelo_entry.get() self.veiculo.ano = self.ano_entry.get() self.veiculo.cor = self.cor_entry.get() self.veiculo.tanque = self.tanque_entry.get() self.veiculo.combustivel = self.combustivel_entry.get() self.veiculo.consumo_cidade = self.consumo_cidade_entry.get() self.veiculo.consumo_estrada = self.consumo_estrada_entry.get() self.veiculo.tempo_0_100 = self.tempo_0_100_entry.get() self.veiculo.chassi = self.chassi_entry.get() self.veiculo.placa = self.placa_entry.get() self.veiculo.tamanho_pneu = self.tamanho_pneu_entry.get() self.veiculo.som = self.som_entry.get() self.veiculo.valor_diaria = self.valor_diaria_entry.get() if(self.veiculo.marca == '' or self.veiculo.modelo == '' or self.veiculo.ano == '' or self.veiculo.cor == '' or self.veiculo.tanque == '' or self.veiculo.combustivel == '' or self.veiculo.consumo_cidade == '' or self.veiculo.consumo_estrada == '' or self.veiculo.tempo_0_100 == '' or self.veiculo.chassi == '' or self.veiculo.placa == '' or self.veiculo.tamanho_pneu == '' or self.veiculo.som == '' or self.veiculo.valor_diaria == ''): tkinter.messagebox.showinfo( "Aviso:", "POR FAVOR PREENCHER TODOS OS CAMPOS!") else: try: self.veiculo.tanque = float(self.veiculo.tanque) self.veiculo.consumo_cidade = float( self.veiculo.consumo_cidade) self.veiculo.consumo_estrada = float( self.veiculo.consumo_estrada) self.veiculo.tempo_0_100 = float(self.veiculo.tempo_0_100) self.veiculo.valor_diaria = float(self.veiculo.valor_diaria) except ValueError: tkinter.messagebox.showinfo( 'Aviso!', 'Os campos tamanho do tanque, Consumo na cidade, consumo ma estrada, tempo_0_100 e valor da diária devem ser preenchidos com números!') else: try: self.dao.update(self.veiculo, self.id) except Exception as e: print(e) else: tkinter.messagebox.showinfo( 'Aviso!', 'Cadastro Realizado com Sucesso!') self.clear_all() self.view_command() def clear_all(self): self.marca_entry.delete(0, END) self.modelo_entry.delete(0, END) self.ano_entry.delete(0, END) self.cor_entry.delete(0, END) self.tanque_entry.delete(0, END) # self.tanque_entry.insert(END, "litros") self.combustivel_entry.delete(0, END) self.consumo_cidade_entry.delete(0, END) # self.consumo_cidade_entry.insert(END, "l/km") self.consumo_estrada_entry.delete(0, END) # self.consumo_estrada_entry.insert(END, "l/km") self.tempo_0_100_entry.delete(0, END) # self.tempo_0_100_entry.insert(END, "segundos") self.chassi_entry.delete(0, END) self.placa_entry.delete(0, END) self.tamanho_pneu_entry.delete(0, END) self.som_entry.delete(0, END) self.valor_diaria_entry.delete(0, END) # self.valor_diaria_entry.insert(END, 'R$ ') def close(self): self.dao.close() self.destroy() def run(self): self.mainloop()
class ClientWindow(object): def __init__(self, root): self.__root = root self.__root.title('客户端') self.__root.resizable(0, 0) self.draw() self.sel_list = [] self.img_dict = {} self.filename = '' self.filesize = 0 #字节 def draw(self): self.frm = Frame(self.__root) self.frm.pack(fill=Y) self.frm_L = Frame(self.frm) self.frm_L.pack(side=LEFT, fill=BOTH) self.frm_R = Frame(self.frm) self.frm_R.pack(side=RIGHT, fill=BOTH) self.text_show = scrolledtext.ScrolledText(self.frm_L, font=('', 14), state=DISABLED, height=21) self.text_show.pack(side=TOP) self.text_show.tag_config('succ', foreground='green') self.text_show.tag_config('fail', foreground='red') self.text_show.tag_config('send', foreground='blue') self.text_show.tag_config('recv', foreground='orangered') self.frm_L_btn = Frame(self.frm_L) self.frm_L_btn.pack(side=TOP, fill=BOTH) self.btn_file = Button(self.frm_L_btn, text='文件', command=self.select_file) self.btn_file.pack(side=LEFT, anchor=W, expand=YES) self.btn_clear = Button(self.frm_L_btn, text='清屏', command=self.clear) self.btn_clear.pack(side=LEFT, anchor=E) self.btn_send = Button(self.frm_L_btn, text='发送', command=self.send_msg) self.btn_send.pack(side=LEFT, anchor=E) self.text_input = Text(self.frm_L, height=12) self.text_input.pack(side=TOP, fill=BOTH) self.lb = Listbox(self.frm_R, height=12, width=24, selectmode='extended') self.lb.pack(side=TOP) # for i in range(5): # self.lb.insert('end', i*30) self.frm_R_btn = Frame(self.frm_R) self.frm_R_btn.pack(side=TOP, fill=BOTH) self.btn_sel = Button(self.frm_R_btn, text=' ↓ ', command=self.select_users) self.btn_sel.pack(side=LEFT, anchor=W) self.btn_del = Button(self.frm_R_btn, text='清空', command=self.empty_users) self.btn_del.pack(side=LEFT, anchor=W) self.btn_get_list = Button(self.frm_R_btn, text='刷新', command=self.get_online_list) self.btn_get_list.pack(side=LEFT, anchor=E, expand=YES) self.lb_sel = Listbox(self.frm_R, height=12, width=24) self.lb_sel.pack(side=TOP) def get_root(self): return self.__root def select_file(self): self.filename = filedialog.askopenfilename() if self.filename == '': return if self.sel_list: name = self.filename size = common.get_size(name) self.filesize = os.path.getsize(name) info = {'name': os.path.basename(name), 'size': self.filesize} self.show(f'send file \'{name}\'\nsize: \'{size}\'\n') if name.endswith(('jpg', 'png', 'jpeg', 'bmp', 'gif')): self.show(name, 'img') self.send(f'IMG::{info}::{self.sel_list}') with open(self.filename, 'rb') as f: for data in f: s.send(data) elif name != '': # self.text_input.delete(1.0, 'end') self.send(f'FILE::{info}::{self.sel_list}') else: self.show('请至少选择一个用户...\n') def clear(self): self.img_dict.clear() self.text_show.config(state=NORMAL) self.text_show.delete(1.0, 'end') self.text_show.config(state=DISABLED) def send_msg(self): msg = self.text_input.get(1.0, 'end') if self.sel_list: self.send(f'MSG::{msg}::{self.sel_list}') self.show(f'{msg}\n') self.text_input.delete(1.0, 'end') else: self.show('请至少选择一个用户...\n') def send(self, msg: str): """对socket.send()方法的封装 Args: msg (str): 需要发送的字符串 """ s.send(msg.encode()) def select_users(self): self.sel_list = [self.lb.get(x) for x in self.lb.curselection()] self.lb_sel.delete(0, 'end') for usr in self.sel_list: self.lb_sel.insert('end', usr) def empty_users(self): self.lb_sel.delete(0, 'end') self.sel_list.clear() def get_online_list(self): self.show('正在获取在线列表...\n') self.send('ONLINE::::') def show(self, msg: str, tag=''): """显示接收或发送的文字消息 Args: msg (str): 需要显示的文字 tag (str, optional): 文字标识(颜色、背景、字体等). Defaults to ''. """ self.text_show.config(state=NORMAL) # if tag != 'img': self.text_show.insert('end', f'[{ctime()}] ', 'send') if tag == 'recv': self.text_show.insert('end', f'{msg}', 'recv') elif tag in ['succ', 'fail']: self.text_show.insert('end', f'{msg}', tag) elif tag == 'img': self.text_show.insert('end', '\n', 'send') photo = ImageTk.PhotoImage(Image.open(msg)) self.img_dict[ctime()] = photo self.text_show.image_create(END, image=photo) self.text_show.insert('end', '\n', 'send') elif tag == '\n': self.text_show.insert('end', '\n', 'send') else: self.text_show.insert('end', f'{msg}', 'send') self.text_show.config(state=DISABLED)
class UBX_PRESET_Frame(Frame): """ UBX Preset and User-defined configuration command panel. """ def __init__(self, app, container, *args, **kwargs): """ Constructor. :param Frame app: reference to main tkinter application :param Frame container: reference to container frame (config-dialog) :param args: optional args to pass to Frame parent class :param kwargs: optional kwargs to pass to Frame parent class """ self.__app = app # Reference to main application class self.__master = self.__app.get_master() # Reference to root class (Tk) self.__container = container Frame.__init__(self, self.__container.container, *args, **kwargs) self._img_send = ImageTk.PhotoImage(Image.open(ICON_SEND)) self._img_pending = ImageTk.PhotoImage(Image.open(ICON_PENDING)) self._img_confirmed = ImageTk.PhotoImage(Image.open(ICON_CONFIRMED)) self._img_warn = ImageTk.PhotoImage(Image.open(ICON_WARNING)) self._preset_command = None self._body() self._do_layout() self._attach_events() self.reset() def _body(self): """ Set up frame and widgets. """ self._lbl_presets = Label(self, text=LBLPRESET, anchor="w") self._lbx_preset = Listbox( self, border=2, relief="sunken", bg=ENTCOL, height=5, width=30, justify=LEFT, exportselection=False, ) self._scr_presetv = Scrollbar(self, orient=VERTICAL) self._scr_preseth = Scrollbar(self, orient=HORIZONTAL) self._lbx_preset.config(yscrollcommand=self._scr_presetv.set) self._lbx_preset.config(xscrollcommand=self._scr_preseth.set) self._scr_presetv.config(command=self._lbx_preset.yview) self._scr_preseth.config(command=self._lbx_preset.xview) self._lbl_send_command = Label(self) self._btn_send_command = Button( self, image=self._img_send, width=50, command=self._on_send_preset, ) def _do_layout(self): """ Layout widgets. """ self._lbl_presets.grid(column=0, row=0, columnspan=6, padx=3, sticky=(W, E)) self._lbx_preset.grid(column=0, row=1, columnspan=3, rowspan=6, padx=3, pady=3, sticky=(W, E)) self._scr_presetv.grid(column=2, row=1, rowspan=6, sticky=(N, S, E)) self._scr_preseth.grid(column=0, row=7, columnspan=3, sticky=(W, E)) self._btn_send_command.grid(column=3, row=1, rowspan=6, ipadx=3, ipady=3, sticky=(E)) self._lbl_send_command.grid(column=4, row=1, rowspan=6, ipadx=3, ipady=3, sticky=(E)) (cols, rows) = self.grid_size() for i in range(cols): self.grid_columnconfigure(i, weight=1) for i in range(rows): self.grid_rowconfigure(i, weight=1) self.option_add("*Font", self.__app.font_sm) def _attach_events(self): """ Bind listbox selection events. """ self._lbx_preset.bind("<<ListboxSelect>>", self._on_select_preset) def reset(self): """ Reset panel. """ # Load user-defined presets if there are any self._userpresets = self.__app.file_handler.load_user_presets() idx = 0 for pst in PRESET_COMMMANDS: self._lbx_preset.insert(idx, pst) idx += 1 for upst in self._userpresets: self._lbx_preset.insert(idx, "USER " + upst) idx += 1 def _on_select_preset(self, *args, **kwargs): # pylint: disable=unused-argument """ Preset command has been selected. """ idx = self._lbx_preset.curselection() self._preset_command = self._lbx_preset.get(idx) def _on_send_preset(self, *args, **kwargs): # pylint: disable=unused-argument """ Preset command send button has been clicked. """ confirmed = True try: if self._preset_command == PSTRESET: confirmed = self._do_factory_reset() elif self._preset_command == PSTSAVE: confirmed = self._do_save_config() elif self._preset_command == PSTMINNMEAON: self._do_set_minnmea() elif self._preset_command == PSTALLNMEAON: self._do_set_allnmea(1) elif self._preset_command == PSTALLNMEAOFF: self._do_set_allnmea(0) elif self._preset_command == PSTMINUBXON: self._do_set_minNAV() elif self._preset_command == PSTALLUBXON: self._do_set_allNAV(1) elif self._preset_command == PSTALLUBXOFF: self._do_set_allNAV(0) elif self._preset_command == PSTALLINFON: self._do_set_inf(True) elif self._preset_command == PSTALLINFOFF: self._do_set_inf(False) elif self._preset_command == PSTALLLOGON: self._do_set_log(4) elif self._preset_command == PSTALLLOGOFF: self._do_set_log(0) elif self._preset_command == PSTALLMONON: self._do_set_mon(4) elif self._preset_command == PSTALLMONOFF: self._do_set_mon(0) elif self._preset_command == PSTALLRXMON: self._do_set_rxm(4) elif self._preset_command == PSTALLRXMOFF: self._do_set_rxm(0) elif self._preset_command == PSTPOLLPORT: self._do_poll_prt() elif self._preset_command == PSTPOLLINFO: self._do_poll_inf() elif self._preset_command == PSTPOLLALL: self._do_poll_all() else: self._do_user_defined(self._preset_command) if confirmed: self._lbl_send_command.config(image=self._img_pending) self.__container.set_status("Command(s) sent", "blue") self.__container.set_pending(UBX_PRESET, ("ACK-ACK", "ACK-NAK", "MON-VER")) else: self.__container.set_status("Command(s) cancelled", "blue") except Exception as err: # pylint: disable=broad-except self.__container.set_status(f"Error {err}", "red") self._lbl_send_command.config(image=self._img_warn) def _do_poll_all(self): """ Poll INF message configuration. """ for msgtype in UBX_PAYLOADS_POLL: if msgtype[0:3] == "CFG" and msgtype not in ( "CFG-INF", "CFG-MSG", "CFG-PRT-IO", "CFG-TP5-TPX", ): msg = UBXMessage("CFG", msgtype, POLL) self.__app.serial_handler.serial_write(msg.serialize()) def _do_poll_prt(self): """ Poll PRT message configuration for each port. """ for portID in range(5): msg = UBXMessage("CFG", "CFG-PRT", POLL, portID=portID) self.__app.serial_handler.serial_write(msg.serialize()) def _do_poll_inf(self): """ Poll INF message configuration. """ for payload in (b"\x00", b"\x01"): # UBX & NMEA msg = UBXMessage("CFG", "CFG-INF", POLL, payload=payload) self.__app.serial_handler.serial_write(msg.serialize()) def _do_set_inf(self, onoff: int): """ Turn on device information messages INF. :param int onoff: on/off boolean """ if onoff: mask = b"\x1f" # all INF msgs else: mask = b"\x01" # errors only for protocolID in (b"\x00", b"\x01"): # UBX and NMEA reserved1 = b"\x00\x00\x00" infMsgMaskDDC = mask infMsgMaskUART1 = mask infMsgMaskUART2 = mask infMsgMaskUSB = mask infMsgMaskSPI = mask reserved2 = b"\x00" payload = (protocolID + reserved1 + infMsgMaskDDC + infMsgMaskUART1 + infMsgMaskUART2 + infMsgMaskUSB + infMsgMaskSPI + reserved2) msg = UBXMessage("CFG", "CFG-INF", SET, payload=payload) self.__app.serial_handler.serial_write(msg.serialize()) self._do_poll_inf() # poll results def _do_set_log(self, msgrate: int): """ Turn on all device logging messages LOG. :param int msgrate: message rate (i.e. every nth position solution) """ for msgtype in UBX_MSGIDS: if msgtype[0:1] == b"\x21": self._do_cfgmsg(msgtype, msgrate) def _do_set_mon(self, msgrate): """ Turn on all device monitoring messages MON. :param int msgrate: message rate (i.e. every nth position solution) """ for msgtype in UBX_MSGIDS: if msgtype[0:1] == b"\x0A": self._do_cfgmsg(msgtype, msgrate) def _do_set_rxm(self, msgrate): """ Turn on all device receiver management messages RXM. :param int msgrate: message rate (i.e. every nth position solution) """ for msgtype in UBX_MSGIDS: if msgtype[0:1] == b"\x02": self._do_cfgmsg(msgtype, msgrate) def _do_set_minnmea(self): """ Turn on minimum set of NMEA messages (GGA & GSA & GSV). """ for msgtype in UBX_MSGIDS: if msgtype[0:1] == b"\xf0": # standard NMEA if msgtype in (b"\xf0\x00", b"\xf0\x02"): # GGA, GSA self._do_cfgmsg(msgtype, 1) elif msgtype == b"\xf0\x03": # GSV self._do_cfgmsg(msgtype, 4) else: self._do_cfgmsg(msgtype, 0) if msgtype[0:1] == b"\xf1": # proprietary NMEA self._do_cfgmsg(msgtype, 0) def _do_set_minNAV(self): """ Turn on minimum set of UBX-NAV messages (PVT & SVINFO). """ for msgtype in UBX_MSGIDS: if msgtype[0:1] == b"\x01": # UBX-NAV if msgtype == b"\x01\x07": # NAV-PVT self._do_cfgmsg(msgtype, 1) # elif msgtype == b"\x01\x30": # NAV-SVINFO (deprecated) # self._do_cfgmsg(msgtype, 4) elif msgtype == b"\x01\x35": # NAV-SAT self._do_cfgmsg(msgtype, 4) else: self._do_cfgmsg(msgtype, 0) def _do_set_allnmea(self, msgrate): """ Turn on all NMEA messages. :param int msgrate: message rate (i.e. every nth position solution) """ for msgtype in UBX_MSGIDS: if msgtype[0:1] in (b"\xf0", b"\xf1"): self._do_cfgmsg(msgtype, msgrate) def _do_set_allNAV(self, msgrate): """ Turn on all UBX-NAV messages. :param int msgrate: message rate (i.e. every nth position solution) """ for msgtype in UBX_MSGIDS: if msgtype[0:1] == b"\x01": self._do_cfgmsg(msgtype, msgrate) def _do_cfgmsg(self, msgtype: str, msgrate: int): """ Set rate for specified message type via CFG-MSG. NB A rate of n means 'for every nth position solution', so values > 1 mean the message is sent less often. :param str msgtype: type of config message :param int msgrate: message rate (i.e. every nth position solution) """ msgClass = int.from_bytes(msgtype[0:1], "little", signed=False) msgID = int.from_bytes(msgtype[1:2], "little", signed=False) msg = UBXMessage( "CFG", "CFG-MSG", SET, msgClass=msgClass, msgID=msgID, rateDDC=msgrate, rateUART1=msgrate, rateUSB=msgrate, rateSPI=msgrate, ) self.__app.serial_handler.serial_write(msg.serialize()) def _do_factory_reset(self) -> bool: """ Restore to factory defaults stored in battery-backed RAM but display confirmation message box first. :return: boolean signifying whether OK was pressed :rtype: bool """ if messagebox.askokcancel(DLGRESET, DLGRESETCONFIRM): clearMask = b"\x1f\x1f\x00\x00" loadMask = b"\x1f\x1f\x00\x00" deviceMask = b"\x07" # target RAM, Flash and EEPROM msg = UBXMessage( "CFG", "CFG-CFG", SET, clearMask=clearMask, loadMask=loadMask, deviceMask=deviceMask, ) self.__app.serial_handler.serial_write(msg.serialize()) return True return False def _do_save_config(self) -> bool: """ Save current configuration to persistent storage but display confirmation message box first. :return: boolean signifying whether OK was pressed :rtype: bool """ if messagebox.askokcancel(DLGSAVE, DLGSAVECONFIRM): saveMask = b"\x1f\x1f\x00\x00" deviceMask = b"\x07" # target RAM, Flash and EEPROM msg = UBXMessage("CFG", "CFG-CFG", SET, saveMask=saveMask, deviceMask=deviceMask) self.__app.serial_handler.serial_write(msg.serialize()) return True return False def _do_user_defined(self, command: str): """ Parse and send user-defined command(s). This could result in any number of errors if the uxbpresets file contains garbage, so there's a broad catch-all-exceptions in the calling routine. :param str command: user defined message constructor(s) """ try: seg = command.split(",") for i in range(1, len(seg), 4): ubx_class = seg[i].strip() ubx_id = seg[i + 1].strip() payload = seg[i + 2].strip() mode = int(seg[i + 3].rstrip("\r\n")) if payload != "": payload = bytes(bytearray.fromhex(payload)) msg = UBXMessage(ubx_class, ubx_id, mode, payload=payload) else: msg = UBXMessage(ubx_class, ubx_id, mode) self.__app.serial_handler.serial_write(msg.serialize()) except Exception as err: # pylint: disable=broad-except self.__app.set_status(f"Error {err}", "red") self._lbl_send_command.config(image=self._img_warn) def update_status(self, cfgtype, **kwargs): """ Update pending confirmation status. :param str cfgtype: identity of UBX message containing config info :param kwargs: status keywords and values from UBX config message """ if cfgtype in ("ACK-ACK", "MON-VER"): self._lbl_send_command.config(image=self._img_confirmed) self.__container.set_status(f"{cfgtype} GET message received", "green") elif cfgtype == "ACK-NAK": self._lbl_send_command.config(image=self._img_warn) self.__container.set_status("PRESET command rejected", "red")
class Application(tk.Frame): def __init__(self, parent, *args, **kwargs): self.entrys = [] self.textboxes = [] self.asterisks = 1 self.selected_index = 0 self.previous_index = None self.update_flag = False self.action_flag = 0 self.previous_key = '' self.new_key = '' #init frame print('INITIALISING FRAME') tk.Frame.__init__(self, parent, *args, **kwargs) self.parent = parent #Set window name, size parent.title('SwiftPass') parent.geometry('700x700') #on mouse1 click, deselect listbox parent.bind('<ButtonPress-1>', self.deselect_lb_item) self.generate_widgets() self.populate_data() def generate_widgets(self): print('GENERATING WIDGETS') #Service ID self.serviceid_text = StringVar() self.serviceid_label = Label(self.parent, text='Service ID', font=( 'bold', 14, ), pady=20, padx=5) self.serviceid_label.grid(row=0, column=0, sticky=W) self.serviceid_entry = Entry(self.parent, textvariable=self.serviceid_text) self.serviceid_entry.grid(row=0, column=1) self.entrys.append(self.serviceid_entry) self.textboxes.append(self.serviceid_text) #Service Name self.service_text = StringVar() self.service_label = Label(self.parent, text='Service Name', font=('bold', 14), pady=20, padx=5) self.service_label.grid(row=1, column=0, sticky=W) self.service_entry = Entry(self.parent, textvariable=self.service_text) self.service_entry.grid(row=1, column=1) self.entrys.append(self.service_entry) self.textboxes.append(self.service_text) #URL self.url_text = StringVar() self.url_label = Label(self.parent, text='URL', font=('bold', 14), pady=20, padx=5) self.url_label.grid(row=2, column=0, sticky=W) self.url_entry = Entry(self.parent, textvariable=self.url_text) self.url_entry.grid(row=2, column=1) self.entrys.append(self.url_entry) self.textboxes.append(self.url_text) #Username self.username_text = StringVar() self.username_label = Label(self.parent, text='Username', font=('bold,', 14), pady=20, padx=5) self.username_label.grid(row=3, column=0, stick=W) self.username_entry = Entry(self.parent, textvariable=self.username_text) self.username_entry.grid(row=3, column=1) self.entrys.append(self.username_entry) self.textboxes.append(self.username_text) #Password self.password_text = StringVar() self.password_label = Label(self.parent, text='Password', font=('bold', 14), pady=20, padx=5) self.password_label.grid(row=4, column=0, sticky=W) self.password_entry = Entry(self.parent, textvariable=self.password_text) self.password_entry.grid(row=4, column=1) self.entrys.append(self.password_entry) self.textboxes.append(self.password_text) #Listbox self.password_list = Listbox(self.parent, height=20, width=50, border=1) self.password_list.grid(row=5, column=0, padx=5, columnspan=3, rowspan=6) self.password_list.bind('<<ListboxSelect>>', self.select) #self.scrollbar = tk.Scrollbar(self.parent) #self.scrollbar.grid(row=3, column=2) #self.password_list.config(yscrollcommand=self.scrollbar.set) #self.scrollbar.config(command=self.password_list.yview) #Add button self.add_btn = Button(self.parent, text='Add Service', width=12, command=self.add_service, fg='black', foreground='black', highlightbackground='black') self.add_btn.grid(row=0, column=3, pady=20, padx=5) #Remove button self.remove_btn = Button(self.parent, text='Remove Service', width=12, command=self.remove_service, fg='black', foreground='black', highlightbackground='black') self.remove_btn.grid(row=0, column=4, pady=20, padx=5) #Edit button self.edit_btn = Button(self.parent, text='Edit Service', width=12, command=self.edit_service, fg='black', foreground='black', highlightbackground='black') self.edit_btn.grid(row=1, column=3, pady=20, padx=5) #Show Password button self.show_passwords_btn = Button(self.parent, text='Show Passwords', width=12, command=self.toggle_show_passwords, fg='black', foreground='black', highlightbackground='black') self.show_passwords_btn.grid(row=1, column=4, pady=20, padx=5) #Save button self.save_btn = Button(self.parent, text='Save', width=12, command=self.save, state='disabled', fg='black', foreground='black', highlightbackground='black') self.save_btn.grid(row=2, column=3, pady=20, padx=5) #Cancel button self.cancel_btn = Button(self.parent, text='Cancel', width=12, command=self.cancel, state='disabled', fg='black', foreground='black', highlightbackground='black') self.cancel_btn.grid(row=2, column=4, pady=20, padx=5) #Copy URL button self.copy_url_btn = Button( self.parent, text='Copy', width=12, command=lambda: self.clipboard(self.url_entry.get()), fg='black', foreground='black', highlightbackground='black') self.copy_url_btn.grid(row=2, column=2) #Copy Username button self.copy_uname_btn = Button( self.parent, text='Copy', width=12, command=lambda: self.clipboard(self.username_entry.get()), fg='black', foreground='black', highlightbackground='black') self.copy_uname_btn.grid(row=3, column=2) #Copy Password button self.copy_pass_btn = Button( self.parent, text='Copy', width=12, command=lambda: self.clipboard( db.get_password(self.serviceid_entry.get())), fg='black', foreground='black', highlightbackground='black') self.copy_pass_btn.grid(row=4, column=2) #self.toggle_tb(1) self.generate_secure_password_32_btn = Button( self.parent, text='Generate (32)', width=12, fg='black', foreground='black', highlightbackground='black', command=lambda: self.password_text.set(self.generate_password(32)), state='disabled') self.generate_secure_password_32_btn.grid(row=4, column=3) self.generate_secure_password_64_btn = Button( self.parent, text='Generate (64)', width=12, fg='black', foreground='black', highlightbackground='black', command=lambda: self.password_text.set(self.generate_password(64)), state='disabled') self.generate_secure_password_64_btn.grid(row=4, column=4) #Deselect currently selected listbox item def deselect_lb_item(self, event): print('DESELECTED LISTBOX') if self.selected_index == self.previous_index: self.password_list.selection_clear(0, tk.END) self.previous_index = self.password_list.curselection() def populate_data(self): #clear listbox print('POPULATING DATA') self.password_list.delete(0, END) if self.asterisks == 1: for row in db.fetch(): #anonyimise password self.anonyimise_listbox(row) if self.asterisks == 0: for row in db.fetch(): #insert row to listbox self.password_list.insert(END, row) self.password_list.select_set(self.selected_index) self.password_list.event_generate("<<ListboxSelect>>") def anonyimise_listbox(self, data): print('ANONYIMISING DATA') #anonyimise password pwd = self.anonymise(str(data[4])) data_list = list(data) data_list[4] = pwd new_row = tuple(data_list) #insert password self.password_list.insert(END, new_row) def unan_listbox(self): print('UNANYMISING DATA') #reinit data self.populate_data() def toggle_show_passwords(self): print('TOGGLING SHOW PASSWORDS') changed_flag = False if self.asterisks == 1: self.asterisks = 0 #reinit data self.populate_data() changed_flag = True if self.asterisks == 0 and changed_flag is False: self.asterisks = 1 #clear listbox self.password_list.delete(0, END) for row in db.fetch(): #anonymise password self.anonyimise_listbox(row) self.password_list.select_set(self.selected_index) self.password_list.event_generate("<<ListboxSelect>>") def anonymise(self, password): #return anonyimised password return "*" * len(password) def add_service(self): print('BEGIN ADD SERVICE') self.clear() self.toggle_tb(0) self.action_flag = 'add' self.add_btn["state"] = "disabled" self.remove_btn["state"] = "disabled" self.edit_btn["state"] = "disabled" self.show_passwords_btn["state"] = "disabled" self.password_list["state"] = "disabled" self.save_btn["state"] = "active" self.cancel_btn["state"] = "active" self.generate_secure_password_32_btn["state"] = "active" self.generate_secure_password_64_btn["state"] = "active" def cancel(self): print('CANCEL ACTION') self.toggle_tb(1) self.save_btn["state"] = "disabled" self.cancel_btn["state"] = "disabled" self.add_btn["state"] = "active" self.remove_btn["state"] = "active" self.edit_btn["state"] = "active" self.password_list["state"] = "normal" self.show_passwords_btn["state"] = "active" self.generate_secure_password_32_btn["state"] = "disabled" self.generate_secure_password_64_btn["state"] = "disabled" return def save(self): print('SAVING ACTION') allow = False if self.action_flag == 'add': if self.insert_service() != -1: allow = True if self.action_flag == 'edit': if self.commit_edit() != -1: allow = True if allow is True: self.toggle_tb(1) self.save_btn["state"] = "disabled" self.cancel_btn["state"] = "disabled" self.add_btn["state"] = "active" self.remove_btn["state"] = "active" self.edit_btn["state"] = "active" self.show_passwords_btn["state"] = "active" self.password_list["state"] = "normal" self.generate_secure_password_32_btn["state"] = "disabled" self.generate_secure_password_64_btn["state"] = "disabled" self.populate_data() def insert_service(self): print('ATTEMPTING INSERT TO DATABASE') if self.check() == -1: return -1 #insert data to be database print('INSERT SUCCESSFUL') db.insert(self.service_entry.get(), self.url_entry.get(), str(self.username_entry.get()), self.password_entry.get()) self.populate_data() def check(self): #length check if len(self.service_entry.get()) == 0 or len( self.username_entry.get()) == 0 or len( self.url_entry.get()) == 0 or len( self.password_entry.get()) == 0: #show message box mb.showerror("Error", "Please ensure all fields contain data") return -1 return 1 def edit_service(self): self.toggle_tb(0) self.add_btn["state"] = "disabled" self.remove_btn["state"] = "disabled" self.edit_btn["state"] = "disabled" self.show_passwords_btn["state"] = "disabled" self.password_list["state"] = "disabled" self.save_btn["state"] = "active" self.cancel_btn["state"] = "active" self.action_flag = 'edit' self.generate_secure_password_32_btn["state"] = "active" self.generate_secure_password_64_btn["state"] = "active" def commit_edit(self): if self.check() == -1: return #update database db.update(self.serviceid_entry.get(), self.service_entry.get(), self.url_entry.get(), str(self.username_entry.get()), self.password_entry.get()) self.populate_data() def remove_service(self): id = self.serviceid_entry.get() db.remove(id) self.populate_data() def clear(self): #clear textboxes for tb in self.textboxes: tb.set('') return def toggle_tb(self, flag): #enable/disable textboxes if flag == 1: for tb in self.entrys: tb.config(state='disabled') return for tb in self.entrys: tb.config(state='normal') self.serviceid_entry.config(state='disabled') def select(self, event): #insert selected listbox item into textboxes sel = self.password_list.get(self.password_list.curselection()) self.selected_index = self.password_list.curselection() service_id = sel[0] service_name = sel[1] url = sel[2] username = sel[3] password = sel[4] self.serviceid_text.set(service_id) self.service_text.set(service_name) self.url_text.set(url) self.username_text.set(username) #check if we need to anonymise if self.asterisks == 1: password = self.anonymise(password) self.password_text.set(password) def clipboard(self, arg): #copy to clipboard cbl.copy(arg) def generate_password(self, len): return ''.join(random.choice(string.ascii_letters) for i in range(len))
#combobox frame=Frame(window) frame.pack(fill=X) combobox=Combobox(frame) items=(1,2,3,"Hello","World") combobox['values']=items combobox.current(1) combobox.bind("<<ComboboxSelected>>",onChangeValue) combobox.pack(side=LEFT) #end combo box #listbox listbox=Listbox(frame) listbox.insert(0,"Rahul") listbox.insert(1,"Rajiv") listbox.insert(2,"Aman") listbox.insert(3,"Vishal") listbox.pack(side=LEFT) textbox=Text(frame) textbox.pack(side=LEFT) button_get_value=Button(frame,text="Get Value",command=getValue) button_get_value.pack(side=LEFT) frame2=Frame(window) frame2.pack() progress=Progressbar(frame2,length=100)
class FileDialog: """Standard file selection dialog -- no checks on selected file. Usage: d = FileDialog(master) fname = d.go(dir_or_file, pattern, default, key) if fname is None: ...canceled... else: ...open file... All arguments to go() are optional. The 'key' argument specifies a key in the global dictionary 'dialogstates', which keeps track of the values for the directory and pattern arguments, overriding the values passed in (it does not keep track of the default argument!). If no key is specified, the dialog keeps no memory of previous state. Note that memory is kept even when the dialog is canceled. (All this emulates the behavior of the Macintosh file selection dialogs.) """ title = "File Selection Dialog" def __init__(self, master, title=None): if title is None: title = self.title self.master = master self.directory = None self.top = Toplevel(master) self.top.title(title) self.top.iconname(title) self.botframe = Frame(self.top) self.botframe.pack(side=BOTTOM, fill=X) self.selection = Entry(self.top) self.selection.pack(side=BOTTOM, fill=X) self.selection.bind('<Return>', self.ok_event) self.filter = Entry(self.top) self.filter.pack(side=TOP, fill=X) self.filter.bind('<Return>', self.filter_command) self.midframe = Frame(self.top) self.midframe.pack(expand=YES, fill=BOTH) self.filesbar = Scrollbar(self.midframe) self.filesbar.pack(side=RIGHT, fill=Y) self.files = Listbox(self.midframe, exportselection=0, yscrollcommand=(self.filesbar, 'set')) self.files.pack(side=RIGHT, expand=YES, fill=BOTH) btags = self.files.bindtags() self.files.bindtags(btags[1:] + btags[:1]) self.files.bind('<ButtonRelease-1>', self.files_select_event) self.files.bind('<Double-ButtonRelease-1>', self.files_double_event) self.filesbar.config(command=(self.files, 'yview')) self.dirsbar = Scrollbar(self.midframe) self.dirsbar.pack(side=LEFT, fill=Y) self.dirs = Listbox(self.midframe, exportselection=0, yscrollcommand=(self.dirsbar, 'set')) self.dirs.pack(side=LEFT, expand=YES, fill=BOTH) self.dirsbar.config(command=(self.dirs, 'yview')) btags = self.dirs.bindtags() self.dirs.bindtags(btags[1:] + btags[:1]) self.dirs.bind('<ButtonRelease-1>', self.dirs_select_event) self.dirs.bind('<Double-ButtonRelease-1>', self.dirs_double_event) self.ok_button = Button(self.botframe, text="OK", command=self.ok_command) self.ok_button.pack(side=LEFT) self.filter_button = Button(self.botframe, text="Filter", command=self.filter_command) self.filter_button.pack(side=LEFT, expand=YES) self.cancel_button = Button(self.botframe, text="Cancel", command=self.cancel_command) self.cancel_button.pack(side=RIGHT) self.top.protocol('WM_DELETE_WINDOW', self.cancel_command) # XXX Are the following okay for a general audience? self.top.bind('<Alt-w>', self.cancel_command) self.top.bind('<Alt-W>', self.cancel_command) def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None): if key and key in dialogstates: self.directory, pattern = dialogstates[key] else: dir_or_file = os.path.expanduser(dir_or_file) if os.path.isdir(dir_or_file): self.directory = dir_or_file else: self.directory, default = os.path.split(dir_or_file) self.set_filter(self.directory, pattern) self.set_selection(default) self.filter_command() self.selection.focus_set() self.top.wait_visibility() # window needs to be visible for the grab self.top.grab_set() self.how = None self.master.mainloop() # Exited by self.quit(how) if key: directory, pattern = self.get_filter() if self.how: directory = os.path.dirname(self.how) dialogstates[key] = directory, pattern self.top.destroy() return self.how def quit(self, how=None): self.how = how self.master.quit() # Exit mainloop() def dirs_double_event(self, event): self.filter_command() def dirs_select_event(self, event): dir, pat = self.get_filter() subdir = self.dirs.get('active') dir = os.path.normpath(os.path.join(self.directory, subdir)) self.set_filter(dir, pat) def files_double_event(self, event): self.ok_command() def files_select_event(self, event): file = self.files.get('active') self.set_selection(file) def ok_event(self, event): self.ok_command() def ok_command(self): self.quit(self.get_selection()) def filter_command(self, event=None): dir, pat = self.get_filter() try: names = os.listdir(dir) except OSError: self.master.bell() return self.directory = dir self.set_filter(dir, pat) names.sort() subdirs = [os.pardir] matchingfiles = [] for name in names: fullname = os.path.join(dir, name) if os.path.isdir(fullname): subdirs.append(name) elif fnmatch.fnmatch(name, pat): matchingfiles.append(name) self.dirs.delete(0, END) for name in subdirs: self.dirs.insert(END, name) self.files.delete(0, END) for name in matchingfiles: self.files.insert(END, name) head, tail = os.path.split(self.get_selection()) if tail == os.curdir: tail = '' self.set_selection(tail) def get_filter(self): filter = self.filter.get() filter = os.path.expanduser(filter) if filter[-1:] == os.sep or os.path.isdir(filter): filter = os.path.join(filter, "*") return os.path.split(filter) def get_selection(self): file = self.selection.get() file = os.path.expanduser(file) return file def cancel_command(self, event=None): self.quit() def set_filter(self, dir, pat): if not os.path.isabs(dir): try: pwd = os.getcwd() except OSError: pwd = None if pwd: dir = os.path.join(pwd, dir) dir = os.path.normpath(dir) self.filter.delete(0, END) self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*")) def set_selection(self, file): self.selection.delete(0, END) self.selection.insert(END, os.path.join(self.directory, file))
class TkUserListSelect(object): """ A simple box to pop up for user based item selection. This is not for file or file path selection, there is another class for that Example ------- >>> user_list_box = TkUserListSelect(title='Title', >>> message='Info For User', >>> user_enum=dict( >>> zip([1, 'hi', 'user sees these', 4], >>> [1, 'user doesnt see these', >>> 'but they correspond with the keys that the user does see', >>> ' 1:1 by location and are what are returned if desired']))) >>> user_list_box.open_frame() ...Interaction (user selects 'hi') >>> user_list_box.return_index() 1 >>> user_list_box.return_index_value() 'hi' >>> user_list_box.return_enum() {'hi': 'user doesnt see these'} >>> user_list_box.return_value() 'user doesnt see these' """ def __init__(self, title, message, user_enum): self.master = Tk() self.value = None self._user_presented_list = list(user_enum.keys()) self._short_bubble_sort() self._user_enum = user_enum self._current_font_type = 'Times' self._current_font_size = 10 self.font_obj = font.Font(font=(self._current_font_type, self._current_font_size)) # self.modalPane = Toplevel(self.master) self.modalPane = self.master # self.modalPane.transient(self.master) self.modalPane.grab_set() self.modalPane.bind("<Return>", self._choose) self.modalPane.bind("<Escape>", self._cancel) if title: self.modalPane.title(title) if message: self.message_label = \ Label(self.modalPane, text=message) self.message_label.pack(padx=5, pady=5) listFrame = Frame(self.modalPane) listFrame.pack(side=TOP, padx=5, pady=5) scrollBar = Scrollbar(listFrame) scrollBar.pack(side=RIGHT, fill=Y) self.listBox = Listbox(listFrame, selectmode=SINGLE) self.listBox.pack(side=LEFT, fill=Y) scrollBar.config(command=self.listBox.yview) self.listBox.config(yscrollcommand=scrollBar.set) # self.list.sort() for item in self._user_presented_list: self.listBox.insert(END, item) buttonFrame = Frame(self.modalPane) buttonFrame.pack(side=BOTTOM) chooseButton = Button(buttonFrame, text="Choose", command=self._choose) chooseButton.pack() cancelButton = Button(buttonFrame, text="Cancel", command=self._cancel) cancelButton.pack(side=RIGHT) self.set_font_size('Times', 10) self.autowidth(500) def set_font_size(self, FONT_TYPE, FONT_SIZE): self._current_font_type = FONT_TYPE self._current_font_size = FONT_SIZE self.font_obj = font.Font(font=(self._current_font_type, self._current_font_size)) self.message_label.config(font=(self._current_font_type, self._current_font_size)) self.listBox.config(font=(self._current_font_type, self._current_font_size)) def autowidth(self, maxwidth): pixels = 0 for item in self.listBox.get(0, "end"): pixels = max(pixels, self.font_obj.measure(item)) # bump listbox size until all entries fit pixels = pixels + 10 width = int(self.listBox.cget("width")) for w in range(0, maxwidth + 1, 5): if self.listBox.winfo_reqwidth() >= pixels: break self.listBox.config(width=width + w) def _short_bubble_sort(self): exchanges = True passnum = len(self._user_presented_list) - 1 while (passnum > 0) and exchanges: exchanges = False for i in range(passnum): try: if len(self._user_presented_list[i]) > \ len(self._user_presented_list[i + 1]): exchanges = True self._user_presented_list[i], self._user_presented_list[i + 1] = \ self._user_presented_list[i + 1], self._user_presented_list[i] except TypeError as e: pass passnum = passnum - 1 def open_frame(self): self.master.mainloop() def _choose(self, event=None): try: firstIndex = self.listBox.curselection()[0] self.index = firstIndex self.index_value = self._user_presented_list[int(firstIndex)] except IndexError: self.index_value = None self.modalPane.destroy() def _cancel(self, event=None): self.modalPane.destroy() def return_index_value(self): return self.index_value def return_index(self): return self.index def return_enum(self): return {self.index_value: self._user_enum[self.index_value]} def return_value(self): return self._user_enum[self.index_value]
class Tela: """.""" def __init__(self): """.""" self.nomeApp = "Mangás Downloader" self.tk = Tk() self.tk.geometry("600x500") self.tk.resizable(False, False) if not path.isdir('mangas'): mkdir('mangas') if path.isfile("mangas/Paginas.json"): self.ani = load(open("mangas/Paginas.json")) else: self.ani = {'nome': [], 'link': []} self.mylist = None self.scrollbar = None self.fra1 = None self.fra2 = None self.bt1 = None self.bt2 = None self.bt3 = None self.bt4 = None self.ren1 = None self.ren2 = None self.ren3 = None self.btProc = None self.etProc = None self.isVoltar = False self.dir = getcwd() self.busca = StringVar() self.inicia() self.tk.title(self.nomeApp) self.selecionado = -1 # self.icon = self.dir + '\\' + 'down.ico' # self.tk.iconbitmap(self.icon) self.tk.mainloop() def inicia(self): """.""" self.fra1 = Frame(self.tk, bd=1) fra3 = Frame(self.tk, bd=1) self.fra2 = Frame(self.tk, bd=1) self.scrollbar = ttk.Scrollbar(self.tk, orient=VERTICAL) self.mylist = Listbox(self.tk, yscrollcommand=self.scrollbar.set) for i in range(len(self.ani['nome'])): self.mylist.insert(END, self.ani['nome'][i]) self.scrollbar.config(command=self.mylist.yview) self.scrollbar.pack(side=RIGHT, fill=Y) # Buscar Label(self.fra1, text='Anime:').pack(side=LEFT) self.etProc = Entry(self.fra1, textvariable=self.busca, width=65) self.etProc.pack(side=LEFT) self.btProc = Button(self.fra1, text='Procurar', command=self.procura) self.ren1 = Button(fra3, text="Renomear Normal", command=lambda: self.renomear(1)) self.ren2 = Button(fra3, text="Renomear Celular", command=lambda: self.renomear(2)) self.ren3 = Button( fra3, text="Renomear Re-Criar e Celular", command=lambda: self.renomear(3)) self.btProc.pack(side=LEFT) self.fra1.pack(fill=X) fra3.pack() # Lista self.mylist.pack(fill=BOTH, expand=True) # Botoes self.bt1 = Button(self.fra2, text="Pegar valor", command=self.li) self.bt2 = Button(self.fra2, text="Voltar", command=self.voltar) self.bt3 = Button(self.fra2, text="Baixar", command=self.baixar) self.bt4 = Button(self.fra2, text="Atualizar Base", command=self.busca_p) self.ren1.pack(side=LEFT) self.ren2.pack(side=LEFT) self.ren3.pack(side=LEFT) self.bt4.pack(side=LEFT) self.bt1.pack(side=LEFT) self.fra2.pack() def li(self): """.""" if self.mylist.curselection(): buscar = self.mylist.get(self.mylist.curselection()).lower() ind = -1 for i in range(len(self.ani['nome'])): if buscar in self.ani['nome'][i].lower(): ind = i break self.selecionado = ind url = self.ani['link'][ind] nome = str(ind + 1) + " " + \ DownloadWindow.sanitizestring(self.ani['nome'][ind]) new_window = Toplevel(self.tk) Thread(target=Manga, args=[ new_window, self, 'Procurando...', nome, url]).start() def mostra_ani(self): """.""" self.ani = load(open("mangas/" + str(self.selecionado + 1) + " " + DownloadWindow.sanitizestring(self.ani['nome'][self.selecionado]) + ".json")) self.atualiza("cap") self.bt1.forget() self.bt4.forget() self.isVoltar = True self.bt2.pack(side=LEFT) self.bt3.pack(side=LEFT) def procura(self): """.""" buscar = self.busca.get().lower() self.busca.set('') if self.btProc['text'] == 'Procurar': self.btProc['text'] = 'Resetar' self.etProc['state'] = DISABLED ind = [] for i in range(len(self.ani['nome'])): if buscar in self.ani['nome'][i].lower(): ind.append(i) if ind is not []: for i in range(self.mylist.size()): self.mylist.delete(0) for i in ind: self.mylist.insert(END, self.ani['nome'][i]) else: messagebox.showerror("Anime Downloader", "Anime não Encontrado!") else: self.btProc['text'] = 'Procurar' self.etProc['state'] = NORMAL if self.isVoltar: self.voltar() else: self.atualiza('nome') self.isVoltar = False def voltar(self): """.""" self.ani = load(open("mangas/Paginas.json")) self.atualiza("nome") self.bt2.forget() self.bt3.forget() self.bt4.pack(side=LEFT) self.bt1.pack(side=LEFT) def atualiza(self, campo): """.""" for i in range(self.mylist.size()): self.mylist.delete(0) for i in range(len(self.ani[campo])): self.mylist.insert(END, self.ani[campo][i]) def baixar(self): """.""" if self.mylist.curselection(): url = self.ani['link'][self.mylist.curselection()[0]] new_window = Toplevel(self.tk) Thread(target=DownloadWindow, args=[ new_window, url, self.dir]).start() def busca_p(self): """.""" new_window = Toplevel(self.tk) Thread(target=Manga, args=[new_window, self, 'Atualizando...']).start() def renomear(self, esc): """.""" # esc = self.ren.get() Thread(target=self.renomear_thread, args=[esc]).start() def renomear_thread(self, esc): """.""" if esc == 1: self.frenomar(self.dir) self.frenomar(self.dir, col=True, mensagem=0) elif esc == 2: self.frenomar(self.dir) self.frenomar(self.dir, col=True) self.frenomar(self.dir, mensagem=0) elif esc == 3: self.frenomar(self.dir) self.frenomar(self.dir, r=False) # print("Renomeando...") # time.sleep(60) self.frenomar(self.dir, r=False, mensagem=0, coloca_hifen=0) def frenomar(self, caminho, col=False, r=True, mensagem=1, coloca_hifen=1): """.""" for _, __, arquivo in walk(caminho): if (str(_).find(caminho) != -1 and str(_).find("pycache") == -1 and str(_).find(caminho+"/mangas") == -1): tam = __.__len__() if tam == 0: i = 1 arquivo.sort() for arq in arquivo: if not r: try: if 'Thumbs' in arq: continue im = open_image(_ + "/" + arq) x, y = im.size if coloca_hifen == 1: im.resize((x, y), ANTIALIAS).save( _ + "/-" + arq) remove(_ + "/" + arq) else: im.resize((x, y), ANTIALIAS).save( _ + "/" + arq.replace("-", "")) remove(_ + "/" + arq) except (ValueError, IOError): from tkinter import messagebox messagebox.showerror( "Mangás Downloader", "Erro no Arquivo:\n" + _ + "/" + arq) else: if not col: aa = arq.split(".") rename(_ + "/" + arq, _ + "/" + self.nomei(aa[aa.__len__() - 2], col=True) + '.' + aa[aa.__len__() - 1]) else: aa = arq.split(".") rename(_ + "/" + arq, _ + "/" + str(i) + '.' + aa[aa.__len__() - 1]) i += 1 if mensagem != 1: from tkinter import messagebox messagebox.showinfo("Mangás Downloader", "Arquivos Renomeados!") @staticmethod def nomei(i, col=False): """.""" if (str(i).__len__() < 2) and col: i = '0' + str(i) return str(i)
class ListboxVidget(Vidget, Eventor): """ ListboxVidget contains a Listbox widget. It adds the following abilities: - Store items of any type, unlike Listbox widget that only stores texts. - Remember selected item even if the listbox widget lost focus. - Notify pre-change and post-change events. """ # Error raised when trying to change the listbox while a change is going on class CircularCallError(ValueError): pass # Error raised when trying to change the listbox while it is disabled class DisabledError(ValueError): pass # Event notified when the listbox's items are to be changed ITEMS_CHANGE_SOON = 'ITEMS_CHANGE_SOON' # Event notified when the listbox's items are changed ITEMS_CHANGE_DONE = 'ITEMS_CHANGE_DONE' # Event notified when the listbox's active item is to be changed ITEMCUR_CHANGE_SOON = 'ITEMCUR_CHANGE_SOON' # Event notified when the listbox's active item is changed ITEMCUR_CHANGE_DONE = 'ITEMCUR_CHANGE_DONE' # Events list EVENTS = ( ITEMS_CHANGE_SOON, ITEMS_CHANGE_DONE, ITEMCUR_CHANGE_SOON, ITEMCUR_CHANGE_DONE, ) def __init__( self, items=None, item_to_text=None, normal_bg='', normal_fg='', active_bg='sky blue', active_fg='white', selected_bg='steel blue', selected_fg='white', master=None, ): """ Initialize object. @param items: Items list. @param item_to_text: Item-to-text function. Default is `str`. @param normal_bg: Unselected item background color. @param normal_fg: Unselected item foreground color. @param active_bg: Active item background color. `Active` means the item is selected (in general meaning) but the listbox has no focus. @param active_fg: Active item foreground color. `Active` means the item is selected (in general meaning) but the listbox has no focus. @param selected_bg: Selected item background color. `Selected` means the item is selected (in general meaning) and the listbox has focus. @param selected_fg: Selected item foreground color. `Selected` means the item is selected (in general meaning) and the listbox has focus. @param master: Master widget. @return: None. """ # Initialize Vidget. # Create main frame widget. Vidget.__init__( self, master=master, ) # Initialize Eventor Eventor.__init__(self) # If items list is given if items is not None: # If items list is not list if not isinstance(items, list): # Raise error raise TypeError(items) # If items list is list. # If items list is not given, or items list is given and is list # Items list self._items = items if items is not None else [] # Item-to-text function. Default is `str`. self._item_to_text = item_to_text if item_to_text is not None else str # Unselected item background color self._normal_fg = normal_fg # Unselected item foreground color self._normal_bg = normal_bg # Active item background color self._active_fg = active_fg # Active item foreground color self._active_bg = active_bg # Selected item background color self._selected_fg = selected_fg # Selected item foreground color self._selected_bg = selected_bg # Whether the listbox is changing self._is_changing = False # Active index. `-1` means void, i.e. no item is active. self._indexcur = -1 # Whether active index is being reset to same value self._is_resetting = False # Create listbox widget self._listbox = Listbox( master=self.widget(), relief='groove', activestyle='none', highlightthickness=0, # Active index cache only supports single-selection mode for now. # See 2N6OR. selectmode='single', ) # Set the listbox widget as config target self.config_target_set(self._listbox) # Create x-axis scrollbar self._scrollbar_xview = _HiddenScrollbar( self.widget(), orient=HORIZONTAL, ) # Create y-axis scrollbar self._scrollbar_yview = _HiddenScrollbar( self.widget(), orient=VERTICAL, ) # Mount scrollbars self._listbox.config(xscrollcommand=self._scrollbar_xview.set) self._listbox.config(yscrollcommand=self._scrollbar_yview.set) self._scrollbar_xview.config(command=self._listbox.xview) self._scrollbar_yview.config(command=self._listbox.yview) # Bind single-click event handler self._listbox.bind('<Button-1>', self._on_single_click) # Bind double-click event handler self._listbox.bind('<Double-Button-1>', self._on_double_click) # Update listbox widget self._listbox_widget_update(keep_active=False) # Update widget self._widget_update() def _widget_update(self): """ Update widget. @return: None. """ # Row 0 for listbox and y-axis scrollbar self.widget().rowconfigure(0, weight=1) # Row 1 for x-axis scrollbar self.widget().rowconfigure(1, weight=0) # Column 0 for listbox and x-axis scrollbar self.widget().columnconfigure(0, weight=1) # Column 1 for y-axis scrollbar self.widget().columnconfigure(1, weight=0) # Lay out listbox self._listbox.grid(row=0, column=0, sticky='NSEW') # Lay out x-axis scrollbar self._scrollbar_xview.grid(row=1, column=0, sticky='EW') # Lay out y-axis scrollbar self._scrollbar_yview.grid(row=0, column=1, sticky='NS') def is_enabled(self): """ Test whether the listbox is enabled. @return: Boolean. """ # Return whether the listbox is enabled return self._listbox.config('state')[4] != DISABLED def is_changing(self): """ Test whether the listbox is changing. @return: Boolean. """ # Return whether the listbox is changing return self._is_changing def is_resetting(self): """ Test whether the listbox is setting active index to the same value. @return: Boolean. """ # Return whether the listbox is setting active index to the same value return self._is_resetting def size(self): """ Get number of items. @return: Number of items. """ # Return number of items return len(self._items) def items(self): """ Get items list. Notice do not change the list outside. @return: Items list. """ # Return items list return self._items def items_set( self, items, notify=True, keep_active=False, ): """ Set items list. Notice do not change the list outside. @param items: Items list. @param notify: Whether notify pre-change and post-change events. @param keep_active: Whether keep or clear active index. @return: None. """ # If the items is not list if not isinstance(items, list): # Raise error raise TypeError(items) # If the items is list. # If the listbox is disabled if not self.is_enabled(): # Raise error raise ListboxVidget.DisabledError() # If the listbox is not disabled. # If the listbox is changing if self._is_changing: # Raise error raise ListboxVidget.CircularCallError() # If the listbox is not changing. # Set changing flag on self._is_changing = True # If notify events if notify: # Notify pre-change event self.handler_notify(self.ITEMS_CHANGE_SOON) # Store the new items self._items = items # Update listbox widget self._listbox_widget_update( keep_active=keep_active ) # If notify events if notify: # Notify post-change event self.handler_notify(self.ITEMS_CHANGE_DONE) # Set changing flag off self._is_changing = False def index_is_valid(self, index): """ Test whether given index is valid. Notice -1 is not valid. @param index: Index to test. @return: Boolean. """ # Test whether given index is valid return 0 <= index and index < self.size() def index_is_valid_or_void(self, index): """ Test whether given index is valid or is -1. @param index: Index to test. @return: Boolean. """ # Test whether given index is valid or is -1 return index == -1 or self.index_is_valid(index) def index_first(self): """ Get the first item's index. @return: First item's index, or -1 if the listbox is empty. """ # Return the first item's index return 0 if self.size() > 0 else -1 def index_last(self): """ Get the last item's index. @return: Last item's index, or -1 if the listbox is empty. """ # Return the last item's index return self.size() - 1 def indexcur(self, internal=False, raise_error=False): """ Get the active index. @param internal: See 2N6OR. @return: The active index. If no active active, either return -1, or raise IndexError if `raise_error` is True. """ # Get active indexes indexcurs = self._indexcurs(internal=internal) # If have active indexes if indexcurs: # Return the first active index return indexcurs[0] # If no active indexes else: # If raise error if raise_error: # Raise error raise IndexError(-1) # If not raise error else: # Return -1 return -1 def _indexcurs(self, internal=False): """ Get active indexes list. 2N6OR @param internal: Whether use listbox widget's selected indexes, instead of cached active index. Notice listbox widget has no selected indexes if it has no focus. Notice using cached active index only supports single-selection mode, which means the result list has at most one index. @return: Active indexes list. """ # If use listbox widget's selected indexes if internal: # Return listbox widget's selected indexes list return [int(x) for x in self._listbox.curselection()] # If not use listbox widget's selected indexes else: # If cached active index is valid if self.index_is_valid(self._indexcur): # Return a list with the cached active index return [self._indexcur] # If cached active index is not valid else: # Return empty list return [] def indexcur_set( self, index, focus=False, notify=True, notify_arg=None, ): """ Set active index. @param index: The index to set. @param focus: Whether set focus on the listbox widget. @param notify: Whether notify pre-change and post-change events. @param notify_arg: Event argument. @return: None. """ # If the index is not valid or -1 if not self.index_is_valid_or_void(index): # Raise error raise IndexError(index) # If the index is valid or is -1. # If the listbox is not enabled if not self.is_enabled(): # Raise error raise ListboxVidget.DisabledError() # If the listbox is enabled. # If the listbox is changing if self._is_changing: # Raise error raise ListboxVidget.CircularCallError() # If the listbox is not changing. # Set changing flag on self._is_changing = True # Get old active index old_indexcur = self._indexcur # Set resetting flag on if new and old indexes are equal self._is_resetting = (index == old_indexcur) # If notify events if notify: # Notify pre-change event self.handler_notify(self.ITEMCUR_CHANGE_SOON, notify_arg) # If old active index is valid if self.index_is_valid(old_indexcur): # Set old active item's background color to normal color self._listbox.itemconfig(old_indexcur, background=self._normal_bg) # Set old active item's foreground color to normal color self._listbox.itemconfig(old_indexcur, foreground=self._normal_fg) # Cache new active index self._indexcur = index # Clear listbox widget's selection self._listbox.selection_clear(0, END) # Set listbox widget's selection self._listbox.selection_set(index) # Set listbox widget's activated index self._listbox.activate(index) # If new active index is valid if index != -1: # Set new active item's background color to active color self._listbox.itemconfig(index, background=self._active_bg) # Set new active item's foreground color to active color self._listbox.itemconfig(index, foreground=self._active_fg) # If set focus if focus: # Set focus on the listbox widget self._listbox.focus_set() # If new active index is valid if index != -1: # Make the active item visible self._listbox.see(index) # If notify events if notify: # Notify post-change event self.handler_notify(self.ITEMCUR_CHANGE_DONE, notify_arg) # Set resetting flag off self._is_resetting = False # Set changing flag off self._is_changing = False def indexcur_set_by_event( self, event, focus=False, notify=True, notify_arg=None, ): """ Set active index using a Tkinter event object that contains coordinates of the active item. @param event: Tkinter event object. @param focus: Whether set focus on the listbox widget. @param notify: Whether notify pre-change and post-change events. @param notify_arg: Event argument. @return: None. """ # Get the event's y co-ordinate's nearest listbox item index index = self._listbox.nearest(event.y) # If the index is not valid if not self.index_is_valid_or_void(index): # Ignore the event return # If the index is valid else: # Set the index as active index self.indexcur_set( index=index, focus=focus, notify=notify, notify_arg=notify_arg, ) def item(self, index): """ Get item at given index. @return: Item at given index, or IndexError if the index is not valid. """ return self.items()[index] def itemcur(self, internal=False, raise_error=False): """ Get the active item. @param internal: See 2N6OR. @param raise_error: Whether raise error if no active item. @return: The active item. If no active item, if `raise_error` is True, raise IndexError, otherwise return None. """ # Get active index. # May raise IndexError if `raise_error` is True. indexcur = self.indexcur( internal=internal, raise_error=raise_error, ) # If no active index if indexcur == -1: # Return None return None # If have active index else: # Return the active item return self.items()[indexcur] def item_insert( self, item, index=None, notify=True, keep_active=True, ): """ Insert item at given index. @param item: Item to insert. @param index: Index to insert. `None` means active index, and if no active index, insert at the end. @param notify: Whether notify pre-change and post-change events. @param keep_active: Whether keep or clear active index. @return: None. """ # If notify events if notify: # Notify pre-change events self.handler_notify(self.ITEMCUR_CHANGE_SOON) self.handler_notify(self.ITEMS_CHANGE_SOON) # Get old active index active_index = self.indexcur() # If the index is None, # it means use active index. if index is None: # Use active index. # `-1` works and means appending. index = active_index # Insert the item to the items list self._items.insert(index, item) # If old active index is valid if active_index != -1: # If old active index is GE the inserted index if active_index >= index: # Shift active index by one active_index += 1 # If old active index is not GE the inserted index, use it as-is. # Set new active index self.indexcur_set(index=active_index, notify=False) # Update listbox widget self._listbox_widget_update( keep_active=keep_active ) # If notify events if notify: # Notify post-change events self.handler_notify(self.ITEMS_CHANGE_DONE) self.handler_notify(self.ITEMCUR_CHANGE_DONE) def item_remove( self, index, notify=True, keep_active=True, ): """ Remove item at given index. @param index: Index to remove. @param notify: Whether notify pre-change and post-change events. @param keep_active: Whether keep or clear active index. @return: None. """ # If the index is not valid if not self.index_is_valid(index): # Raise error raise ValueError(index) # If the index is valid. # If notify events if notify: # Notify pre-change events self.handler_notify(self.ITEMCUR_CHANGE_SOON) self.handler_notify(self.ITEMS_CHANGE_SOON) # Get old active index active_index = self.indexcur() # Remove item at the index del self._items[index] # If old active index is valid if active_index != -1: # Get the last index index_last = self.index_last() # If old active index is GT the last index if active_index > index_last: # Use the last index as new active index active_index = index_last # If old active index is not GT the last index, use it as-is. # Set new active index self.indexcur_set(index=active_index, notify=False) # Update listbox widget self._listbox_widget_update( keep_active=keep_active ) # If notify events if notify: # Notify post-change events self.handler_notify(self.ITEMS_CHANGE_DONE) self.handler_notify(self.ITEMCUR_CHANGE_DONE) def handler_add( self, event, handler, need_arg=False, ): """ Add event handler for an event. If the event is ListboxVidget event, add the event handler to Eventor. If the event is not ListboxVidget event, add the event handler to listbox widget. Notice this method overrides `Eventor.handler_add` in order to add non-ListboxVidget event handler to listbox widget. @param event: Event name. @param handler: Event handler. @param need_arg: Whether the event handler needs event argument. @return: None. """ # If the event is ListboxVidget event if event in self.EVENTS: # Add the event handler to Eventor return Eventor.handler_add( self, event=event, handler=handler, need_arg=need_arg, ) # If the event is not ListboxVidget event, # it is assumed to be Tkinter widget event. else: # Add the event handler to listbox widget return self.bind( event=event, handler=handler, ) def bind( self, event, handler, ): """ Add event handler to listbox widget. ListboxVidget internally uses `<Button-1>` and `<Double-Button-1>` to capture active index changes. So if the given event is `<Button-1>` or `<Double-Button-1>`, the given handler will be wrapped. @param event: Event name. @param handler: Event handler. @return: None. """ # If the event is not `<Button-1>` or `<Double-Button-1>` if event not in ['<Button-1>', '<Double-Button-1>']: # Add the event handler to listbox widget self._listbox.bind(event, handler) # If the event is `<Button-1>` or `<Double-Button-1>` else: # Create event handler wrapper def handler_wrapper(e): """ Event handler wrapper that sets new active index and then calls the wrapped event handler. Setting new active index is needed because when this handler is called by Tkinter, the active index of the listbox is still old. @param e: Tkinter event object. @return: None. """ # Set new active index self.indexcur_set_by_event(e, notify=True) # Call the wrapped event handler handler(e) # Add the event handler wrapper to the listbox widget self._listbox.bind(event, handler_wrapper) def _on_single_click(self, event): """ `<Button-1>` event handler that updates active index. @param event: Tkinter event object. @return: None. """ # Updates active index self.indexcur_set_by_event(event, notify=True) def _on_double_click(self, event): """ `<Double-Button-1>` event handler that updates active index. @param event: Tkinter event object. @return: None. """ # Updates active index self.indexcur_set_by_event(event, notify=True) def _listbox_widget_update( self, keep_active, ): """ Update listbox widget's items and selection. @param keep_active: Whether keep or clear active index. @return: None. """ # Remove old items from listbox widget self._listbox.delete(0, END) # Insert new items into listbox widget. # For each ListboxVidget items. for index, item in enumerate(self.items()): # Get item text item_text = self._item_to_text(item) # Insert the item text into listbox widget self._listbox.insert(index, item_text) # Set the item's normal background color self._listbox.itemconfig(index, background=self._normal_bg) # Set the item's normal foreground color self._listbox.itemconfig(index, foreground=self._normal_fg) # Set the item's selected background color self._listbox.itemconfig(index, selectbackground=self._selected_bg) # Set the item's selected foreground color self._listbox.itemconfig(index, selectforeground=self._selected_fg) # If keep active index if keep_active: # Use old active index indexcur = self._indexcur # If not keep active index else: # Set active index to -1 indexcur = self._indexcur = -1 # Clear old selection self._listbox.selection_clear(0, END) # Set new selection. # `-1` works. self._listbox.selection_set(indexcur) # Set new active index. # `-1` works. self._listbox.activate(indexcur) # If new active index is valid if indexcur != -1: # Set active background color self._listbox.itemconfig(indexcur, background=self._active_bg) # Set active foreground color self._listbox.itemconfig(indexcur, foreground=self._active_fg) # Make the active item visible self._listbox.see(indexcur)
class Editor(ttk.Notebook): COR_FUNDO = '#282a36' COR_FRENTE = '#ffffdd' def __init__(self, parent): self.parent = parent ttk.Notebook.__init__(self, master=self.parent) self.pack(expand=True, fill='both') self.bind('<Button><3>', self.criaMenuFlutuante) self.fonte = font.Font(family='Consolas', size=12, weight='normal', slant='roman') self.criaAbas() self.rolagemHorizontal() # // cria o menu flutuante com o widget listbox... def criaMenuFlutuante(self, e): opcoes = [ f'Fechar aba atual {" "*14} Ctrl+W', f'Selecionar todo o texto{" "*3} Ctrl+A', f'colar{" "*35} Ctrl+V', f'copiar{" "*33} Ctrl+C', f'recortar{" "*30} Ctrl+X' ] self.menuFlutuante = Listbox(self, width=30, height=5, bg=self.COR_FUNDO, fg=self.COR_FRENTE) for x in range(len(opcoes)): self.menuFlutuante.insert(x, opcoes[x]) self.menuFlutuante.place(x=e.x, y=e.y) self.menuFlutuante.bind('<Leave>', self.fechaMenuFlutuante) self.menuFlutuante.bind('<<ListboxSelect>>', self.menuFlutuanteSelecao) # identifica o elemento clicado no menu flutuante # e age de acordo com a selecao def menuFlutuanteSelecao(self, e=None): item = self.menuFlutuante.curselection()[0] print(item) if item == 0: aba = self.index('current') self.forget(aba) elif item == 1: self.selecionarTudo() elif item == 2: self.colar() elif item == 3: self.copiar() def copiar(self, e=None): self.texto.tag_delete('sels') texto = self.texto.get(1.0, 'end-1c') self.clipboard_clear() self.clipboard_append(texto) def colar(self): self.texto.insert('insert', self.clipboard_get()) self.texto.tag_delete('sels') def recortar(self): texto = self.texto.get('1.0', 'end-1c') self.texto.delete('1.0', 'end') self.clipboard_append(texto) self.texto.tag_delete('sels') # fecha o menu flutuante quando mouse sai... def fechaMenuFlutuante(self, e): self.menuFlutuante.destroy() # cria as novas abas ao clica no menu ou ctrl+n... def criaAbas(self): self.frame = Frame(self, bg=self.COR_FUNDO) self.contaLinha = Text(self.frame, width=5, bd=0, relief='flat', font=self.fonte, bg=self.COR_FUNDO, fg=self.COR_FRENTE) self.contaLinha.bind('<MouseWheel>', self.naoRolar) self.frame.pack(fill='both', expand=True) self.contaLinha.pack(side='left', anchor='w', fill='y') self.texto = Text(self.frame, bd=0, relief='flat', font=self.fonte, bg=self.COR_FUNDO, fg=self.COR_FRENTE, insertbackground='#fff', wrap='none') self.texto.focus_force() self.add(self.frame, text='aba') self.texto.pack(fill='both', side='left', expand=True) self.texto.bind('<KeyPress>', self.insereLinhas) self.texto.bind('<Tab>', self.espacosTab) self.texto.bind('<MouseWheel>', self.detectaRolagem) self.texto.bind('<Button><3>', self.criaMenuFlutuante) self.texto.bind('<Control_L><w>', self.fechaAba) # fecha aba atual com ctrl+w def fechaAba(self, e=None): aba = self.index('current') self.forget(aba) def selecionarTudo(self): self.texto.tag_add('sels', '1.0', 'end-1c') self.texto.tag_config('sels', background='blue') self.texto.mark_set('insert', '1.0') self.texto.see('insert') return 'break' # insere as linhas na lateral esquerda... def insereLinhas(self, e): self.tecla = e.char self.autoPar() if self.tecla in ['\'', '\"', '(', '{', '[']: return 'break' self.linhaAtual = float(self.texto.index('end-1c')) self.contaLinha.insert(self.linhaAtual + 1, str(int(self.linhaAtual)) + '\n') self.deletaLinhas() self.texto.tag_delete('sels') # deleta as linhas sobresalentes.... def deletaLinhas(self): self.contaLinha.delete(float(self.texto.index('end')), 'insert') self.contaLinha.see(float(self.texto.index('insert')) - 1) # transforma os TAB´s em 4 espaços... def espacosTab(self, e): self.texto.insert(self.texto.index('end-1c'), f'{" "*4}') return 'break' # autocompleta pares de delimitadores def autoPar(self): tam = self.texto.index('end-1c') i = tam.index('.') tam = tam[i + 1:] pares = ['\'', '\"', '(', '{', '['] fechaPares = ['\'', '\"', ')', '}', ']'] if self.tecla in pares: par = pares.index(self.tecla) else: return if len(tam) == 1: indice = '%.1f' % (float(self.texto.index('insert'))) elif len(tam) == 2: indice = '%.2f' % (float(self.texto.index('insert'))) elif len(tam) == 3: indice = '%.3f' % (float(self.texto.index('insert'))) self.texto.mark_set('insert', indice) print(indice) self.texto.insert(indice, pares[par] + fechaPares[par]) # detecta a rolagem da area de texto e indica # a mesma para o contador de linhas para rolar junto def detectaRolagem(self, e): self.contaLinha.yview_scroll(int(-1 * (e.delta / 120)), 'units') print(int(-1 * (e.delta))) # detecta se o comprimento da linha ja atingiu o maximo da lagura da # tela e rola automaticamente na horizontal def rolagemHorizontal(self): self.rolagem = Scrollbar(self.texto, orient='horizontal') self.rolagem.pack(side='bottom', fill='x') self.rolagem.configure(command=self.texto.xview) self.texto.configure(xscrollcommand=self.rolagem.set) # impede a rolagem do contador de linhas ao receber um # evento de entrada e rolagem do mouse def naoRolar(self, e): return 'break'
class Add_Recipe_Modal(Modal): def __init__(self, parent=None, title="Add Recipe"): self.shorts = [] self.amounts = None self.ingredients = None Modal.__init__(self, parent, title, geometry="375x410" if system() == "Windows" else "375x350") def initialize(self): amount_label = Label(self, width=8, text="Amount") amount_label.grid(row=0, column=0) ingredients_label = Label(self, width=35, text="Item Name") ingredients_label.grid(row=0, column=1) self.amounts_list = Listbox(self, width=8, selectmode="single") self.amounts_list.bind("<Double-Button-1>", self.edit) self.amounts_list.grid(row=1, column=0, sticky="E") self.ingredients_list = Listbox(self, width=35, selectmode="single") self.ingredients_list.bind("<Double-Button-1>", self.edit) self.ingredients_list.grid(row=1, column=1) add_button = Button(self, width=7, text="Add", command=self.add) self.bind("<Control-+>", self.add) self.bind("<Insert>", self.add) add_button.grid(row=2, column=1, sticky="E") remove_button = Button(self, text="Remove", command=self.remove) self.bind("<Delete>", self.remove) remove_button.grid(row=2, column=0) produces_label = Label(self, text="Produces: ") produces_label.grid(row=3, column=0, sticky="W") self.produces_box = Entry(self, width=5) self.produces_box.insert(0, "1") self.produces_box.grid(row=3, column=1, sticky="W") machine_label = Label(self, text="Machine: ") machine_label.grid(row=4, column=0, sticky="W") self.machine_box = Entry(self) self.machine_box.grid(row=4, column=1, sticky="EW") info_label = Label(self, text="Extra Info: ") info_label.grid(row=5, column=0, sticky="W") self.info_box = Entry(self) self.info_box.grid(row=5, column=1, sticky="EW") cancel_button = Button(self, text="Cancel", width=7, command=self.cancel) self.bind("<Escape>", self.cancel) cancel_button.grid(row=6, column=0, pady=10) ok_button = Button(self, text="OK", width=7, command=self.ok) self.bind("<Return>", self.ok) ok_button.grid(row=6, column=1, pady=10, sticky="E") self.bind("<<ListboxSelect>>", self.sync) def sync(self, event): if event.widget is self.amounts_list and len(self.amounts_list.curselection()) != 0: self.ingredients_list.selection_set(self.amounts_list.curselection()[0]) def add(self, event=None): short, name, amount = Add_Ingredient_Modal().show() if short is not None and name is not None and amount is not None: if name not in self.ingredients_list.get(0, "end"): self.ingredients_list.insert("end", name) self.amounts_list.insert("end", amount) self.shorts.append(short) def edit(self, event=None): if len(self.ingredients_list.curselection()) != 0: index = self.ingredients_list.curselection()[0] current_short = self.shorts[index] current_name = self.ingredients_list.get(index) current_amount = self.amounts_list.get(index) new_short, new_name, new_amount = Edit_Ingredient_Modal().show(current_short, current_name, current_amount) if new_short is not None and new_name is not None and new_amount is not None: self.amounts_list.delete(index) self.ingredients_list.delete(index) self.amounts_list.insert(index, new_amount) self.ingredients_list.insert(index, new_name) self.shorts[index] = new_short def remove(self, event=None): if len(self.ingredients_list.curselection()) != 0: slct = int(self.ingredients_list.curselection()[0]) self.ingredients_list.delete(slct) self.amounts_list.delete(slct) del(self.shorts[slct]) def ok(self, event=None): if len(self.ingredients_list.get(0)) != 0 and self.produces_box is not None and self.produces_box.get().isdigit(): self.produces = int(self.produces_box.get()) self.amounts = self.amounts_list.get(0, last="end") self.ingredients = self.ingredients_list.get(0, last="end") self.machine = self.machine_box.get() self.info = self.info_box.get() self.destroy() def cancel(self, event=None): self.amounts = None self.ingredients = None self.shorts = None self.produces = None self.machine = None self.info = None self.destroy() def show(self): Modal.show(self) return self.shorts, self.ingredients, self.amounts, self.produces, self.machine, self.info
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent, background="#8080FF") self.parent = parent self.initUI() def initUI(self): self.parent.title("EQ GuildViewer 0.1") fontb = Font(size=12, weight="bold") # inicializo variables self.ant = None self.lastLine = 0 self.name = "" # frame padre area = Frame(self) area.pack(side=BOTTOM, fill=BOTH, expand=1) areab = Frame(self) areab.pack(side=TOP, fill=BOTH, expand=1) # scroll players self.scrollbar2 = Scrollbar(areab, orient=VERTICAL) # construimos un menu con todos los nombres del diccionario y un boton self.refreshButton = Button(areab, text="""PARSEA!""", command=self.onRefresh, bd=2, relief="groove") self.listboxLogs = Listbox( areab, width=50, activestyle="none", highlightthickness=0, yscrollcommand=self.scrollbar2.set, relief=RIDGE ) self.listboxLogs.pack(side=LEFT, fill=Y) self.scrollbar2.pack(side=LEFT, fill=Y) self.refreshButton.pack(side=LEFT, fill=BOTH, expand=1) for player in optionsDictionary: self.listboxLogs.insert(END, player) # scroll self.scrollbar = Scrollbar(area, orient=VERTICAL) self.scrollbar.pack(side=RIGHT, fill=Y) # area1 area1 = Frame(area) area1.pack(side=LEFT, fill=Y) lbl = Label(area1, text="Name") self.listbox = Listbox( area1, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl.pack(side=TOP) self.listbox.pack(side=BOTTOM, fill=Y, expand=1) # area2 area2 = Frame(area) area2.pack(side=LEFT, fill=Y) lbl2 = Label(area2, text="Level") self.listbox2 = Listbox( area2, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl2.pack(side=TOP) self.listbox2.pack(side=BOTTOM, fill=Y, expand=1) # area3 area3 = Frame(area) area3.pack(side=LEFT, fill=Y) lbl3 = Label(area3, text="Class") self.listbox3 = Listbox( area3, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl3.pack(side=TOP) self.listbox3.pack(side=BOTTOM, fill=Y, expand=1) # area4 area4 = Frame(area) area4.pack(side=LEFT, fill=Y) lbl4 = Label(area4, text="Race") self.listbox4 = Listbox( area4, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl4.pack(side=TOP) self.listbox4.pack(side=BOTTOM, fill=Y, expand=1) # area3 area5 = Frame(area) area5.pack(side=LEFT, fill=Y) lbl5 = Label(area5, text="Zone") self.listbox5 = Listbox( area5, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none" ) lbl5.pack(side=TOP) self.listbox5.pack(side=BOTTOM, fill=Y, expand=1) self.pack(fill=BOTH, expand=1) # config-scrollbar self.scrollbar.config(command=self.yview) self.scrollbar2["command"] = self.listboxLogs.yview # bindeos de acciones self.listbox.bind("<<ListboxSelect>>", self.onSelect) self.listbox.bind("<MouseWheel>", self.onTest) self.listbox2.bind("<<ListboxSelect>>", self.onSelect) self.listbox2.bind("<MouseWheel>", self.onTest) self.listbox3.bind("<<ListboxSelect>>", self.onSelect) self.listbox3.bind("<MouseWheel>", self.onTest) self.listbox4.bind("<<ListboxSelect>>", self.onSelect) self.listbox4.bind("<MouseWheel>", self.onTest) self.listbox5.bind("<<ListboxSelect>>", self.onSelect) self.listbox5.bind("<MouseWheel>", self.onTest) self.listboxLogs.bind("<<ListboxSelect>>", self.onSelectPlayer) # mostrar la barra de scroll def yview(self, *args): self.listbox.yview(*args) self.listbox2.yview(*args) self.listbox3.yview(*args) self.listbox4.yview(*args) self.listbox5.yview(*args) # accion de la rueda del raton def onTest(self, val): return "break" # seleccionar un elementos de una listbox def onSelect(self, val): try: if self.ant != None: self.listbox.itemconfig(self.ant, background="#FFFFFF") self.listbox2.itemconfig(self.ant, background="#FFFFFF") self.listbox3.itemconfig(self.ant, background="#FFFFFF") self.listbox4.itemconfig(self.ant, background="#FFFFFF") self.listbox5.itemconfig(self.ant, background="#FFFFFF") self.listbox.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox2.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox3.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox4.itemconfig(val.widget.curselection(), background="#C0C0C0") self.listbox5.itemconfig(val.widget.curselection(), background="#C0C0C0") self.ant = val.widget.curselection() except: None # print('No hay valores') # dependiendo de que nombre se elija en el menu cargamos en lastLine la linea de ese nombre del diccionario def onSelectPlayer(self, val): try: self.name = val.widget.get(val.widget.curselection()) self.lastLine = optionsDictionary[self.name] # print(self.name, ' ', self.lastLine) except: None # print('No hay valores') # recorremos el fichero log al clickar sobre el boton 'Refresh!' def onRefresh(self): if self.name != "": yes = False count = 0 dictionary = {} dictionaryAuxiliar = {} stringLog = "../eqlog_" + str(self.name) + "_project1999.txt" with open(stringLog, "r") as log: for i in range(int(self.lastLine)): next(log) count = count + 1 for line in log: match = re.match("\[.*\] \[(.*) (.*)\] (.*) \((.*)\) <.*> ZONE: (.*)", line) matchRole = re.match("\[.*\] \[(.*)\] (.*) <.*>", line) matchToken = re.match("\[.*\] You say, 't0000'", line) matchTokenI = re.match("\[.*\] You say, 't0001'", line) if matchTokenI != None: yes = True elif match != None and yes: dictionaryAuxiliar[match.group(3)] = ( match.group(1), match.group(2), match.group(4), match.group(5), ) elif matchRole != None and yes: dictionaryAuxiliar[matchRole.group(2)] = [(matchRole.group(1))] elif matchToken != None and yes: dictionary = dictionaryAuxiliar.copy() dictionaryAuxiliar.clear() yes = False count = count + 1 # bucle para sacar datos, primero eliminamos todo lo que haya self.listbox.delete(0, self.listbox.size()) self.listbox2.delete(0, self.listbox2.size()) self.listbox3.delete(0, self.listbox3.size()) self.listbox4.delete(0, self.listbox4.size()) self.listbox5.delete(0, self.listbox5.size()) for member in dictionary: self.listbox.insert(END, member) self.listbox2.insert(END, dictionary[member][0]) try: self.listbox3.insert(END, dictionary[member][1]) self.listbox4.insert(END, dictionary[member][2]) self.listbox5.insert(END, dictionary[member][3]) except IndexError as error: self.listbox3.insert(END, "-") self.listbox5.insert(END, "-") self.listbox4.insert(END, "-") # print(dictionary) # print('Longitud', len(dictionary)) # guardamos la linea ultima leida en el diccionario # self.lastLine = count # optionsDictionary[self.name] = count # print('Despues:', optionsDictionary) # guardamos el diccionario en el archivo options options = open("options.txt", "w") for player in optionsDictionary: options.write(str(player) + ":" + str(optionsDictionary[player])) options.close()
class RecursiveDescentApp: """ A graphical tool for exploring the recursive descent parser. The tool displays the parser's tree and the remaining text, and allows the user to control the parser's operation. In particular, the user can expand subtrees on the frontier, match tokens on the frontier against the text, and backtrack. A "step" button simply steps through the parsing process, performing the operations that ``RecursiveDescentParser`` would use. """ def __init__(self, grammar, sent, trace=0): self._sent = sent self._parser = SteppingRecursiveDescentParser(grammar, trace) # Set up the main window. self._top = Tk() self._top.title("Recursive Descent Parser Application") # Set up key bindings. self._init_bindings() # Initialize the fonts. self._init_fonts(self._top) # Animations. animating_lock is a lock to prevent the demo # from performing new operations while it's animating. self._animation_frames = IntVar(self._top) self._animation_frames.set(5) self._animating_lock = 0 self._autostep = 0 # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_feedback(self._top) self._init_grammar(self._top) self._init_canvas(self._top) # Initialize the parser. self._parser.initialize(self._sent) # Resize callback self._canvas.bind("<Configure>", self._configure) ######################################### ## Initialization Helpers ######################################### def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget("size")) self._boldfont = Font(family="helvetica", weight="bold", size=self._size.get()) self._font = Font(family="helvetica", size=self._size.get()) if self._size.get() < 0: big = self._size.get() - 2 else: big = self._size.get() + 2 self._bigfont = Font(family="helvetica", weight="bold", size=big) def _init_grammar(self, parent): # Grammar view. self._prodframe = listframe = Frame(parent) self._prodframe.pack(fill="both", side="left", padx=2) self._prodlist_label = Label(self._prodframe, font=self._boldfont, text="Available Expansions") self._prodlist_label.pack() self._prodlist = Listbox( self._prodframe, selectmode="single", relief="groove", background="white", foreground="#909090", font=self._font, selectforeground="#004040", selectbackground="#c0f0c0", ) self._prodlist.pack(side="right", fill="both", expand=1) self._productions = list(self._parser.grammar().productions()) for production in self._productions: self._prodlist.insert("end", (" %s" % production)) self._prodlist.config(height=min(len(self._productions), 25)) # Add a scrollbar if there are more than 25 productions. if len(self._productions) > 25: listscroll = Scrollbar(self._prodframe, orient="vertical") self._prodlist.config(yscrollcommand=listscroll.set) listscroll.config(command=self._prodlist.yview) listscroll.pack(side="left", fill="y") # If they select a production, apply it. self._prodlist.bind("<<ListboxSelect>>", self._prodlist_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind("<Control-q>", self.destroy) self._top.bind("<Control-x>", self.destroy) self._top.bind("<Escape>", self.destroy) self._top.bind("e", self.expand) # self._top.bind('<Alt-e>', self.expand) # self._top.bind('<Control-e>', self.expand) self._top.bind("m", self.match) self._top.bind("<Alt-m>", self.match) self._top.bind("<Control-m>", self.match) self._top.bind("b", self.backtrack) self._top.bind("<Alt-b>", self.backtrack) self._top.bind("<Control-b>", self.backtrack) self._top.bind("<Control-z>", self.backtrack) self._top.bind("<BackSpace>", self.backtrack) self._top.bind("a", self.autostep) # self._top.bind('<Control-a>', self.autostep) self._top.bind("<Control-space>", self.autostep) self._top.bind("<Control-c>", self.cancel_autostep) self._top.bind("<space>", self.step) self._top.bind("<Delete>", self.reset) self._top.bind("<Control-p>", self.postscript) # self._top.bind('<h>', self.help) # self._top.bind('<Alt-h>', self.help) self._top.bind("<Control-h>", self.help) self._top.bind("<F1>", self.help) # self._top.bind('<g>', self.toggle_grammar) # self._top.bind('<Alt-g>', self.toggle_grammar) # self._top.bind('<Control-g>', self.toggle_grammar) self._top.bind("<Control-g>", self.edit_grammar) self._top.bind("<Control-t>", self.edit_sentence) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill="none", side="bottom", padx=3, pady=2) Button( buttonframe, text="Step", background="#90c0d0", foreground="black", command=self.step, ).pack(side="left") Button( buttonframe, text="Autostep", background="#90c0d0", foreground="black", command=self.autostep, ).pack(side="left") Button( buttonframe, text="Expand", underline=0, background="#90f090", foreground="black", command=self.expand, ).pack(side="left") Button( buttonframe, text="Match", underline=0, background="#90f090", foreground="black", command=self.match, ).pack(side="left") Button( buttonframe, text="Backtrack", underline=0, background="#f0a0a0", foreground="black", command=self.backtrack, ).pack(side="left") # Replace autostep... # self._autostep_button = Button(buttonframe, text='Autostep', # underline=0, command=self.autostep) # self._autostep_button.pack(side='left') def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas["scrollregion"] = "%d %d %d %d" % (x1, y1, x2, y2) self._redraw() def _init_feedback(self, parent): self._feedbackframe = feedbackframe = Frame(parent) feedbackframe.pack(fill="x", side="bottom", padx=3, pady=3) self._lastoper_label = Label(feedbackframe, text="Last Operation:", font=self._font) self._lastoper_label.pack(side="left") lastoperframe = Frame(feedbackframe, relief="sunken", border=1) lastoperframe.pack(fill="x", side="right", expand=1, padx=5) self._lastoper1 = Label(lastoperframe, foreground="#007070", background="#f0f0f0", font=self._font) self._lastoper2 = Label( lastoperframe, anchor="w", width=30, foreground="#004040", background="#f0f0f0", font=self._font, ) self._lastoper1.pack(side="left") self._lastoper2.pack(side="left", fill="x", expand=1) def _init_canvas(self, parent): self._cframe = CanvasFrame( parent, background="white", # width=525, height=250, closeenough=10, border=2, relief="sunken", ) self._cframe.pack(expand=1, fill="both", side="top", pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Reset Parser", underline=0, command=self.reset, accelerator="Del") filemenu.add_command( label="Print to Postscript", underline=0, command=self.postscript, accelerator="Ctrl-p", ) filemenu.add_command(label="Exit", underline=1, command=self.destroy, accelerator="Ctrl-x") menubar.add_cascade(label="File", underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command( label="Edit Grammar", underline=5, command=self.edit_grammar, accelerator="Ctrl-g", ) editmenu.add_command( label="Edit Text", underline=5, command=self.edit_sentence, accelerator="Ctrl-t", ) menubar.add_cascade(label="Edit", underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label="Step", underline=1, command=self.step, accelerator="Space") rulemenu.add_separator() rulemenu.add_command(label="Match", underline=0, command=self.match, accelerator="Ctrl-m") rulemenu.add_command(label="Expand", underline=0, command=self.expand, accelerator="Ctrl-e") rulemenu.add_separator() rulemenu.add_command(label="Backtrack", underline=0, command=self.backtrack, accelerator="Ctrl-b") menubar.add_cascade(label="Apply", underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton( label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar, ) viewmenu.add_separator() viewmenu.add_radiobutton( label="Tiny", variable=self._size, underline=0, value=10, command=self.resize, ) viewmenu.add_radiobutton( label="Small", variable=self._size, underline=0, value=12, command=self.resize, ) viewmenu.add_radiobutton( label="Medium", variable=self._size, underline=0, value=14, command=self.resize, ) viewmenu.add_radiobutton( label="Large", variable=self._size, underline=0, value=18, command=self.resize, ) viewmenu.add_radiobutton( label="Huge", variable=self._size, underline=0, value=24, command=self.resize, ) menubar.add_cascade(label="View", underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animation_frames, value=0) animatemenu.add_radiobutton( label="Slow Animation", underline=0, variable=self._animation_frames, value=10, accelerator="-", ) animatemenu.add_radiobutton( label="Normal Animation", underline=0, variable=self._animation_frames, value=5, accelerator="=", ) animatemenu.add_radiobutton( label="Fast Animation", underline=0, variable=self._animation_frames, value=2, accelerator="+", ) menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", underline=0, command=self.about) helpmenu.add_command(label="Instructions", underline=0, command=self.help, accelerator="F1") menubar.add_cascade(label="Help", underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Helper ######################################### def _get(self, widget, treeloc): for i in treeloc: widget = widget.subtrees()[i] if isinstance(widget, TreeSegmentWidget): widget = widget.label() return widget ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old tree, widgets, etc. if self._tree is not None: self._cframe.destroy_widget(self._tree) for twidget in self._textwidgets: self._cframe.destroy_widget(twidget) if self._textline is not None: self._canvas.delete(self._textline) # Draw the tree. helv = ("helvetica", -self._size.get()) bold = ("helvetica", -self._size.get(), "bold") attribs = { "tree_color": "#000000", "tree_width": 2, "node_font": bold, "leaf_font": helv, } tree = self._parser.tree() self._tree = tree_to_treesegment(canvas, tree, **attribs) self._cframe.add_widget(self._tree, 30, 5) # Draw the text. helv = ("helvetica", -self._size.get()) bottom = y = self._cframe.scrollregion()[3] self._textwidgets = [ TextWidget(canvas, word, font=self._font) for word in self._sent ] for twidget in self._textwidgets: self._cframe.add_widget(twidget, 0, 0) twidget.move(0, bottom - twidget.bbox()[3] - 5) y = min(y, twidget.bbox()[1]) # Draw a line over the text, to separate it from the tree. self._textline = canvas.create_line(-5000, y - 5, 5000, y - 5, dash=".") # Highlight appropriate nodes. self._highlight_nodes() self._highlight_prodlist() # Make sure the text lines up. self._position_text() def _redraw_quick(self): # This should be more-or-less sufficient after an animation. self._highlight_nodes() self._highlight_prodlist() self._position_text() def _highlight_nodes(self): # Highlight the list of nodes to be checked. bold = ("helvetica", -self._size.get(), "bold") for treeloc in self._parser.frontier()[:1]: self._get(self._tree, treeloc)["color"] = "#20a050" self._get(self._tree, treeloc)["font"] = bold for treeloc in self._parser.frontier()[1:]: self._get(self._tree, treeloc)["color"] = "#008080" def _highlight_prodlist(self): # Highlight the productions that can be expanded. # Boy, too bad tkinter doesn't implement Listbox.itemconfig; # that would be pretty useful here. self._prodlist.delete(0, "end") expandable = self._parser.expandable_productions() untried = self._parser.untried_expandable_productions() productions = self._productions for index in range(len(productions)): if productions[index] in expandable: if productions[index] in untried: self._prodlist.insert(index, " %s" % productions[index]) else: self._prodlist.insert(index, " %s (TRIED)" % productions[index]) self._prodlist.selection_set(index) else: self._prodlist.insert(index, " %s" % productions[index]) def _position_text(self): # Line up the text widgets that are matched against the tree numwords = len(self._sent) num_matched = numwords - len(self._parser.remaining_text()) leaves = self._tree_leaves()[:num_matched] xmax = self._tree.bbox()[0] for i in range(0, len(leaves)): widget = self._textwidgets[i] leaf = leaves[i] widget["color"] = "#006040" leaf["color"] = "#006040" widget.move(leaf.bbox()[0] - widget.bbox()[0], 0) xmax = widget.bbox()[2] + 10 # Line up the text widgets that are not matched against the tree. for i in range(len(leaves), numwords): widget = self._textwidgets[i] widget["color"] = "#a0a0a0" widget.move(xmax - widget.bbox()[0], 0) xmax = widget.bbox()[2] + 10 # If we have a complete parse, make everything green :) if self._parser.currently_complete(): for twidget in self._textwidgets: twidget["color"] = "#00a000" # Move the matched leaves down to the text. for i in range(0, len(leaves)): widget = self._textwidgets[i] leaf = leaves[i] dy = widget.bbox()[1] - leaf.bbox()[3] - 10.0 dy = max(dy, leaf.parent().label().bbox()[3] - leaf.bbox()[3] + 10) leaf.move(0, dy) def _tree_leaves(self, tree=None): if tree is None: tree = self._tree if isinstance(tree, TreeSegmentWidget): leaves = [] for child in tree.subtrees(): leaves += self._tree_leaves(child) return leaves else: return [tree] ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def reset(self, *e): self._autostep = 0 self._parser.initialize(self._sent) self._lastoper1["text"] = "Reset Application" self._lastoper2["text"] = "" self._redraw() def autostep(self, *e): if self._animation_frames.get() == 0: self._animation_frames.set(2) if self._autostep: self._autostep = 0 else: self._autostep = 1 self._step() def cancel_autostep(self, *e): # self._autostep_button['text'] = 'Autostep' self._autostep = 0 # Make sure to stop auto-stepping if we get any user input. def step(self, *e): self._autostep = 0 self._step() def match(self, *e): self._autostep = 0 self._match() def expand(self, *e): self._autostep = 0 self._expand() def backtrack(self, *e): self._autostep = 0 self._backtrack() def _step(self): if self._animating_lock: return # Try expanding, matching, and backtracking (in that order) if self._expand(): pass elif self._parser.untried_match() and self._match(): pass elif self._backtrack(): pass else: self._lastoper1["text"] = "Finished" self._lastoper2["text"] = "" self._autostep = 0 # Check if we just completed a parse. if self._parser.currently_complete(): self._autostep = 0 self._lastoper2["text"] += " [COMPLETE PARSE]" def _expand(self, *e): if self._animating_lock: return old_frontier = self._parser.frontier() rv = self._parser.expand() if rv is not None: self._lastoper1["text"] = "Expand:" self._lastoper2["text"] = rv self._prodlist.selection_clear(0, "end") index = self._productions.index(rv) self._prodlist.selection_set(index) self._animate_expand(old_frontier[0]) return True else: self._lastoper1["text"] = "Expand:" self._lastoper2["text"] = "(all expansions tried)" return False def _match(self, *e): if self._animating_lock: return old_frontier = self._parser.frontier() rv = self._parser.match() if rv is not None: self._lastoper1["text"] = "Match:" self._lastoper2["text"] = rv self._animate_match(old_frontier[0]) return True else: self._lastoper1["text"] = "Match:" self._lastoper2["text"] = "(failed)" return False def _backtrack(self, *e): if self._animating_lock: return if self._parser.backtrack(): elt = self._parser.tree() for i in self._parser.frontier()[0]: elt = elt[i] self._lastoper1["text"] = "Backtrack" self._lastoper2["text"] = "" if isinstance(elt, Tree): self._animate_backtrack(self._parser.frontier()[0]) else: self._animate_match_backtrack(self._parser.frontier()[0]) return True else: self._autostep = 0 self._lastoper1["text"] = "Finished" self._lastoper2["text"] = "" return False def about(self, *e): ABOUT = ("NLTK Recursive Descent Parser Application\n" + "Written by Edward Loper") TITLE = "About: Recursive Descent Parser Application" try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def help(self, *e): self._autostep = 0 # The default font's not very legible; try using 'fixed' instead. try: ShowText( self._top, "Help: Recursive Descent Parser Application", (__doc__ or "").strip(), width=75, font="fixed", ) except: ShowText( self._top, "Help: Recursive Descent Parser Application", (__doc__ or "").strip(), width=75, ) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size + 2))) self._redraw() ######################################### ## Expand Production Selection ######################################### def _toggle_grammar(self, *e): if self._show_grammar.get(): self._prodframe.pack(fill="both", side="left", padx=2, after=self._feedbackframe) self._lastoper1["text"] = "Show Grammar" else: self._prodframe.pack_forget() self._lastoper1["text"] = "Hide Grammar" self._lastoper2["text"] = "" # def toggle_grammar(self, *e): # self._show_grammar = not self._show_grammar # if self._show_grammar: # self._prodframe.pack(fill='both', expand='y', side='left', # after=self._feedbackframe) # self._lastoper1['text'] = 'Show Grammar' # else: # self._prodframe.pack_forget() # self._lastoper1['text'] = 'Hide Grammar' # self._lastoper2['text'] = '' def _prodlist_select(self, event): selection = self._prodlist.curselection() if len(selection) != 1: return index = int(selection[0]) old_frontier = self._parser.frontier() production = self._parser.expand(self._productions[index]) if production: self._lastoper1["text"] = "Expand:" self._lastoper2["text"] = production self._prodlist.selection_clear(0, "end") self._prodlist.selection_set(index) self._animate_expand(old_frontier[0]) else: # Reset the production selections. self._prodlist.selection_clear(0, "end") for prod in self._parser.expandable_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) ######################################### ## Animation ######################################### def _animate_expand(self, treeloc): oldwidget = self._get(self._tree, treeloc) oldtree = oldwidget.parent() top = not isinstance(oldtree.parent(), TreeSegmentWidget) tree = self._parser.tree() for i in treeloc: tree = tree[i] widget = tree_to_treesegment( self._canvas, tree, node_font=self._boldfont, leaf_color="white", tree_width=2, tree_color="white", node_color="white", leaf_font=self._font, ) widget.label()["color"] = "#20a050" (oldx, oldy) = oldtree.label().bbox()[:2] (newx, newy) = widget.label().bbox()[:2] widget.move(oldx - newx, oldy - newy) if top: self._cframe.add_widget(widget, 0, 5) widget.move(30 - widget.label().bbox()[0], 0) self._tree = widget else: oldtree.parent().replace_child(oldtree, widget) # Move the children over so they don't overlap. # Line the children up in a strange way. if widget.subtrees(): dx = (oldx + widget.label().width() / 2 - widget.subtrees()[0].bbox()[0] / 2 - widget.subtrees()[0].bbox()[2] / 2) for subtree in widget.subtrees(): subtree.move(dx, 0) self._makeroom(widget) if top: self._cframe.destroy_widget(oldtree) else: oldtree.destroy() colors = [ "gray%d" % (10 * int(10 * x / self._animation_frames.get())) for x in range(self._animation_frames.get(), 0, -1) ] # Move the text string down, if necessary. dy = widget.bbox()[3] + 30 - self._canvas.coords(self._textline)[1] if dy > 0: for twidget in self._textwidgets: twidget.move(0, dy) self._canvas.move(self._textline, 0, dy) self._animate_expand_frame(widget, colors) def _makeroom(self, treeseg): """ Make sure that no sibling tree bbox's overlap. """ parent = treeseg.parent() if not isinstance(parent, TreeSegmentWidget): return index = parent.subtrees().index(treeseg) # Handle siblings to the right rsiblings = parent.subtrees()[index + 1:] if rsiblings: dx = treeseg.bbox()[2] - rsiblings[0].bbox()[0] + 10 for sibling in rsiblings: sibling.move(dx, 0) # Handle siblings to the left if index > 0: lsibling = parent.subtrees()[index - 1] dx = max(0, lsibling.bbox()[2] - treeseg.bbox()[0] + 10) treeseg.move(dx, 0) # Keep working up the tree. self._makeroom(parent) def _animate_expand_frame(self, widget, colors): if len(colors) > 0: self._animating_lock = 1 widget["color"] = colors[0] for subtree in widget.subtrees(): if isinstance(subtree, TreeSegmentWidget): subtree.label()["color"] = colors[0] else: subtree["color"] = colors[0] self._top.after(50, self._animate_expand_frame, widget, colors[1:]) else: widget["color"] = "black" for subtree in widget.subtrees(): if isinstance(subtree, TreeSegmentWidget): subtree.label()["color"] = "black" else: subtree["color"] = "black" self._redraw_quick() widget.label()["color"] = "black" self._animating_lock = 0 if self._autostep: self._step() def _animate_backtrack(self, treeloc): # Flash red first, if we're animating. if self._animation_frames.get() == 0: colors = [] else: colors = ["#a00000", "#000000", "#a00000"] colors += [ "gray%d" % (10 * int(10 * x / (self._animation_frames.get()))) for x in range(1, self._animation_frames.get() + 1) ] widgets = [self._get(self._tree, treeloc).parent()] for subtree in widgets[0].subtrees(): if isinstance(subtree, TreeSegmentWidget): widgets.append(subtree.label()) else: widgets.append(subtree) self._animate_backtrack_frame(widgets, colors) def _animate_backtrack_frame(self, widgets, colors): if len(colors) > 0: self._animating_lock = 1 for widget in widgets: widget["color"] = colors[0] self._top.after(50, self._animate_backtrack_frame, widgets, colors[1:]) else: for widget in widgets[0].subtrees(): widgets[0].remove_child(widget) widget.destroy() self._redraw_quick() self._animating_lock = 0 if self._autostep: self._step() def _animate_match_backtrack(self, treeloc): widget = self._get(self._tree, treeloc) node = widget.parent().label() dy = (node.bbox()[3] - widget.bbox()[1] + 14) / max( 1, self._animation_frames.get()) self._animate_match_backtrack_frame(self._animation_frames.get(), widget, dy) def _animate_match(self, treeloc): widget = self._get(self._tree, treeloc) dy = (self._textwidgets[0].bbox()[1] - widget.bbox()[3] - 10.0) / max( 1, self._animation_frames.get()) self._animate_match_frame(self._animation_frames.get(), widget, dy) def _animate_match_frame(self, frame, widget, dy): if frame > 0: self._animating_lock = 1 widget.move(0, dy) self._top.after(10, self._animate_match_frame, frame - 1, widget, dy) else: widget["color"] = "#006040" self._redraw_quick() self._animating_lock = 0 if self._autostep: self._step() def _animate_match_backtrack_frame(self, frame, widget, dy): if frame > 0: self._animating_lock = 1 widget.move(0, dy) self._top.after(10, self._animate_match_backtrack_frame, frame - 1, widget, dy) else: widget.parent().remove_child(widget) widget.destroy() self._animating_lock = 0 if self._autostep: self._step() def edit_grammar(self, *e): CFGEditor(self._top, self._parser.grammar(), self.set_grammar) def set_grammar(self, grammar): self._parser.set_grammar(grammar) self._productions = list(grammar.productions()) self._prodlist.delete(0, "end") for production in self._productions: self._prodlist.insert("end", (" %s" % production)) def edit_sentence(self, *e): sentence = " ".join(self._sent) title = "Edit Text" instr = "Enter a new sentence to parse." EntryDialog(self._top, sentence, instr, self.set_sentence, title) def set_sentence(self, sentence): self._sent = sentence.split() # [XX] use tagged? self.reset()
class ListChooserDialog: def __init__(self, parent, listEntries, guiPrompt, allowManualFolderSelection, forceFolderOnlyChoosing=False): """ NOTE: do not call this constructor directly. Use the ListChooserDialog.showDialog function instead. """ self.forceFolderOnlyChoosing = forceFolderOnlyChoosing self.top = tkinter.Toplevel(parent) defaultPadding = {"padx":20, "pady":10} # Set a description for this dialog (eg "Please choose a game to mod" tkinter.Label(self.top, text=guiPrompt).pack() # Define the main listbox to hold the choices given by the 'listEntries' parameter listboxFrame = tkinter.Frame(self.top) # Define a scrollbar and a listbox. The yscrollcommand is so that the listbox can control the scrollbar scrollbar = tkinter.Scrollbar(listboxFrame, orient=tkinter.VERTICAL) self.listbox = Listbox(listboxFrame, selectmode=tkinter.BROWSE, yscrollcommand=scrollbar.set) # Also configure the scrollbar to control the listbox, and pack it scrollbar.config(command=self.listbox.yview) scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y) # Setting width to 0 forces auto-resize of listbox see: https://stackoverflow.com/a/26504193/848627 for item in listEntries: self.listbox.insert(tkinter.END, item) self.listbox.config(width=0) self.listbox.pack(side=tkinter.LEFT, fill=tkinter.BOTH, expand=1) # Finally, pack the Frame so its contents are displayed on the dialog listboxFrame.pack(**defaultPadding) # If the user is allowed to choose a directory manually, add directory chooser button if allowManualFolderSelection: b2 = tkinter.Button(self.top, text="Choose Folder Manually", command=self.showDirectoryChooser) b2.pack(**defaultPadding) # Add an 'OK' button. When pressed, the dialog is closed b = tkinter.Button(self.top, text="OK", command=self.ok) b.pack(**defaultPadding) # This variable stores the returned value from the dialog self.result = None def showDirectoryChooser(self): if IS_MAC and not self.forceFolderOnlyChoosing: self.result = filedialog.askopenfilename(filetypes=[(None, "com.apple.application")]) else: self.result = filedialog.askdirectory() self.top.destroy() def ok(self): """ This function is called when the 'OK' button is pressed. It retrieves the value of the currently selected item, then closes the dialog :return: """ selected_value = None if len(self.listbox.curselection()) > 0: selected_index = self.listbox.curselection()[0] selected_value = self.listbox.get(selected_index) self.result = selected_value self.top.destroy() @staticmethod def showDialog(rootGUIWindow, choiceList, guiPrompt, allowManualFolderSelection, forceFolderOnlyChoosing=False): """ Static helper function to show dialog and get a return value. Arguments are the same as constructor :param rootGUIWindow: the parent tkinter object of the dialog (can be root window) :param choiceList: a list of strings that the user is to choose from :param guiPrompt: the description that will be shown on the dialog :param allowManualFolderSelection: if true, user is allowed to select a folder manually. :return: returns the value the user selected (string), or None if none available """ d = ListChooserDialog(rootGUIWindow, choiceList, guiPrompt, allowManualFolderSelection, forceFolderOnlyChoosing) rootGUIWindow.wait_window(d.top) return d.result
class GUI: def __init__(self, master): self.master = master master.title("Zoom Poll Analyzer") master.geometry("1200x800") master.configure(bg="red3") self.listee = Listbox(master, width=80, height=35) self.listee.place(x=50, y=140) self.header = Label(master, text="ZOOM POLL ANALYZER", width=30, height=2, font=30).place(x=500, y=50) self.buton4 = Button(master, text="Start", width=35, height=2, command=self.start).place(x=850, y=475) self.buton5 = Button(master, text="Show Result", width=35, height=2, command=self.newwindow).place(x=850, y=550) self.buton6 = Button(master, text="Show Histograms", width=35, height=2, command=self.imagewindow).place(x=850, y=625) def start(self): driver = ZoomPollAnalyzer("answer-keys-directory", "students-list-directory", "polls-directory", "output") driver.start() if os.name == 'posix': self.names = glob.glob(os.getcwd() + "/output/**/*.xlsx", recursive=True) for i in self.names: if "Poll" in i.split("/")[-1]: self.listee.insert(0, i.split("/")[-1]) elif "attendance" in i.split("/")[-1]: self.listee.insert(0, i.split("/")[-1]) else: self.names = glob.glob(os.getcwd() + "\output/*.xlsx", recursive=True) for i in self.names: if "Poll" in i.split("\\")[-1]: self.listee.insert(0, i.split("\\")[-1]) elif "attendance" in i.split("\\")[-1]: self.listee.insert(0, i.split("\\")[-1]) def newwindow(self): self.window = Tk() self.window.title("Student List") self.window.geometry("1000x600") xls = pd.ExcelFile(os.getcwd() + "/output/" + self.listee.get(self.listee.curselection())) sheetData = pd.read_excel(xls, 'Sheet1') headings = sheetData.columns data = list(headings.values.tolist()) rows = len(sheetData) tree = ttk.Treeview(self.window, columns=data, show=["headings"], selectmode='browse') tree.place(x=0, y=100) for heading in headings: heading = str(heading) tree.column(heading, width=120, anchor='center') tree.heading(heading, text=heading) for rownumber in range(rows): rowvalue = sheetData.values[rownumber] rowdata = tuple(rowvalue) tree.insert('', 'end', values=rowdata) def imagewindow(self): self.imagewindoww = Toplevel(bg='yellow') self.imagewindoww.title("Histograms With Reports") self.imagewindoww.geometry("1000x600") self.combo = ttk.Combobox(self.imagewindoww) self.combo.place(x=50, y=50) path = (os.getcwd() + "/output/Histograms " + self.listee.get(self.listee.curselection())).split(".xlsx")[0] self.png_dict = {} combo_values = [] self.name = glob.glob(path[:-1] + str(int(path[-1]) - 1) + "/*.png", recursive=True) for qe in self.name: png = qe.split("/")[-1] combo_values.append(png.split(".")[0]) self.png_dict[png.split(".")[0]] = qe combo_values.sort() self.combo["values"] = combo_values self.combo.bind("<<ComboboxSelected>>", lambda event: self.imageshow1(event)) def imageshow1(self, event): png_file = self.combo.get() self.image = Image.open(self.png_dict[png_file]) self.resized = self.image.resize((500, 500), Image.ANTIALIAS) self.photo = ImageTk.PhotoImage(self.resized) self.showimage = Label(self.imagewindoww, image=self.photo) self.showimage.resized = self.photo self.showimage.place(x=50, y=100) excel = self.png_dict[png_file].split(".png")[0] + ".xlsx" xls = pd.ExcelFile(excel) sheetData = pd.read_excel(xls, 'Sheet1') headings = sheetData.columns data = list(headings.values.tolist()) rows = len(sheetData) tree = ttk.Treeview(self.imagewindoww, columns=data, show=["headings"], selectmode='browse') tree.place(x=600, y=100) for heading in headings: heading = str(heading) tree.column(heading, width=200, anchor='center') tree.heading(heading, text=heading) for rownumber in range(rows): rowvalue = sheetData.values[rownumber] rowdata = tuple(rowvalue) tree.insert('', 'end', values=rowdata)
my_listbox.pack(pady=15) ## coz of my_listbox no defined so got to put it here scroll_bar_4_my_listbox.config(command=my_listbox.yview) # my_listbox.insert(0, "This is an item") #? 0 -> put it in the first one # #? END -> put it in the END my_list = [ "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven" ] for content in my_list: my_listbox.insert(END, content) my_listbox.insert(15, "this is an new item") #? put it in the 16th place def delete_all(): my_listbox.delete(0, END) #? delete all def delete(): my_listbox.delete( ANCHOR ) #? when something in the list box is highlighted when you click on it, That is the ANCHOR Tk.update(root) def select():
class DrtGlueDemo: def __init__(self, examples): # Set up the main window. self._top = Tk() self._top.title("DRT Glue Demo") # Set up key bindings. self._init_bindings() # Initialize the fonts.self._error = None self._init_fonts(self._top) self._examples = examples self._readingCache = [None for example in examples] # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Set the data to None self._curExample = -1 self._readings = [] self._drs = None self._drsWidget = None self._error = None self._init_glue() # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_exampleListbox(self._top) self._init_readingListbox(self._top) self._init_canvas(self._top) # Resize callback self._canvas.bind("<Configure>", self._configure) ######################################### ## Initialization Helpers ######################################### def _init_glue(self): tagger = RegexpTagger([ ("^(David|Mary|John)$", "NNP"), ( "^(walks|sees|eats|chases|believes|gives|sleeps|chases|persuades|tries|seems|leaves)$", "VB", ), ("^(go|order|vanish|find|approach)$", "VB"), ("^(a)$", "ex_quant"), ("^(every)$", "univ_quant"), ("^(sandwich|man|dog|pizza|unicorn|cat|senator)$", "NN"), ("^(big|gray|former)$", "JJ"), ("^(him|himself)$", "PRP"), ]) depparser = MaltParser(tagger=tagger) self._glue = DrtGlue(depparser=depparser, remove_duplicates=False) def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget("size")) self._boldfont = Font(family="helvetica", weight="bold", size=self._size.get()) self._font = Font(family="helvetica", size=self._size.get()) if self._size.get() < 0: big = self._size.get() - 2 else: big = self._size.get() + 2 self._bigfont = Font(family="helvetica", weight="bold", size=big) def _init_exampleListbox(self, parent): self._exampleFrame = listframe = Frame(parent) self._exampleFrame.pack(fill="both", side="left", padx=2) self._exampleList_label = Label(self._exampleFrame, font=self._boldfont, text="Examples") self._exampleList_label.pack() self._exampleList = Listbox( self._exampleFrame, selectmode="single", relief="groove", background="white", foreground="#909090", font=self._font, selectforeground="#004040", selectbackground="#c0f0c0", ) self._exampleList.pack(side="right", fill="both", expand=1) for example in self._examples: self._exampleList.insert("end", (" %s" % example)) self._exampleList.config(height=min(len(self._examples), 25), width=40) # Add a scrollbar if there are more than 25 examples. if len(self._examples) > 25: listscroll = Scrollbar(self._exampleFrame, orient="vertical") self._exampleList.config(yscrollcommand=listscroll.set) listscroll.config(command=self._exampleList.yview) listscroll.pack(side="left", fill="y") # If they select a example, apply it. self._exampleList.bind("<<ListboxSelect>>", self._exampleList_select) def _init_readingListbox(self, parent): self._readingFrame = listframe = Frame(parent) self._readingFrame.pack(fill="both", side="left", padx=2) self._readingList_label = Label(self._readingFrame, font=self._boldfont, text="Readings") self._readingList_label.pack() self._readingList = Listbox( self._readingFrame, selectmode="single", relief="groove", background="white", foreground="#909090", font=self._font, selectforeground="#004040", selectbackground="#c0f0c0", ) self._readingList.pack(side="right", fill="both", expand=1) # Add a scrollbar if there are more than 25 examples. listscroll = Scrollbar(self._readingFrame, orient="vertical") self._readingList.config(yscrollcommand=listscroll.set) listscroll.config(command=self._readingList.yview) listscroll.pack(side="right", fill="y") self._populate_readingListbox() def _populate_readingListbox(self): # Populate the listbox with integers self._readingList.delete(0, "end") for i in range(len(self._readings)): self._readingList.insert("end", (" %s" % (i + 1))) self._readingList.config(height=min(len(self._readings), 25), width=5) # If they select a example, apply it. self._readingList.bind("<<ListboxSelect>>", self._readingList_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind("<Control-q>", self.destroy) self._top.bind("<Control-x>", self.destroy) self._top.bind("<Escape>", self.destroy) self._top.bind("n", self.next) self._top.bind("<space>", self.next) self._top.bind("p", self.prev) self._top.bind("<BackSpace>", self.prev) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill="none", side="bottom", padx=3, pady=2) Button( buttonframe, text="Prev", background="#90c0d0", foreground="black", command=self.prev, ).pack(side="left") Button( buttonframe, text="Next", background="#90c0d0", foreground="black", command=self.next, ).pack(side="left") def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas["scrollregion"] = "%d %d %d %d" % (x1, y1, x2, y2) self._redraw() def _init_canvas(self, parent): self._cframe = CanvasFrame( parent, background="white", # width=525, height=250, closeenough=10, border=2, relief="sunken", ) self._cframe.pack(expand=1, fill="both", side="top", pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Exit", underline=1, command=self.destroy, accelerator="q") menubar.add_cascade(label="File", underline=0, menu=filemenu) actionmenu = Menu(menubar, tearoff=0) actionmenu.add_command(label="Next", underline=0, command=self.next, accelerator="n, Space") actionmenu.add_command(label="Previous", underline=0, command=self.prev, accelerator="p, Backspace") menubar.add_cascade(label="Action", underline=0, menu=actionmenu) optionmenu = Menu(menubar, tearoff=0) optionmenu.add_checkbutton( label="Remove Duplicates", underline=0, variable=self._glue.remove_duplicates, command=self._toggle_remove_duplicates, accelerator="r", ) menubar.add_cascade(label="Options", underline=0, menu=optionmenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_radiobutton( label="Tiny", variable=self._size, underline=0, value=10, command=self.resize, ) viewmenu.add_radiobutton( label="Small", variable=self._size, underline=0, value=12, command=self.resize, ) viewmenu.add_radiobutton( label="Medium", variable=self._size, underline=0, value=14, command=self.resize, ) viewmenu.add_radiobutton( label="Large", variable=self._size, underline=0, value=18, command=self.resize, ) viewmenu.add_radiobutton( label="Huge", variable=self._size, underline=0, value=24, command=self.resize, ) menubar.add_cascade(label="View", underline=0, menu=viewmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", underline=0, command=self.about) menubar.add_cascade(label="Help", underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old DRS, widgets, etc. if self._drsWidget is not None: self._drsWidget.clear() if self._drs: self._drsWidget = DrsWidget(self._canvas, self._drs) self._drsWidget.draw() if self._error: self._drsWidget = DrsWidget(self._canvas, self._error) self._drsWidget.draw() ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def prev(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or before) the first item if index <= 0: self._select_previous_example() else: self._readingList_store_selection(index - 1) else: # select its first reading self._readingList_store_selection(readingListSize - 1) else: self._select_previous_example() def _select_previous_example(self): # if the current example is not the first example if self._curExample > 0: self._exampleList_store_selection(self._curExample - 1) else: # go to the last example self._exampleList_store_selection(len(self._examples) - 1) def next(self, *e): selection = self._readingList.curselection() readingListSize = self._readingList.size() # if there are readings if readingListSize > 0: # if one reading is currently selected if len(selection) == 1: index = int(selection[0]) # if it's on (or past) the last item if index >= (readingListSize - 1): self._select_next_example() else: self._readingList_store_selection(index + 1) else: # select its first reading self._readingList_store_selection(0) else: self._select_next_example() def _select_next_example(self): # if the current example is not the last example if self._curExample < len(self._examples) - 1: self._exampleList_store_selection(self._curExample + 1) else: # go to the first example self._exampleList_store_selection(0) def about(self, *e): ABOUT = ( "NLTK Discourse Representation Theory (DRT) Glue Semantics Demo\n" + "Written by Daniel H. Garrette") TITLE = "About: NLTK DRT Glue Demo" try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size + 2))) self._redraw() def _toggle_remove_duplicates(self): self._glue.remove_duplicates = not self._glue.remove_duplicates self._exampleList.selection_clear(0, "end") self._readings = [] self._populate_readingListbox() self._readingCache = [None for ex in self._examples] self._curExample = -1 self._error = None self._drs = None self._redraw() def _exampleList_select(self, event): selection = self._exampleList.curselection() if len(selection) != 1: return self._exampleList_store_selection(int(selection[0])) def _exampleList_store_selection(self, index): self._curExample = index example = self._examples[index] self._exampleList.selection_clear(0, "end") if example: cache = self._readingCache[index] if cache: if isinstance(cache, list): self._readings = cache self._error = None else: self._readings = [] self._error = cache else: try: self._readings = self._glue.parse_to_meaning(example) self._error = None self._readingCache[index] = self._readings except Exception as e: self._readings = [] self._error = DrtVariableExpression( Variable("Error: " + str(e))) self._readingCache[index] = self._error # add a star to the end of the example self._exampleList.delete(index) self._exampleList.insert(index, (" %s *" % example)) self._exampleList.config(height=min( len(self._examples), 25), width=40) self._populate_readingListbox() self._exampleList.selection_set(index) self._drs = None self._redraw() def _readingList_select(self, event): selection = self._readingList.curselection() if len(selection) != 1: return self._readingList_store_selection(int(selection[0])) def _readingList_store_selection(self, index): reading = self._readings[index] self._readingList.selection_clear(0, "end") if reading: self._readingList.selection_set(index) self._drs = reading.simplify().normalize().resolve_anaphora() self._redraw()
class Controller: SNAP_RADIUS = 5 def __init__(self, tk: Tk): tk.title("Layered Polygons") menubar = Menu(tk) menu_file = Menu(menubar, tearoff=0) menu_file.add_command(label="New...", command=self._new_scene) menu_file.add_command(label="Open...", command=self._open_scene) menu_file.add_separator() menu_file.add_command(label="Save", command=self._save_scene) menu_file.add_command(label="Save As...", command=self._save_scene_as) menu_file.add_separator() menu_export = Menu(menu_file, tearoff=0) menu_export.add_command(label="Wavefront (.obj)...", command=self._export_obj) menu_file.add_cascade(label="Export As", menu=menu_export) menu_file.add_separator() menu_file.add_command(label="Quit", command=self._quit_app) menubar.add_cascade(label="File", menu=menu_file) tk.config(menu=menubar) paned = PanedWindow(tk, relief=RAISED) paned.pack(fill=BOTH, expand=1) frame = Frame(paned) paned.add(frame) self._canvas = LayPolyCanvas(frame) bar_x = Scrollbar(frame, orient=HORIZONTAL) bar_x.pack(side=BOTTOM, fill=X) bar_x.config(command=self._canvas.xview) bar_y = Scrollbar(frame, orient=VERTICAL) bar_y.pack(side=RIGHT, fill=Y) bar_y.config(command=self._canvas.yview) self._canvas.config(xscrollcommand=bar_x.set, yscrollcommand=bar_y.set) self._canvas.pack(side=LEFT, expand=True, fill=BOTH) # Thanks to the two guys on Stack Overflow for that! # ( http://stackoverflow.com/a/7734187 ) self._layer_list = Listbox(paned, selectmode=SINGLE) paned.add(self._layer_list) self._scene = None self._current_layer = None self._is_drawing_polygon = False self._tk = tk self._canvas.bind("<Button-1>", self._canvas_left_click) self._canvas.bind("<Button-3>", self._canvas_right_click) self._canvas.bind("<Motion>", self._canvas_mouse_moved) self._layer_list.bind("<<ListboxSelect>>", self._layer_change) self._current_path = None def _canvas_left_click(self, event): if not self._scene or not self._current_layer: return x, y = self._canvas.window_to_canvas_coords(event.x, event.y) if self._is_drawing_polygon: polygon = self._current_layer.get_polygon_at(-1) # Move vtx away from mouse to not interfere with search for closest polygon.get_vertex_at(-1).\ set_coords(x-self.SNAP_RADIUS, y-self.SNAP_RADIUS) closest_vertex = self._current_layer.get_closest_vertex( x, y, self.SNAP_RADIUS) if closest_vertex: polygon.remove_vertex_at(-1) if closest_vertex is polygon.get_vertex_at(0): self._is_drawing_polygon = False else: polygon.add_vertex(closest_vertex) polygon.add_vertex(Vertex(x, y)) else: polygon.get_vertex_at(-1)\ .set_coords(x, y) polygon.add_vertex(Vertex(x, y)) self._canvas.notify_polygon_change(self._current_layer .get_polygon_count()-1) else: # Create start vertex or use already existing one start_vertex = self._current_layer\ .get_closest_vertex(x, y, self.SNAP_RADIUS) if not start_vertex: start_vertex = Vertex(x, y) # Vertex for mouse cursor next_vertex = Vertex(x, y) self._current_layer.add_polygon( Polygon([start_vertex, next_vertex])) self._is_drawing_polygon = True self._canvas.notify_layer_change() def _canvas_right_click(self, event): if not self._current_layer: return if self._is_drawing_polygon: self._current_layer.remove_polygon_at(-1) self._is_drawing_polygon = False else: x, y = self._canvas.window_to_canvas_coords(event.x, event.y) for i in range(0, self._current_layer.get_polygon_count()): if self._current_layer.get_polygon_at(i).contains(x, y): self._current_layer.remove_polygon_at(i) break self._canvas.notify_layer_change() def _canvas_mouse_moved(self, event): if self._is_drawing_polygon: x, y = self._canvas.window_to_canvas_coords(event.x, event.y) self._current_layer.get_polygon_at(-1).get_vertex_at(-1)\ .set_coords(x, y) self._canvas.notify_polygon_change(self._current_layer .get_polygon_count()-1) def _layer_change(self, event): selection = self._layer_list.curselection() if len(selection) > 0 and self._scene: layer = self._scene.get_layer_at(selection[0]) if layer: self._is_drawing_polygon = False self._current_layer = layer self._canvas.notify_new_layer(self._current_layer) def _set_scene(self, scene: Scene) -> bool: if scene.get_layer_count() <= 0: messagebox.showerror("Error!", "Scene has no layers!") return False self._scene = scene # Prepare canvas # TODO Extra 10px padding for canvas width, height = self._scene.get_size() self._canvas.config(scrollregion=(0, 0, width, height)) # Empty listbox, fill it, select first entry self._layer_list.delete(0, self._layer_list.size()-1) for i in range(0, self._scene.get_layer_count()): self._layer_list.insert(i, self._scene.get_layer_at(i).get_name()) self._layer_list.selection_set(0) self._layer_list.event_generate("<<ListboxSelect>>") return True def _set_current_path(self, path): self._current_path = path if path: self._tk.title(path + " - Layered Polygons") else: self._tk.title("Untitled - Layered Polygons") def _new_scene(self): path = filedialog.askopenfilename(defaultextension=".ora", filetypes=[("OpenRaster files", ".ora")]) if not path: return scene = ora.read(path) if not scene: messagebox.showerror("Error!", "File could not be opened!") return if self._set_scene(scene): self._set_current_path(None) def _open_scene(self): path = filedialog.askopenfilename(defaultextension=".lp", filetypes=[("Layered polygons" " files", ".lp")]) if not path: return scene = lp.read(path) if not scene: messagebox.showerror("Error!", "File could not be opened!") return if self._set_scene(scene): self._set_current_path(path) def _save_scene_help(self, path): if lp.save(path, self._scene): self._set_current_path(path) else: messagebox.showerror("Error!", "File could not be saved!") def _save_scene(self): if not self._current_path: self._save_scene_as() return self._save_scene_help(self._current_path) def _save_scene_as(self): if not self._scene: return path = filedialog.asksaveasfilename(defaultextension=".lp", filetypes=[("Layered polygons" " files", ".lp")]) if path: self._save_scene_help(path) def _export_obj(self): if not self._scene: return path_obj = filedialog.asksaveasfilename(defaultextension=".obj", filetypes=[("Wavefront object" " files", ".obj")]) if not path_obj: return path_obj, path_mtl, path_data = obj.get_paths(path_obj) obj.save(path_obj, path_mtl, path_data, self._scene) def _quit_app(self): self._tk.quit() exit()
class ImporterGUI: """ This class is the main gui and shows the import window, it also contains the main methods which uses other helper classes Attributes: root = the root tk previewFrame = the frame that shows the preview of the dataframe XMLList = the 2D list which holds the xml filepath on the index 0 and the xsl filepath on index 1 """ def __init__(self, root: Tk): self.root = root self.previewFrame = Frame(root) self.pt = Table(self.previewFrame) self.dialect = detector.Dialect() self.XMLList = [] self.DialectList = [] self.hasHeaderVar = BooleanVar() self.currentPath = "" h1 = Label(self.root, text="Imported Files", bg="#eee") h1.pack(padx=5, pady=5, fill="x") # Dialog Frame dialogFrame = Frame(self.root) dialogFrame.grid_columnconfigure(1, weight=1) Button(dialogFrame, text="Import Files", command=self.openFileDialog, width=20).grid(row=0, column=0) Button(dialogFrame, text="Delete selected File", command=self.deleteSelectedFile, width=20).grid(row=1, column=0) Button(dialogFrame, text="Delete all", command=self.deleteAllFiles, width=20).grid(row=2, column=0) # the outside frame for the files listbox (it holds the listbox and the scrollbar) listbox_border = Frame(dialogFrame, bd=2, relief="sunken", background="white") listbox_border.grid(row=0, column=1, rowspan=3, padx=3, sticky="nsew") # the actual listbox self.importedFiles = Listbox(listbox_border, selectmode=SINGLE, height=4, borderwidth=0, highlightthickness=0, relief=SUNKEN, background="white") self.importedFiles.bind("<<ListboxSelect>>", self.selectionChanged) # the scrollbar inside the listbox_border frame vsb = Scrollbar(listbox_border, orient="vertical", command=self.importedFiles.yview) self.importedFiles.configure(yscrollcommand=vsb) vsb.pack(side="right", fill="y") self.importedFiles.pack(padx=2, pady=2, fill="both", expand=True) dialogFrame.pack(fill="x", padx=10) # XSL File Frame (its disabled when a csv file is selected in the listbox, # and set to "normal" when a xml is selected h1 = Label(root, text="XSL File", bg="#eee") h1.pack(padx=5, pady=5, fill="x") xslFrame = Frame(root) self.importXSL_btn = Button(xslFrame, state=DISABLED, text="Import XSL File", command=self.openXSLFileDialog, width=20) self.importXSL_btn.grid(row=0, column=0) self.XSLPath_text = Text(xslFrame, height=1, borderwidth=2, relief=SUNKEN) self.XSLPath_text.grid(row=0, column=1) xslFrame.pack(fill="x", padx=10, pady=5) # Detector Frame h1 = Label(root, text="Detector", bg="#eee") h1.pack(padx=5, pady=5, fill="x") detectorFrame = Frame(root) Label(detectorFrame, text="Encoding:", width=20, anchor="w", justify="left").grid(row=0) self.encodingText = Text(detectorFrame, height=1, borderwidth=2, relief=SUNKEN, width=10) self.encodingText.grid(row=0, column=1) Label(detectorFrame, text="Has Header:", width=20, anchor="w", justify="left").grid(row=1) self.hasHeaderCheckbutton = Checkbutton(detectorFrame, var=self.hasHeaderVar, onvalue=1, offvalue=0) self.hasHeaderCheckbutton.grid(sticky="W", row=1, column=1) Label(detectorFrame, text="Seperator:", width=20, anchor="w", justify="left").grid(row=2) self.seperatorText = Text(detectorFrame, height=1, borderwidth=2, relief=SUNKEN, width=10) self.seperatorText.grid(row=2, column=1) Label(detectorFrame, text="Quote Char:", width=20, anchor="w", justify="left").grid(row=3) self.quoteCharText = Text(detectorFrame, height=1, borderwidth=2, relief=SUNKEN, width=10) self.quoteCharText.grid(row=3, column=1) Button(detectorFrame, text="Save Dialect Changes", command=self.saveDialectChanges, width=20).grid(row=4, column=0) detectorFrame.pack(fill="x", padx=10, pady=5) # dataframe preview frame preview = Label(root, text="Preview", bg="#eee") preview.pack(expand=TRUE, fill="x", padx=5, side=TOP) self.pt.show() self.previewFrame.pack(pady=10, padx=10, fill="both", side=TOP) # the bottom most centered export button which leads to the export window exportBtn = Button(root, text="Export", command=self.export, width=20, padx=0) exportBtn.pack(fill="x", padx=10, pady=10) def saveDialectChanges(self): """ saves the Dialect changes made by the user """ dialect = detector.Dialect() dialect.encoding = self.encodingText.get(1.0, 'end-1c') dialect.hasHeader = self.hasHeaderVar.get() dialect.delimiter = self.seperatorText.get(1.0, 'end-1c') dialect.quoteChar = self.quoteCharText.get(1.0, 'end-1c') if not self.currentPath: files = self.getImportedFiles() self.currentPath = files[0] path = self.currentPath print(path) if not any(path in x for x in self.DialectList): self.DialectList.append([path, dialect]) elif any(path in x for x in self.DialectList): x = [x for x in self.DialectList if path in x][0] self.DialectList[self.DialectList.index(x)][1] = dialect self.updateDf(self.getImportedFiles()) def selectionChanged(self, event): """ this is an event which is triggered by selection changed inside the listbox widget it checks if the selected file is a xml, if so it sets the textbox intractable for the user :param event: the event which called it """ selection = event.widget.curselection() if selection: data = event.widget.get(selection[0]) self.currentPath = data if data.endswith(".xml"): # disable encoding changes self.encodingText.delete(1.0, END) self.hasHeaderVar.set(False) self.seperatorText.delete(1.0, END) self.quoteCharText.delete(1.0, END) self.encodingText["state"] = "disabled" self.hasHeaderCheckbutton["state"] = "disabled" self.seperatorText["state"] = "disabled" self.quoteCharText["state"] = "disabled" self.importXSL_btn["state"] = "normal" if any(data in x for x in self.XMLList): x = [x for x in self.XMLList if data in x][0] self.XSLPath_text.delete(1.0, END) self.XSLPath_text.insert( 1.0, self.XMLList[self.XMLList.index(x)][1]) else: self.XSLPath_text.delete(1.0, END) self.XSLPath_text.insert(1.0, "please import a XSL File!") else: self.encodingText.delete(1.0, END) self.hasHeaderVar.set(False) self.seperatorText.delete(1.0, END) self.quoteCharText.delete(1.0, END) self.encodingText["state"] = "normal" self.hasHeaderCheckbutton["state"] = "normal" self.seperatorText["state"] = "normal" self.quoteCharText["state"] = "normal" self.importXSL_btn["state"] = "disabled" self.XSLPath_text.delete(1.0, END) if any(data in x for x in self.DialectList): x = [x for x in self.DialectList if data in x][0] dialect = self.DialectList[self.DialectList.index(x)][1] self.updateDialect(dialect) def openXSLFileDialog(self): """ this function is called if the user wants to import a xsl file in the xsl file frame it opens the filedialog and appends the xsl to the according xml into the XMLList attribute after that, it try's to update the dataframe and its preview by calling the update function """ file = askopenfilename(parent=self.root, title='Choose a file', filetypes=[("Extensible Stylesheet Language", "*.xsl"), ("All files", "*.*")]) self.XMLList.append( [self.importedFiles.get(self.importedFiles.curselection()), file]) self.XSLPath_text.delete(1.0, END) self.XSLPath_text.insert(1.0, file) self.updateDf(self.getImportedFiles()) def openFileDialog(self): """ this function opens the file dialog and imports the selected filepaths into the listbox and also calls the update function to redraw the new dataframe """ files = list( askopenfilenames(parent=self.root, title='Choose a file', filetypes=[("Excel files", ".xml .csv")])) self.updateSelectedFiles(files) self.updateDf(self.getImportedFiles()) def deleteSelectedFile(self): """ deletes the selected file from the listbox and redraws the dataframe since one of its source is deleted also if a xml file is deleted, it also deletes the corresponding xsl file from the XMLList """ path = self.importedFiles.get(self.importedFiles.curselection()) if path is self.currentPath: self.currentPath = "" # delete from dialect list if any(path in x for x in self.DialectList): x = [x for x in self.DialectList if path in x][0] self.DialectList.pop(self.DialectList.index(x)) index = self.importedFiles.get(0, END).index(path) self.importedFiles.delete(index) # delete from xml list if path.endswith(".xml"): x = [x for x in self.XMLList if path in x][0] self.XMLList.pop(self.XMLList.index(x)) self.updateDf(self.getImportedFiles()) def deleteAllFiles(self): """ deletes all imported filepaths from the listbox and also from the dataframe """ self.importedFiles.delete(0, END) self.currentPath = "" self.XMLList = [] self.DialectList = [] def getImportedFiles(self): """ :return: returns the selected filepath from the listbox """ return self.importedFiles.get(0, END) def updateSelectedFiles(self, files): """ after opening a file dialog, this method is called to pass the new imported filepaths into the listbox :param files: filespaths from the filedialog """ startIndex = self.importedFiles.size() for index, file in enumerate(files): self.importedFiles.insert(index + startIndex, file) def export(self): """ opens the export window and passes the dataframe from the preview frame """ importer.setDataFrame(self.pt.model.df) ExporterGUI(self.root, importer, self.dialect) def updateDf(self, files: list): """ checks if the dataframe can be updated by the newly imported filepaths calls the merge function if there is more than 1 file inside the filelist also udpates the detector frame (displaying dialect data) :param files: the whole filepath list """ if len(files) > 1 or len(self.XMLList) > 0: canMerge = merger.prepareMerge(files, self.XMLList, self.DialectList) self.DialectList = merger.dialectList if canMerge: newDataFrame = merger.mergeFiles() importer.setDataFrame(newDataFrame) self.pt.updateModel(TableModel(newDataFrame)) self.pt.redraw() elif len(files) > 0 and files[0].endswith(".csv"): if not any(files[0] in x for x in self.DialectList): self.dialect.guessDialectCSV(files[0]) self.DialectList.append([files[0], self.dialect]) else: x = [x for x in self.DialectList if files[0] in x][0] self.dialect = self.DialectList[self.DialectList.index(x)][1] importer.importCSV(files[0], self.dialect) updatedDataframe = importer.getDataFrame() self.pt.updateModel(TableModel(updatedDataframe)) self.pt.redraw() self.updateDialect(self.dialect) def updateDialect(self, dialect: detector.Dialect): """ updates the dialect text fields from the gui :param dialect: the new changed dialect """ # updates the dialect data self.encodingText.delete(1.0, END) self.encodingText.insert(1.0, dialect.encoding) self.hasHeaderVar.set(dialect.hasHeader) self.seperatorText.delete(1.0, END) self.seperatorText.insert(1.0, dialect.delimiter) self.quoteCharText.delete(1.0, END) self.quoteCharText.insert(1.0, dialect.quoteChar)
class PypeTkPad(object): def __init__(self, master, queue, pypeOutput): self.queue = queue self.pypeOutput = pypeOutput self.master = master self.master.title('PypePad') self.master.geometry("%dx%d%+d%+d" % (700, 500, 0, 0)) self.master.minsize(300, 100) self.output_file_name = None self.BuildMainFrame() self.UpdateOutput() def NewCommand(self): self.ClearAllCommand() def OpenCommand(self): import tkinter.filedialog from tkinter import END openfile = tkinter.filedialog.askopenfile() if not openfile: return for line in openfile.readlines(): self.text_input.insert(END,line) def SaveCommand(self): import tkinter.filedialog from tkinter import END saveasfile = tkinter.filedialog.asksaveasfile() if not saveasfile: return alltext = self.text_input.get("1.0",END) saveasfile.write(alltext) def QuitCommand(self): self.master.quit() def ClearInputCommand(self): from tkinter import END self.text_input.delete("1.0",END) def ClearOutputCommand(self): from tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.delete("1.0",END) self.text_output["state"] = DISABLED self.text_output.see(END) self.text_output.update() def ClearAllCommand(self): self.ClearInputCommand() self.ClearOutputCommand() def OutputFileCommand(self): import tkinter.filedialog outputfilename = tkinter.filedialog.asksaveasfilename() if sys.platform == 'win32' and len(outputfilename.split()) > 1: outputfilename = '"%s"' % outputfilename self.output_file_name = outputfilename def AboutCommand(self): self.OutputText('\n') self.OutputText('* PypePad, Copyright (c) Luca Antiga, David Steinman. *\n') self.OutputText('\n') def UpdateOutput(self): if self.pypeOutput: text = self.pypeOutput.pop(0) self.output_stream.write(text) self.master.after(10,self.UpdateOutput) def RunPype(self,arguments): if not arguments: return if self.output_to_file.get() is not 'n' and self.output_file_name: self.output_stream.output_to_file = True self.output_stream.output_file = open(self.output_file_name,self.output_to_file.get()) else: self.output_stream.output_to_file = False self.queue.append(arguments) def GetWordUnderCursor(self): from tkinter import CURRENT splitindex = self.text_input.index(CURRENT).split('.') line = self.text_input.get(splitindex[0]+".0",splitindex[0]+".end") wordstart = line.rfind(' ',0,int(splitindex[1])-1)+1 wordend = line.find(' ',int(splitindex[1])) if wordend == -1: wordend = len(line) word = line[wordstart:wordend] return word def GetWordIndex(self): startindex = self.text_input.index("insert-1c wordstart") endindex = self.text_input.index("insert-1c wordend") if self.text_input.get(startindex+'-1c') == '-' and self.text_input.get(startindex+'-2c') == '-': startindex = self.text_input.index("insert-1c wordstart -2c") elif self.text_input.get(startindex+'-1c') == '-' and self.text_input.get(startindex+'-2c') == ' ': startindex = self.text_input.index("insert-1c wordstart -1c") self.wordIndex[0] = startindex self.wordIndex[1] = endindex word = self.text_input.get(self.wordIndex[0],self.wordIndex[1]) return word def GetLogicalLine(self,physicallineid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallineid]] def GetLogicalLineRange(self,physicallinefirstid,physicallinelastid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallinefirstid]:indexes[physicallinelastid]+1] def GetAllLogicalLines(self): return self.GetLogicalLines()[1] def GetLogicalLines(self): from tkinter import END # Python 2 hack to remove the u'...' prefix from unicode literal strings. does not change py3 behavior physicallines = [str(line) for line in self.text_input.get("1.0",END).split('\n')] lines = [] indexes = [0] * len(physicallines) lineid = 0 previousline = "" join = 0 for line in physicallines: if line.startswith('#'): if join: indexes[lineid] = indexes[lineid-1] elif join: if line.endswith('\\'): lines[-1] = lines[-1] + " " + line[:-1] join = 1 else: lines[-1] = lines[-1] + " " + line join = 0 indexes[lineid] = indexes[lineid-1] else: if line.endswith('\\'): join = 1 lines.append(line[:-1]) else: lines.append(line) join = 0 if lineid > 0: indexes[lineid] = indexes[lineid-1]+1 lineid += 1 return indexes, lines def GetLineUnderCursor(self): from tkinter import INSERT currentlineid = int(self.text_input.index(INSERT).split('.')[0]) - 1 return self.GetLogicalLine(currentlineid) def RunAllCommand(self): lines = self.GetAllLogicalLines() for line in lines: if line and line.strip(): self.RunPype(line) def RunLineCommand(self): line = self.GetLineUnderCursor() if line and line.strip(): self.RunPype(line) def RunSelectionCommand(self): from tkinter import TclError, SEL_FIRST, SEL_LAST try: firstlineid = int(self.text_input.index(SEL_FIRST).split('.')[0]) - 1 lastlineid = int(self.text_input.index(SEL_LAST).split('.')[0]) - 1 lines = self.GetLogicalLineRange(firstlineid,lastlineid) for line in lines: self.RunPype(line) except TclError: pass def GetSuggestionsList(self,word): list = [] try: from vmtk import vmtkscripts from vmtk import pypes except ImportError: return None if word.startswith('--'): list = ['--pipe','--help'] elif word.startswith('-'): optionlist = [] scriptindex = self.text_input.search('vmtk',self.wordIndex[0],backwards=1) moduleName = self.text_input.get( scriptindex,scriptindex+' wordend' ) try: module = importlib.import_module('vmtk.'+moduleName) # Find the principle class to instantiate the requested action defined inside the requested writerModule script. # Returns a single member list (containing the principle class name) which satisfies the following criteria: # 1) is a class defined within the script # 2) the class is a subclass of pypes.pypescript scriptObjectClasses = [x for x in dir(module) if isclass(getattr(module, x)) and issubclass(getattr(module, x), pypes.pypeScript)] scriptObjectClassName = scriptObjectClasses[0] scriptObject = getattr(module, scriptObjectClassName) scriptObject = scriptObject() members = scriptObject.InputMembers + scriptObject.OutputMembers for member in members: optionlist.append('-'+member.OptionName) list = [option for option in optionlist if option.count(word)] except: return list else: list = [scriptname for scriptname in vmtkscripts.__all__ if scriptname.count(word)] for index, item in enumerate(list): # check if scriptname contains starting prefix 'vmtk.' and remove it before returning list to the user. if 'vmtk.' == item[0:5]: splitList = item.split('.') list[index] = splitList[1] else: continue return list def FillSuggestionsList(self,word): from tkinter import END self.suggestionslist.delete(0,END) suggestions = self.GetSuggestionsList(word) for suggestion in suggestions: self.suggestionslist.insert(END,suggestion) def ReplaceTextCommand(self,word): self.text_input.delete(self.wordIndex[0],self.wordIndex[1]) self.text_input.insert(self.wordIndex[0],word) self.text_input.focus_set() def ShowHelpCommand(self): word = self.GetWordUnderCursor() self.OutputText(word) if word: self.RunPype(word+' --help') else: self.OutputText('Enter your vmtk Pype above and Run.\n') def AutoCompleteCommand(self): word = self.GetWordIndex() self.suggestionswindow.withdraw() if word: self.FillSuggestionsList(word) self.suggestionswindow.geometry("%dx%d%+d%+d" % (400, 150, self.text_output.winfo_rootx(),self.text_output.winfo_rooty())) self.suggestionswindow.deiconify() self.suggestionswindow.lift() def InsertScriptName(self,scriptname): from tkinter import INSERT self.text_input.insert(INSERT,scriptname+' ') def InsertFileName(self): from tkinter import INSERT import tkinter.filedialog openfilename = tkinter.filedialog.askopenfilename() if not openfilename: return if len(openfilename.split()) > 1: openfilename = '"%s"' % openfilename self.text_input.insert(INSERT,openfilename+' ') def KeyPressHandler(self,event): if event.keysym == "Tab" : self.AutoCompleteCommand() self.suggestionslist.focus_set() self.suggestionslist.selection_set(0) return "break" else: self.text_input.focus_set() def TopKeyPressHandler(self,event): from tkinter import ACTIVE, INSERT if event.keysym in ['Down','Up'] : self.suggestionslist.focus_set() elif event.keysym == "Return": word = self.suggestionslist.get(ACTIVE) self.ReplaceTextCommand(word) self.suggestionswindow.withdraw() self.text_input.focus_set() elif len(event.keysym) == 1 : self.suggestionswindow.withdraw() self.text_input.insert(INSERT,event.keysym) self.text_input.focus_set() else : self.suggestionswindow.withdraw() self.text_input.focus_set() def NewHandler(self,event): self.NewCommand() def OpenHandler(self,event): self.OpenCommand() def SaveHandler(self,event): self.SaveCommand() def InsertFileNameHandler(self,event): self.InsertFileName() return "break" def QuitHandler(self,event): self.QuitCommand() def ShowHelpHandler(self,event): self.ShowHelpCommand() def RunKeyboardHandler(self,event): from tkinter import SEL_FIRST, TclError try: self.text_input.index(SEL_FIRST) self.RunSelectionCommand() except TclError: self.RunLineCommand() return "break" def RunAllHandler(self,event): self.RunAllCommand() def PopupHandler(self,event): try: self.popupmenu.tk_popup(event.x_root, event.y_root, 0) finally: self.popupmenu.grab_release() def OutputText(self,text): from tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.insert(END,text) self.text_output["state"] = DISABLED def BuildScriptMenu(self,parentmenu,modulename): from tkinter import Menu menu = Menu(parentmenu,bd=1,activeborderwidth=0) try: module = importlib.import_module('vmtk.'+modulename) except ImportError: return None scriptnames = [scriptname for scriptname in getattr(module, '__all__')] for index, scriptname in enumerate(scriptnames): # check if scriptname contains starting prefix 'vmtk.' and remove it before returning list to the user. if 'vmtk.' == scriptname[0:5]: splitList = scriptname.split('.') scriptnames[index] = splitList[1] else: continue menulength = 20 for i in range(len(scriptnames)//menulength+1): subscriptnames = scriptnames[i*menulength:(i+1)*menulength] if not subscriptnames: break submenu = Menu(menu,bd=1,activeborderwidth=0) menu.add_cascade(label=subscriptnames[0]+"...",menu=submenu) for scriptname in subscriptnames: callback = CallbackShim(self.InsertScriptName,scriptname) submenu.add_command(label=scriptname,command=callback) return menu def BuildMainFrame(self): from tkinter import Menu, IntVar, StringVar, Toplevel, Listbox, Frame, PanedWindow, Text, Scrollbar, Entry from tkinter import X, N, S, W, E, VERTICAL, TOP, END, DISABLED, RAISED menu = Menu(self.master,activeborderwidth=0,bd=0) self.master.config(menu=menu) filemenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="File", underline=0, menu=filemenu) filemenu.add_command(label="New", accelerator='Ctrl+N',command=self.NewCommand) filemenu.add_command(label="Open...",accelerator='Ctrl+O', command=self.OpenCommand) filemenu.add_command(label="Save as...",accelerator='Ctrl+S', command=self.SaveCommand) filemenu.add_separator() filemenu.add_command(label="Quit",accelerator='Ctrl+Q', command=self.QuitCommand) self.log_on = IntVar() self.log_on.set(1) self.output_to_file = StringVar() self.output_to_file.set('n') scriptmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) modulenames = ['vmtkscripts'] for modulename in modulenames: scriptsubmenu = self.BuildScriptMenu(menu,modulename) if scriptsubmenu: scriptmenu.add_cascade(label=modulename,menu=scriptsubmenu) editmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Edit",underline=0, menu=editmenu) editmenu.add_cascade(label="Insert script",menu=scriptmenu) editmenu.add_command(label="Insert file name", accelerator='Ctrl+F',command=self.InsertFileName) editmenu.add_separator() editmenu.add_command(label="Clear input", command=self.ClearInputCommand) editmenu.add_command(label="Clear output", command=self.ClearOutputCommand) editmenu.add_command(label="Clear all", command=self.ClearAllCommand) editmenu.add_separator() editmenu.add_checkbutton(label="Log", variable=self.log_on) editmenu.add_separator() editmenu.add_radiobutton(label="No output to file", variable=self.output_to_file,value='n') editmenu.add_radiobutton(label="Write output to file", variable=self.output_to_file,value='w') editmenu.add_radiobutton(label="Append output to file", variable=self.output_to_file,value='a') editmenu.add_command(label="Output file...", command=self.OutputFileCommand) runmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Run", underline=0, menu=runmenu) runmenu.add_command(label="Run all", command=self.RunAllCommand) runmenu.add_command(label="Run current line", command=self.RunLineCommand) runmenu.add_command(label="Run selection", command=self.RunSelectionCommand) helpmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Help", underline=0, menu=helpmenu) helpmenu.add_command(label="Help", underline=0, accelerator='F1',command=self.ShowHelpCommand) helpmenu.add_command(label="About", underline=0, command=self.AboutCommand) self.master.bind("<Control-KeyPress-q>", self.QuitHandler) self.master.bind("<Control-KeyPress-n>", self.NewHandler) self.master.bind("<Control-KeyPress-o>", self.OpenHandler) self.master.bind("<Control-KeyPress-s>", self.SaveHandler) self.master.bind("<Control-KeyPress-f>", self.InsertFileNameHandler) self.master.bind("<KeyPress-F1>", self.ShowHelpHandler) self.master.bind("<KeyPress>", self.KeyPressHandler) self.wordIndex = ['1.0','1.0'] self.suggestionswindow = Toplevel(bg='#ffffff',bd=0,height=50,width=600,highlightthickness=0,takefocus=True) self.suggestionswindow.overrideredirect(1) self.suggestionslist = Listbox(self.suggestionswindow,bg='#ffffff',bd=1,fg='#336699',activestyle='none',highlightthickness=0,height=9) self.suggestionslist.insert(END,"foo") self.suggestionslist.pack(side=TOP,fill=X) self.suggestionswindow.bind("<KeyPress>", self.TopKeyPressHandler) self.suggestionswindow.withdraw() self.master.rowconfigure(0,weight=1) self.master.columnconfigure(0,weight=1) content = Frame(self.master,bd=0,padx=2,pady=2) content.grid(row=0,column=0,sticky=N+S+W+E) content.rowconfigure(0,weight=1,minsize=50) content.rowconfigure(1,weight=0) content.columnconfigure(0,weight=1) panes = PanedWindow(content,orient=VERTICAL,bd=1,sashwidth=8,sashpad=0,sashrelief=RAISED,showhandle=True) panes.grid(row=0,column=0,sticky=N+S+W+E) frame1 = Frame(panes,bd=0) frame1.grid(row=0,column=0,sticky=N+S+W+E) frame1.columnconfigure(0,weight=1) frame1.columnconfigure(1,weight=0) frame1.rowconfigure(0,weight=1) panes.add(frame1,height=300,minsize=20) frame2 = Frame(panes,bd=0) frame2.grid(row=1,column=0,sticky=N+S+W+E) frame2.columnconfigure(0,weight=1) frame2.columnconfigure(1,weight=0) frame2.rowconfigure(0,weight=1) panes.add(frame2,minsize=20) self.text_input = Text(frame1, bg='#ffffff',bd=1,highlightthickness=0) self.text_input.bind("<KeyPress>", self.KeyPressHandler) self.text_input.bind("<Button-3>", self.PopupHandler) self.text_input.bind("<Control-Return>", self.RunKeyboardHandler) self.input_scrollbar = Scrollbar(frame1,orient=VERTICAL,command=self.text_input.yview) self.text_input["yscrollcommand"] = self.input_scrollbar.set self.text_output = Text(frame2,state=DISABLED,bd=1,bg='#ffffff',highlightthickness=0) self.output_scrollbar = Scrollbar(frame2,orient=VERTICAL,command=self.text_output.yview) self.text_output["yscrollcommand"] = self.output_scrollbar.set self.text_entry = Entry(content,bd=1,bg='#ffffff',state=DISABLED,highlightthickness=0) self.text_input.focus_set() self.text_input.grid(row=0,column=0,sticky=N+S+W+E) self.input_scrollbar.grid(row=0,column=1,sticky=N+S+W+E) self.text_output.grid(row=0,column=0,sticky=N+S+W+E) self.output_scrollbar.grid(row=0,column=1,sticky=N+S+W+E) self.text_entry.grid(row=1,column=0,sticky=N+S+W+E) self.popupmenu = Menu(self.text_input, tearoff=1, bd=0) self.popupmenu.add_command(label="Context help", command=self.ShowHelpCommand) self.popupmenu.add_cascade(label="Insert script",menu=scriptmenu) self.popupmenu.add_command(label="Insert file name...", command=self.InsertFileName) self.popupmenu.add_separator() self.popupmenu.add_command(label="Run all", command=self.RunAllCommand) self.popupmenu.add_command(label="Run current line", command=self.RunLineCommand) self.popupmenu.add_command(label="Run selection", command=self.RunSelectionCommand) self.output_stream = TkPadOutputStream(self.text_output) self.input_stream = TkPadInputStream(self.text_entry,self.output_stream)
class PypeTkPad(object): def __init__(self, master, queue, pypeOutput): self.queue = queue self.pypeOutput = pypeOutput self.master = master self.master.title('PypePad') self.master.geometry("%dx%d%+d%+d" % (700, 500, 0, 0)) self.master.minsize(300, 100) self.output_file_name = None self.BuildMainFrame() self.UpdateOutput() def NewCommand(self): self.ClearAllCommand() def OpenCommand(self): import tkinter.filedialog from tkinter import END openfile = tkinter.filedialog.askopenfile() if not openfile: return for line in openfile.readlines(): self.text_input.insert(END, line) def SaveCommand(self): import tkinter.filedialog from tkinter import END saveasfile = tkinter.filedialog.asksaveasfile() if not saveasfile: return alltext = self.text_input.get("1.0", END) saveasfile.write(alltext) def QuitCommand(self): self.master.quit() def ClearInputCommand(self): from tkinter import END self.text_input.delete("1.0", END) def ClearOutputCommand(self): from tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.delete("1.0", END) self.text_output["state"] = DISABLED self.text_output.see(END) self.text_output.update() def ClearAllCommand(self): self.ClearInputCommand() self.ClearOutputCommand() def OutputFileCommand(self): import tkinter.filedialog outputfilename = tkinter.filedialog.asksaveasfilename() if sys.platform == 'win32' and len(outputfilename.split()) > 1: outputfilename = '"%s"' % outputfilename self.output_file_name = outputfilename def AboutCommand(self): self.OutputText('\n') self.OutputText( '* PypePad, Copyright (c) Luca Antiga, David Steinman. *\n') self.OutputText('\n') def UpdateOutput(self): if self.pypeOutput: text = self.pypeOutput.pop(0) self.output_stream.write(text) self.master.after(10, self.UpdateOutput) def RunPype(self, arguments): if not arguments: return if self.output_to_file.get() is not 'n' and self.output_file_name: self.output_stream.output_to_file = True self.output_stream.output_file = open(self.output_file_name, self.output_to_file.get()) else: self.output_stream.output_to_file = False self.queue.append(arguments) def GetWordUnderCursor(self): from tkinter import CURRENT splitindex = self.text_input.index(CURRENT).split('.') line = self.text_input.get(splitindex[0] + ".0", splitindex[0] + ".end") wordstart = line.rfind(' ', 0, int(splitindex[1]) - 1) + 1 wordend = line.find(' ', int(splitindex[1])) if wordend == -1: wordend = len(line) word = line[wordstart:wordend] return word def GetWordIndex(self): startindex = self.text_input.index("insert-1c wordstart") endindex = self.text_input.index("insert-1c wordend") if self.text_input.get(startindex + '-1c') == '-' and self.text_input.get( startindex + '-2c') == '-': startindex = self.text_input.index("insert-1c wordstart -2c") elif self.text_input.get(startindex + '-1c') == '-' and self.text_input.get( startindex + '-2c') == ' ': startindex = self.text_input.index("insert-1c wordstart -1c") self.wordIndex[0] = startindex self.wordIndex[1] = endindex word = self.text_input.get(self.wordIndex[0], self.wordIndex[1]) return word def GetLogicalLine(self, physicallineid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallineid]] def GetLogicalLineRange(self, physicallinefirstid, physicallinelastid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallinefirstid]:indexes[physicallinelastid] + 1] def GetAllLogicalLines(self): return self.GetLogicalLines()[1] def GetLogicalLines(self): from tkinter import END # Python 2 hack to remove the u'...' prefix from unicode literal strings. does not change py3 behavior physicallines = [ str(line) for line in self.text_input.get("1.0", END).split('\n') ] lines = [] indexes = [0] * len(physicallines) lineid = 0 previousline = "" join = 0 for line in physicallines: if line.startswith('#'): if join: indexes[lineid] = indexes[lineid - 1] elif join: if line.endswith('\\'): lines[-1] = lines[-1] + " " + line[:-1] join = 1 else: lines[-1] = lines[-1] + " " + line join = 0 indexes[lineid] = indexes[lineid - 1] else: if line.endswith('\\'): join = 1 lines.append(line[:-1]) else: lines.append(line) join = 0 if lineid > 0: indexes[lineid] = indexes[lineid - 1] + 1 lineid += 1 return indexes, lines def GetLineUnderCursor(self): from tkinter import INSERT currentlineid = int(self.text_input.index(INSERT).split('.')[0]) - 1 return self.GetLogicalLine(currentlineid) def RunAllCommand(self): lines = self.GetAllLogicalLines() for line in lines: if line and line.strip(): self.RunPype(line) def RunLineCommand(self): line = self.GetLineUnderCursor() if line and line.strip(): self.RunPype(line) def RunSelectionCommand(self): from tkinter import TclError, SEL_FIRST, SEL_LAST try: firstlineid = int( self.text_input.index(SEL_FIRST).split('.')[0]) - 1 lastlineid = int(self.text_input.index(SEL_LAST).split('.')[0]) - 1 lines = self.GetLogicalLineRange(firstlineid, lastlineid) for line in lines: self.RunPype(line) except TclError: pass def GetSuggestionsList(self, word): list = [] try: from vmtk import vmtkscripts from vmtk import pypes except ImportError: return None if word.startswith('--'): list = ['--pipe', '--help'] elif word.startswith('-'): optionlist = [] scriptindex = self.text_input.search('vmtk', self.wordIndex[0], backwards=1) moduleName = self.text_input.get(scriptindex, scriptindex + ' wordend') try: module = importlib.import_module('vmtk.' + moduleName) # Find the principle class to instantiate the requested action defined inside the requested writerModule script. # Returns a single member list (containing the principle class name) which satisfies the following criteria: # 1) is a class defined within the script # 2) the class is a subclass of pypes.pypescript scriptObjectClasses = [ x for x in dir(module) if isclass(getattr(module, x)) and issubclass(getattr(module, x), pypes.pypeScript) ] scriptObjectClassName = scriptObjectClasses[0] scriptObject = getattr(module, scriptObjectClassName) scriptObject = scriptObject() members = scriptObject.InputMembers + scriptObject.OutputMembers for member in members: optionlist.append('-' + member.OptionName) list = [option for option in optionlist if option.count(word)] except: return list else: list = [ scriptname for scriptname in vmtkscripts.__all__ if scriptname.count(word) ] for index, item in enumerate(list): # check if scriptname contains starting prefix 'vmtk.' and remove it before returning list to the user. if 'vmtk.' == item[0:5]: splitList = item.split('.') list[index] = splitList[1] else: continue return list def FillSuggestionsList(self, word): from tkinter import END self.suggestionslist.delete(0, END) suggestions = self.GetSuggestionsList(word) for suggestion in suggestions: self.suggestionslist.insert(END, suggestion) def ReplaceTextCommand(self, word): self.text_input.delete(self.wordIndex[0], self.wordIndex[1]) self.text_input.insert(self.wordIndex[0], word) self.text_input.focus_set() def ShowHelpCommand(self): word = self.GetWordUnderCursor() self.OutputText(word) if word: self.RunPype(word + ' --help') else: self.OutputText('Enter your vmtk Pype above and Run.\n') def AutoCompleteCommand(self): word = self.GetWordIndex() self.suggestionswindow.withdraw() if word: self.FillSuggestionsList(word) self.suggestionswindow.geometry( "%dx%d%+d%+d" % (400, 150, self.text_output.winfo_rootx(), self.text_output.winfo_rooty())) self.suggestionswindow.deiconify() self.suggestionswindow.lift() def InsertScriptName(self, scriptname): from tkinter import INSERT self.text_input.insert(INSERT, scriptname + ' ') def InsertFileName(self): from tkinter import INSERT import tkinter.filedialog openfilename = tkinter.filedialog.askopenfilename() if not openfilename: return if len(openfilename.split()) > 1: openfilename = '"%s"' % openfilename self.text_input.insert(INSERT, openfilename + ' ') def KeyPressHandler(self, event): if event.keysym == "Tab": self.AutoCompleteCommand() self.suggestionslist.focus_set() self.suggestionslist.selection_set(0) return "break" else: self.text_input.focus_set() def TopKeyPressHandler(self, event): from tkinter import ACTIVE, INSERT if event.keysym in ['Down', 'Up']: self.suggestionslist.focus_set() elif event.keysym == "Return": word = self.suggestionslist.get(ACTIVE) self.ReplaceTextCommand(word) self.suggestionswindow.withdraw() self.text_input.focus_set() elif len(event.keysym) == 1: self.suggestionswindow.withdraw() self.text_input.insert(INSERT, event.keysym) self.text_input.focus_set() else: self.suggestionswindow.withdraw() self.text_input.focus_set() def NewHandler(self, event): self.NewCommand() def OpenHandler(self, event): self.OpenCommand() def SaveHandler(self, event): self.SaveCommand() def InsertFileNameHandler(self, event): self.InsertFileName() return "break" def QuitHandler(self, event): self.QuitCommand() def ShowHelpHandler(self, event): self.ShowHelpCommand() def RunKeyboardHandler(self, event): from tkinter import SEL_FIRST, TclError try: self.text_input.index(SEL_FIRST) self.RunSelectionCommand() except TclError: self.RunLineCommand() return "break" def RunAllHandler(self, event): self.RunAllCommand() def PopupHandler(self, event): try: self.popupmenu.tk_popup(event.x_root, event.y_root, 0) finally: self.popupmenu.grab_release() def OutputText(self, text): from tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.insert(END, text) self.text_output["state"] = DISABLED def BuildScriptMenu(self, parentmenu, modulename): from tkinter import Menu menu = Menu(parentmenu, bd=1, activeborderwidth=0) try: module = importlib.import_module('vmtk.' + modulename) except ImportError: return None scriptnames = [scriptname for scriptname in getattr(module, '__all__')] for index, scriptname in enumerate(scriptnames): # check if scriptname contains starting prefix 'vmtk.' and remove it before returning list to the user. if 'vmtk.' == scriptname[0:5]: splitList = scriptname.split('.') scriptnames[index] = splitList[1] else: continue menulength = 20 for i in range(len(scriptnames) // menulength + 1): subscriptnames = scriptnames[i * menulength:(i + 1) * menulength] if not subscriptnames: break submenu = Menu(menu, bd=1, activeborderwidth=0) menu.add_cascade(label=subscriptnames[0] + "...", menu=submenu) for scriptname in subscriptnames: callback = CallbackShim(self.InsertScriptName, scriptname) submenu.add_command(label=scriptname, command=callback) return menu def BuildMainFrame(self): from tkinter import Menu, IntVar, StringVar, Toplevel, Listbox, Frame, PanedWindow, Text, Scrollbar, Entry from tkinter import X, N, S, W, E, VERTICAL, TOP, END, DISABLED, RAISED menu = Menu(self.master, activeborderwidth=0, bd=0) self.master.config(menu=menu) filemenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="File", underline=0, menu=filemenu) filemenu.add_command(label="New", accelerator='Ctrl+N', command=self.NewCommand) filemenu.add_command(label="Open...", accelerator='Ctrl+O', command=self.OpenCommand) filemenu.add_command(label="Save as...", accelerator='Ctrl+S', command=self.SaveCommand) filemenu.add_separator() filemenu.add_command(label="Quit", accelerator='Ctrl+Q', command=self.QuitCommand) self.log_on = IntVar() self.log_on.set(1) self.output_to_file = StringVar() self.output_to_file.set('n') scriptmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) modulenames = ['vmtkscripts'] for modulename in modulenames: scriptsubmenu = self.BuildScriptMenu(menu, modulename) if scriptsubmenu: scriptmenu.add_cascade(label=modulename, menu=scriptsubmenu) editmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Edit", underline=0, menu=editmenu) editmenu.add_cascade(label="Insert script", menu=scriptmenu) editmenu.add_command(label="Insert file name", accelerator='Ctrl+F', command=self.InsertFileName) editmenu.add_separator() editmenu.add_command(label="Clear input", command=self.ClearInputCommand) editmenu.add_command(label="Clear output", command=self.ClearOutputCommand) editmenu.add_command(label="Clear all", command=self.ClearAllCommand) editmenu.add_separator() editmenu.add_checkbutton(label="Log", variable=self.log_on) editmenu.add_separator() editmenu.add_radiobutton(label="No output to file", variable=self.output_to_file, value='n') editmenu.add_radiobutton(label="Write output to file", variable=self.output_to_file, value='w') editmenu.add_radiobutton(label="Append output to file", variable=self.output_to_file, value='a') editmenu.add_command(label="Output file...", command=self.OutputFileCommand) runmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Run", underline=0, menu=runmenu) runmenu.add_command(label="Run all", command=self.RunAllCommand) runmenu.add_command(label="Run current line", command=self.RunLineCommand) runmenu.add_command(label="Run selection", command=self.RunSelectionCommand) helpmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Help", underline=0, menu=helpmenu) helpmenu.add_command(label="Help", underline=0, accelerator='F1', command=self.ShowHelpCommand) helpmenu.add_command(label="About", underline=0, command=self.AboutCommand) self.master.bind("<Control-KeyPress-q>", self.QuitHandler) self.master.bind("<Control-KeyPress-n>", self.NewHandler) self.master.bind("<Control-KeyPress-o>", self.OpenHandler) self.master.bind("<Control-KeyPress-s>", self.SaveHandler) self.master.bind("<Control-KeyPress-f>", self.InsertFileNameHandler) self.master.bind("<KeyPress-F1>", self.ShowHelpHandler) self.master.bind("<KeyPress>", self.KeyPressHandler) self.wordIndex = ['1.0', '1.0'] self.suggestionswindow = Toplevel(bg='#ffffff', bd=0, height=50, width=600, highlightthickness=0, takefocus=True) self.suggestionswindow.overrideredirect(1) self.suggestionslist = Listbox(self.suggestionswindow, bg='#ffffff', bd=1, fg='#336699', activestyle='none', highlightthickness=0, height=9) self.suggestionslist.insert(END, "foo") self.suggestionslist.pack(side=TOP, fill=X) self.suggestionswindow.bind("<KeyPress>", self.TopKeyPressHandler) self.suggestionswindow.withdraw() self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=1) content = Frame(self.master, bd=0, padx=2, pady=2) content.grid(row=0, column=0, sticky=N + S + W + E) content.rowconfigure(0, weight=1, minsize=50) content.rowconfigure(1, weight=0) content.columnconfigure(0, weight=1) panes = PanedWindow(content, orient=VERTICAL, bd=1, sashwidth=8, sashpad=0, sashrelief=RAISED, showhandle=True) panes.grid(row=0, column=0, sticky=N + S + W + E) frame1 = Frame(panes, bd=0) frame1.grid(row=0, column=0, sticky=N + S + W + E) frame1.columnconfigure(0, weight=1) frame1.columnconfigure(1, weight=0) frame1.rowconfigure(0, weight=1) panes.add(frame1, height=300, minsize=20) frame2 = Frame(panes, bd=0) frame2.grid(row=1, column=0, sticky=N + S + W + E) frame2.columnconfigure(0, weight=1) frame2.columnconfigure(1, weight=0) frame2.rowconfigure(0, weight=1) panes.add(frame2, minsize=20) self.text_input = Text(frame1, bg='#ffffff', bd=1, highlightthickness=0) self.text_input.bind("<KeyPress>", self.KeyPressHandler) self.text_input.bind("<Button-3>", self.PopupHandler) self.text_input.bind("<Control-Return>", self.RunKeyboardHandler) self.input_scrollbar = Scrollbar(frame1, orient=VERTICAL, command=self.text_input.yview) self.text_input["yscrollcommand"] = self.input_scrollbar.set self.text_output = Text(frame2, state=DISABLED, bd=1, bg='#ffffff', highlightthickness=0) self.output_scrollbar = Scrollbar(frame2, orient=VERTICAL, command=self.text_output.yview) self.text_output["yscrollcommand"] = self.output_scrollbar.set self.text_entry = Entry(content, bd=1, bg='#ffffff', state=DISABLED, highlightthickness=0) self.text_input.focus_set() self.text_input.grid(row=0, column=0, sticky=N + S + W + E) self.input_scrollbar.grid(row=0, column=1, sticky=N + S + W + E) self.text_output.grid(row=0, column=0, sticky=N + S + W + E) self.output_scrollbar.grid(row=0, column=1, sticky=N + S + W + E) self.text_entry.grid(row=1, column=0, sticky=N + S + W + E) self.popupmenu = Menu(self.text_input, tearoff=1, bd=0) self.popupmenu.add_command(label="Context help", command=self.ShowHelpCommand) self.popupmenu.add_cascade(label="Insert script", menu=scriptmenu) self.popupmenu.add_command(label="Insert file name...", command=self.InsertFileName) self.popupmenu.add_separator() self.popupmenu.add_command(label="Run all", command=self.RunAllCommand) self.popupmenu.add_command(label="Run current line", command=self.RunLineCommand) self.popupmenu.add_command(label="Run selection", command=self.RunSelectionCommand) self.output_stream = TkPadOutputStream(self.text_output) self.input_stream = TkPadInputStream(self.text_entry, self.output_stream)
class RecursiveDescentApp(object): """ A graphical tool for exploring the recursive descent parser. The tool displays the parser's tree and the remaining text, and allows the user to control the parser's operation. In particular, the user can expand subtrees on the frontier, match tokens on the frontier against the text, and backtrack. A "step" button simply steps through the parsing process, performing the operations that ``RecursiveDescentParser`` would use. """ def __init__(self, grammar, sent, trace=0): self._sent = sent self._parser = SteppingRecursiveDescentParser(grammar, trace) # Set up the main window. self._top = Tk() self._top.title('Recursive Descent Parser Application') # Set up key bindings. self._init_bindings() # Initialize the fonts. self._init_fonts(self._top) # Animations. animating_lock is a lock to prevent the demo # from performing new operations while it's animating. self._animation_frames = IntVar(self._top) self._animation_frames.set(5) self._animating_lock = 0 self._autostep = 0 # The user can hide the grammar. self._show_grammar = IntVar(self._top) self._show_grammar.set(1) # Create the basic frames. self._init_menubar(self._top) self._init_buttons(self._top) self._init_feedback(self._top) self._init_grammar(self._top) self._init_canvas(self._top) # Initialize the parser. self._parser.initialize(self._sent) # Resize callback self._canvas.bind('<Configure>', self._configure) ######################################### ## Initialization Helpers ######################################### def _init_fonts(self, root): # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html> self._sysfont = tkinter.font.Font(font=Button()["font"]) root.option_add("*Font", self._sysfont) # TWhat's our font size (default=same as sysfont) self._size = IntVar(root) self._size.set(self._sysfont.cget('size')) self._boldfont = tkinter.font.Font(family='helvetica', weight='bold', size=self._size.get()) self._font = tkinter.font.Font(family='helvetica', size=self._size.get()) if self._size.get() < 0: big = self._size.get()-2 else: big = self._size.get()+2 self._bigfont = tkinter.font.Font(family='helvetica', weight='bold', size=big) def _init_grammar(self, parent): # Grammar view. self._prodframe = listframe = Frame(parent) self._prodframe.pack(fill='both', side='left', padx=2) self._prodlist_label = Label(self._prodframe, font=self._boldfont, text='Available Expansions') self._prodlist_label.pack() self._prodlist = Listbox(self._prodframe, selectmode='single', relief='groove', background='white', foreground='#909090', font=self._font, selectforeground='#004040', selectbackground='#c0f0c0') self._prodlist.pack(side='right', fill='both', expand=1) self._productions = list(self._parser.grammar().productions()) for production in self._productions: self._prodlist.insert('end', (' %s' % production)) self._prodlist.config(height=min(len(self._productions), 25)) # Add a scrollbar if there are more than 25 productions. if len(self._productions) > 25: listscroll = Scrollbar(self._prodframe, orient='vertical') self._prodlist.config(yscrollcommand = listscroll.set) listscroll.config(command=self._prodlist.yview) listscroll.pack(side='left', fill='y') # If they select a production, apply it. self._prodlist.bind('<<ListboxSelect>>', self._prodlist_select) def _init_bindings(self): # Key bindings are a good thing. self._top.bind('<Control-q>', self.destroy) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Escape>', self.destroy) self._top.bind('e', self.expand) #self._top.bind('<Alt-e>', self.expand) #self._top.bind('<Control-e>', self.expand) self._top.bind('m', self.match) self._top.bind('<Alt-m>', self.match) self._top.bind('<Control-m>', self.match) self._top.bind('b', self.backtrack) self._top.bind('<Alt-b>', self.backtrack) self._top.bind('<Control-b>', self.backtrack) self._top.bind('<Control-z>', self.backtrack) self._top.bind('<BackSpace>', self.backtrack) self._top.bind('a', self.autostep) #self._top.bind('<Control-a>', self.autostep) self._top.bind('<Control-space>', self.autostep) self._top.bind('<Control-c>', self.cancel_autostep) self._top.bind('<space>', self.step) self._top.bind('<Delete>', self.reset) self._top.bind('<Control-p>', self.postscript) #self._top.bind('<h>', self.help) #self._top.bind('<Alt-h>', self.help) self._top.bind('<Control-h>', self.help) self._top.bind('<F1>', self.help) #self._top.bind('<g>', self.toggle_grammar) #self._top.bind('<Alt-g>', self.toggle_grammar) #self._top.bind('<Control-g>', self.toggle_grammar) self._top.bind('<Control-g>', self.edit_grammar) self._top.bind('<Control-t>', self.edit_sentence) def _init_buttons(self, parent): # Set up the frames. self._buttonframe = buttonframe = Frame(parent) buttonframe.pack(fill='none', side='bottom', padx=3, pady=2) Button(buttonframe, text='Step', background='#90c0d0', foreground='black', command=self.step,).pack(side='left') Button(buttonframe, text='Autostep', background='#90c0d0', foreground='black', command=self.autostep,).pack(side='left') Button(buttonframe, text='Expand', underline=0, background='#90f090', foreground='black', command=self.expand).pack(side='left') Button(buttonframe, text='Match', underline=0, background='#90f090', foreground='black', command=self.match).pack(side='left') Button(buttonframe, text='Backtrack', underline=0, background='#f0a0a0', foreground='black', command=self.backtrack).pack(side='left') # Replace autostep... # self._autostep_button = Button(buttonframe, text='Autostep', # underline=0, command=self.autostep) # self._autostep_button.pack(side='left') def _configure(self, event): self._autostep = 0 (x1, y1, x2, y2) = self._cframe.scrollregion() y2 = event.height - 6 self._canvas['scrollregion'] = '%d %d %d %d' % (x1,y1,x2,y2) self._redraw() def _init_feedback(self, parent): self._feedbackframe = feedbackframe = Frame(parent) feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3) self._lastoper_label = Label(feedbackframe, text='Last Operation:', font=self._font) self._lastoper_label.pack(side='left') lastoperframe = Frame(feedbackframe, relief='sunken', border=1) lastoperframe.pack(fill='x', side='right', expand=1, padx=5) self._lastoper1 = Label(lastoperframe, foreground='#007070', background='#f0f0f0', font=self._font) self._lastoper2 = Label(lastoperframe, anchor='w', width=30, foreground='#004040', background='#f0f0f0', font=self._font) self._lastoper1.pack(side='left') self._lastoper2.pack(side='left', fill='x', expand=1) def _init_canvas(self, parent): self._cframe = CanvasFrame(parent, background='white', #width=525, height=250, closeenough=10, border=2, relief='sunken') self._cframe.pack(expand=1, fill='both', side='top', pady=2) canvas = self._canvas = self._cframe.canvas() # Initially, there's no tree or text self._tree = None self._textwidgets = [] self._textline = None def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Reset Parser', underline=0, command=self.reset, accelerator='Del') filemenu.add_command(label='Print to Postscript', underline=0, command=self.postscript, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label='Edit Grammar', underline=5, command=self.edit_grammar, accelerator='Ctrl-g') editmenu.add_command(label='Edit Text', underline=5, command=self.edit_sentence, accelerator='Ctrl-t') menubar.add_cascade(label='Edit', underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label='Step', underline=1, command=self.step, accelerator='Space') rulemenu.add_separator() rulemenu.add_command(label='Match', underline=0, command=self.match, accelerator='Ctrl-m') rulemenu.add_command(label='Expand', underline=0, command=self.expand, accelerator='Ctrl-e') rulemenu.add_separator() rulemenu.add_command(label='Backtrack', underline=0, command=self.backtrack, accelerator='Ctrl-b') menubar.add_cascade(label='Apply', underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton(label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar) viewmenu.add_separator() viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animation_frames, value=0) animatemenu.add_radiobutton(label="Slow Animation", underline=0, variable=self._animation_frames, value=10, accelerator='-') animatemenu.add_radiobutton(label="Normal Animation", underline=0, variable=self._animation_frames, value=5, accelerator='=') animatemenu.add_radiobutton(label="Fast Animation", underline=0, variable=self._animation_frames, value=2, accelerator='+') menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) helpmenu.add_command(label='Instructions', underline=0, command=self.help, accelerator='F1') menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar) ######################################### ## Helper ######################################### def _get(self, widget, treeloc): for i in treeloc: widget = widget.subtrees()[i] if isinstance(widget, TreeSegmentWidget): widget = widget.label() return widget ######################################### ## Main draw procedure ######################################### def _redraw(self): canvas = self._canvas # Delete the old tree, widgets, etc. if self._tree is not None: self._cframe.destroy_widget(self._tree) for twidget in self._textwidgets: self._cframe.destroy_widget(twidget) if self._textline is not None: self._canvas.delete(self._textline) # Draw the tree. helv = ('helvetica', -self._size.get()) bold = ('helvetica', -self._size.get(), 'bold') attribs = {'tree_color': '#000000', 'tree_width': 2, 'node_font': bold, 'leaf_font': helv,} tree = self._parser.tree() self._tree = tree_to_treesegment(canvas, tree, **attribs) self._cframe.add_widget(self._tree, 30, 5) # Draw the text. helv = ('helvetica', -self._size.get()) bottom = y = self._cframe.scrollregion()[3] self._textwidgets = [TextWidget(canvas, word, font=self._font) for word in self._sent] for twidget in self._textwidgets: self._cframe.add_widget(twidget, 0, 0) twidget.move(0, bottom-twidget.bbox()[3]-5) y = min(y, twidget.bbox()[1]) # Draw a line over the text, to separate it from the tree. self._textline = canvas.create_line(-5000, y-5, 5000, y-5, dash='.') # Highlight appropriate nodes. self._highlight_nodes() self._highlight_prodlist() # Make sure the text lines up. self._position_text() def _redraw_quick(self): # This should be more-or-less sufficient after an animation. self._highlight_nodes() self._highlight_prodlist() self._position_text() def _highlight_nodes(self): # Highlight the list of nodes to be checked. bold = ('helvetica', -self._size.get(), 'bold') for treeloc in self._parser.frontier()[:1]: self._get(self._tree, treeloc)['color'] = '#20a050' self._get(self._tree, treeloc)['font'] = bold for treeloc in self._parser.frontier()[1:]: self._get(self._tree, treeloc)['color'] = '#008080' def _highlight_prodlist(self): # Highlight the productions that can be expanded. # Boy, too bad tkinter doesn't implement Listbox.itemconfig; # that would be pretty useful here. self._prodlist.delete(0, 'end') expandable = self._parser.expandable_productions() untried = self._parser.untried_expandable_productions() productions = self._productions for index in range(len(productions)): if productions[index] in expandable: if productions[index] in untried: self._prodlist.insert(index, ' %s' % productions[index]) else: self._prodlist.insert(index, ' %s (TRIED)' % productions[index]) self._prodlist.selection_set(index) else: self._prodlist.insert(index, ' %s' % productions[index]) def _position_text(self): # Line up the text widgets that are matched against the tree numwords = len(self._sent) num_matched = numwords - len(self._parser.remaining_text()) leaves = self._tree_leaves()[:num_matched] xmax = self._tree.bbox()[0] for i in range(0, len(leaves)): widget = self._textwidgets[i] leaf = leaves[i] widget['color'] = '#006040' leaf['color'] = '#006040' widget.move(leaf.bbox()[0] - widget.bbox()[0], 0) xmax = widget.bbox()[2] + 10 # Line up the text widgets that are not matched against the tree. for i in range(len(leaves), numwords): widget = self._textwidgets[i] widget['color'] = '#a0a0a0' widget.move(xmax - widget.bbox()[0], 0) xmax = widget.bbox()[2] + 10 # If we have a complete parse, make everything green :) if self._parser.currently_complete(): for twidget in self._textwidgets: twidget['color'] = '#00a000' # Move the matched leaves down to the text. for i in range(0, len(leaves)): widget = self._textwidgets[i] leaf = leaves[i] dy = widget.bbox()[1] - leaf.bbox()[3] - 10.0 dy = max(dy, leaf.parent().label().bbox()[3] - leaf.bbox()[3] + 10) leaf.move(0, dy) def _tree_leaves(self, tree=None): if tree is None: tree = self._tree if isinstance(tree, TreeSegmentWidget): leaves = [] for child in tree.subtrees(): leaves += self._tree_leaves(child) return leaves else: return [tree] ######################################### ## Button Callbacks ######################################### def destroy(self, *e): self._autostep = 0 if self._top is None: return self._top.destroy() self._top = None def reset(self, *e): self._autostep = 0 self._parser.initialize(self._sent) self._lastoper1['text'] = 'Reset Application' self._lastoper2['text'] = '' self._redraw() def autostep(self, *e): if self._animation_frames.get() == 0: self._animation_frames.set(2) if self._autostep: self._autostep = 0 else: self._autostep = 1 self._step() def cancel_autostep(self, *e): #self._autostep_button['text'] = 'Autostep' self._autostep = 0 # Make sure to stop auto-stepping if we get any user input. def step(self, *e): self._autostep = 0; self._step() def match(self, *e): self._autostep = 0; self._match() def expand(self, *e): self._autostep = 0; self._expand() def backtrack(self, *e): self._autostep = 0; self._backtrack() def _step(self): if self._animating_lock: return # Try expanding, matching, and backtracking (in that order) if self._expand(): pass elif self._parser.untried_match() and self._match(): pass elif self._backtrack(): pass else: self._lastoper1['text'] = 'Finished' self._lastoper2['text'] = '' self._autostep = 0 # Check if we just completed a parse. if self._parser.currently_complete(): self._autostep = 0 self._lastoper2['text'] += ' [COMPLETE PARSE]' def _expand(self, *e): if self._animating_lock: return old_frontier = self._parser.frontier() rv = self._parser.expand() if rv is not None: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = rv self._prodlist.selection_clear(0, 'end') index = self._productions.index(rv) self._prodlist.selection_set(index) self._animate_expand(old_frontier[0]) return 1 else: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = '(all expansions tried)' return 0 def _match(self, *e): if self._animating_lock: return old_frontier = self._parser.frontier() rv = self._parser.match() if rv is not None: self._lastoper1['text'] = 'Match:' self._lastoper2['text'] = rv self._animate_match(old_frontier[0]) return 1 else: self._lastoper1['text'] = 'Match:' self._lastoper2['text'] = '(failed)' return 0 def _backtrack(self, *e): if self._animating_lock: return if self._parser.backtrack(): elt = self._parser.tree() for i in self._parser.frontier()[0]: elt = elt[i] self._lastoper1['text'] = 'Backtrack' self._lastoper2['text'] = '' if isinstance(elt, Tree): self._animate_backtrack(self._parser.frontier()[0]) else: self._animate_match_backtrack(self._parser.frontier()[0]) return 1 else: self._autostep = 0 self._lastoper1['text'] = 'Finished' self._lastoper2['text'] = '' return 0 def about(self, *e): ABOUT = ("NLTK Recursive Descent Parser Application\n"+ "Written by Edward Loper") TITLE = 'About: Recursive Descent Parser Application' try: from tkinter.messagebox import Message Message(message=ABOUT, title=TITLE).show() except: ShowText(self._top, TITLE, ABOUT) def help(self, *e): self._autostep = 0 # The default font's not very legible; try using 'fixed' instead. try: ShowText(self._top, 'Help: Recursive Descent Parser Application', (__doc__ or '').strip(), width=75, font='fixed') except: ShowText(self._top, 'Help: Recursive Descent Parser Application', (__doc__ or '').strip(), width=75) def postscript(self, *e): self._autostep = 0 self._cframe.print_to_file() def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def resize(self, size=None): if size is not None: self._size.set(size) size = self._size.get() self._font.configure(size=-(abs(size))) self._boldfont.configure(size=-(abs(size))) self._sysfont.configure(size=-(abs(size))) self._bigfont.configure(size=-(abs(size+2))) self._redraw() ######################################### ## Expand Production Selection ######################################### def _toggle_grammar(self, *e): if self._show_grammar.get(): self._prodframe.pack(fill='both', side='left', padx=2, after=self._feedbackframe) self._lastoper1['text'] = 'Show Grammar' else: self._prodframe.pack_forget() self._lastoper1['text'] = 'Hide Grammar' self._lastoper2['text'] = '' # def toggle_grammar(self, *e): # self._show_grammar = not self._show_grammar # if self._show_grammar: # self._prodframe.pack(fill='both', expand='y', side='left', # after=self._feedbackframe) # self._lastoper1['text'] = 'Show Grammar' # else: # self._prodframe.pack_forget() # self._lastoper1['text'] = 'Hide Grammar' # self._lastoper2['text'] = '' def _prodlist_select(self, event): selection = self._prodlist.curselection() if len(selection) != 1: return index = int(selection[0]) old_frontier = self._parser.frontier() production = self._parser.expand(self._productions[index]) if production: self._lastoper1['text'] = 'Expand:' self._lastoper2['text'] = production self._prodlist.selection_clear(0, 'end') self._prodlist.selection_set(index) self._animate_expand(old_frontier[0]) else: # Reset the production selections. self._prodlist.selection_clear(0, 'end') for prod in self._parser.expandable_productions(): index = self._productions.index(prod) self._prodlist.selection_set(index) ######################################### ## Animation ######################################### def _animate_expand(self, treeloc): oldwidget = self._get(self._tree, treeloc) oldtree = oldwidget.parent() top = not isinstance(oldtree.parent(), TreeSegmentWidget) tree = self._parser.tree() for i in treeloc: tree = tree[i] widget = tree_to_treesegment(self._canvas, tree, node_font=self._boldfont, leaf_color='white', tree_width=2, tree_color='white', node_color='white', leaf_font=self._font) widget.label()['color'] = '#20a050' (oldx, oldy) = oldtree.label().bbox()[:2] (newx, newy) = widget.label().bbox()[:2] widget.move(oldx-newx, oldy-newy) if top: self._cframe.add_widget(widget, 0, 5) widget.move(30-widget.label().bbox()[0], 0) self._tree = widget else: oldtree.parent().replace_child(oldtree, widget) # Move the children over so they don't overlap. # Line the children up in a strange way. if widget.subtrees(): dx = (oldx + widget.label().width()/2 - widget.subtrees()[0].bbox()[0]/2 - widget.subtrees()[0].bbox()[2]/2) for subtree in widget.subtrees(): subtree.move(dx, 0) self._makeroom(widget) if top: self._cframe.destroy_widget(oldtree) else: oldtree.destroy() colors = ['gray%d' % (10*int(10*x/self._animation_frames.get())) for x in range(self._animation_frames.get(),0,-1)] # Move the text string down, if necessary. dy = widget.bbox()[3] + 30 - self._canvas.coords(self._textline)[1] if dy > 0: for twidget in self._textwidgets: twidget.move(0, dy) self._canvas.move(self._textline, 0, dy) self._animate_expand_frame(widget, colors) def _makeroom(self, treeseg): """ Make sure that no sibling tree bbox's overlap. """ parent = treeseg.parent() if not isinstance(parent, TreeSegmentWidget): return index = parent.subtrees().index(treeseg) # Handle siblings to the right rsiblings = parent.subtrees()[index+1:] if rsiblings: dx = treeseg.bbox()[2] - rsiblings[0].bbox()[0] + 10 for sibling in rsiblings: sibling.move(dx, 0) # Handle siblings to the left if index > 0: lsibling = parent.subtrees()[index-1] dx = max(0, lsibling.bbox()[2] - treeseg.bbox()[0] + 10) treeseg.move(dx, 0) # Keep working up the tree. self._makeroom(parent) def _animate_expand_frame(self, widget, colors): if len(colors) > 0: self._animating_lock = 1 widget['color'] = colors[0] for subtree in widget.subtrees(): if isinstance(subtree, TreeSegmentWidget): subtree.label()['color'] = colors[0] else: subtree['color'] = colors[0] self._top.after(50, self._animate_expand_frame, widget, colors[1:]) else: widget['color'] = 'black' for subtree in widget.subtrees(): if isinstance(subtree, TreeSegmentWidget): subtree.label()['color'] = 'black' else: subtree['color'] = 'black' self._redraw_quick() widget.label()['color'] = 'black' self._animating_lock = 0 if self._autostep: self._step() def _animate_backtrack(self, treeloc): # Flash red first, if we're animating. if self._animation_frames.get() == 0: colors = [] else: colors = ['#a00000', '#000000', '#a00000'] colors += ['gray%d' % (10*int(10*x/(self._animation_frames.get()))) for x in range(1, self._animation_frames.get()+1)] widgets = [self._get(self._tree, treeloc).parent()] for subtree in widgets[0].subtrees(): if isinstance(subtree, TreeSegmentWidget): widgets.append(subtree.label()) else: widgets.append(subtree) self._animate_backtrack_frame(widgets, colors) def _animate_backtrack_frame(self, widgets, colors): if len(colors) > 0: self._animating_lock = 1 for widget in widgets: widget['color'] = colors[0] self._top.after(50, self._animate_backtrack_frame, widgets, colors[1:]) else: for widget in widgets[0].subtrees(): widgets[0].remove_child(widget) widget.destroy() self._redraw_quick() self._animating_lock = 0 if self._autostep: self._step() def _animate_match_backtrack(self, treeloc): widget = self._get(self._tree, treeloc) node = widget.parent().label() dy = (1.0 * (node.bbox()[3] - widget.bbox()[1] + 14) / max(1, self._animation_frames.get())) self._animate_match_backtrack_frame(self._animation_frames.get(), widget, dy) def _animate_match(self, treeloc): widget = self._get(self._tree, treeloc) dy = ((self._textwidgets[0].bbox()[1] - widget.bbox()[3] - 10.0) / max(1, self._animation_frames.get())) self._animate_match_frame(self._animation_frames.get(), widget, dy) def _animate_match_frame(self, frame, widget, dy): if frame > 0: self._animating_lock = 1 widget.move(0, dy) self._top.after(10, self._animate_match_frame, frame-1, widget, dy) else: widget['color'] = '#006040' self._redraw_quick() self._animating_lock = 0 if self._autostep: self._step() def _animate_match_backtrack_frame(self, frame, widget, dy): if frame > 0: self._animating_lock = 1 widget.move(0, dy) self._top.after(10, self._animate_match_backtrack_frame, frame-1, widget, dy) else: widget.parent().remove_child(widget) widget.destroy() self._animating_lock = 0 if self._autostep: self._step() def edit_grammar(self, *e): CFGEditor(self._top, self._parser.grammar(), self.set_grammar) def set_grammar(self, grammar): self._parser.set_grammar(grammar) self._productions = list(grammar.productions()) self._prodlist.delete(0, 'end') for production in self._productions: self._prodlist.insert('end', (' %s' % production)) def edit_sentence(self, *e): sentence = " ".join(self._sent) title = 'Edit Text' instr = 'Enter a new sentence to parse.' EntryDialog(self._top, sentence, instr, self.set_sentence, title) def set_sentence(self, sentence): self._sent = sentence.split() #[XX] use tagged? self.reset()
class App: # 初始化类的一些属性和方法 def __init__(self): self.root = Tk() self.width = self.root.winfo_screenwidth() # 获取电脑窗体的宽度 self.height = self.root.winfo_screenheight() # 获取电脑窗体的高度 '''设置开学日期''' self.basicDate = '2019-9-2' self.basicDate = strptime(self.basicDate, "%Y-%m-%d") '''获取当前日期''' self.today = strftime('%Y-%m-%d') # print(type(self.today)) # self.today = '2019-9-16' self.today = strptime(self.today, "%Y-%m-%d") # print(type(self.today)) '''获取当前日期''' '''计算当前是第几周''' self.basicDate = datetime(self.basicDate[0], self.basicDate[1], self.basicDate[2]) self.today = datetime(self.today[0], self.today[1], self.today[2]) self.result = (self.today - self.basicDate).days + 1 # 今天是开学的第self.result天 # print(self.result) self.week = 0 if self.result % 7 == 0: self.week = self.result // 7 else: self.week = self.result // 7 + 1 '''计算当前是第几周''' self.initForm() # 初始化应用窗体 def initForm(self): self.root.title("课表(当前是第"+str(self.week)+"周)—— 作者:逸轩") w = int((self.width - 880) / 2) h = int((self.height - 500) / 2) self.root.geometry('880x500+%s+%s' % (w, h)) self.initClasses(self.week) self.initListbox() self.root.mainloop() # 初始化课表 def initClasses(self, week): self.fm = Frame(self.root, height=200, width=400) self.fm.place(x=0, y=0) # 上课时间 labelTime = Label(self.fm, text=' ', fg='black') labelTime.grid(row=0, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='1(8:00)', fg='black', background='#7FFF00', width=12) labelTime.grid(row=1, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='2(8:55)', fg='black', background='#FFD700', width=12) labelTime.grid(row=2, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='3(10:00)', fg='black', background='#FF69B4', width=12) labelTime.grid(row=3, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='4(10:55)', fg='black', background='#BA2BE2', width=12) labelTime.grid(row=4, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='5(14:00)', fg='black', background='#FFA07A', width=12) labelTime.grid(row=5, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='6(14:55)', fg='black', background='#87CEFA', width=12) labelTime.grid(row=6, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='7(16:00)', fg='black', background='#00FFFF', width=12) labelTime.grid(row=7, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='8(16:55)', fg='black', background='#98FB98', width=12) labelTime.grid(row=8, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='9(19:00)', fg='black', background='#FFFF00', width=12) labelTime.grid(row=9, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='10(19:55)', fg='black', background='#D2691E', width=12) labelTime.grid(row=10, column=0, sticky=E, padx=5, pady=5) labelTime = Label(self.fm, text='11(20:50)', fg='black', background='#FF6347', width=12) labelTime.grid(row=11, column=0, sticky=E, padx=5, pady=5) label1 = Label(self.fm, text='星期一', fg='black', background='#FF8C00', width=20) label1.grid(row=0, column=1, sticky=W + S + N + E, padx=5, pady=5) label2 = Label(self.fm, text='星期二', fg='black', background='#FF8C00', width=20) label2.grid(row=0, column=2, sticky=W + S + N + E, padx=5, pady=5) label3 = Label(self.fm, text='星期三', fg='black', background='#FF8C00', width=20) label3.grid(row=0, column=3, sticky=W + S + N + E, padx=5, pady=5) label4 = Label(self.fm, text='星期四', fg='black', background='#FF8C00', width=20) label4.grid(row=0, column=4, sticky=W + S + N + E, padx=5, pady=5) label5 = Label(self.fm, text='星期五', fg='black', background='#FF8C00', width=20) label5.grid(row=0, column=5, sticky=W + S + N + E, padx=5, pady=5) # self.fm.place_forget() # 整理星期一************************************************* if week >= 16 and week <= 17: label1 = Label(self.fm, text='VC++(计科楼101)', fg='black', background='#7FFF00') label1.grid(row=1, column=1, sticky=W + S + N + E, padx=5, pady=5) label1 = Label(self.fm, text='VC++(计科楼101)', fg='black', background='#FFD700', width=20) label1.grid(row=2, column=1, sticky=W + S + N + E, padx=5, pady=5) if (week >= 4 and week <= 6) or (week >= 8 and week <= 16): label1 = Label(self.fm, text='JavaScript(教1楼307)', fg='black', background='#FF69B4', width=20) label1.grid(row=3, column=1, sticky=W + S + N + E, padx=5, pady=5) label1 = Label(self.fm, text='JavaScript(教1楼307)', fg='black', background='#BA2BE2', width=20) label1.grid(row=4, column=1, sticky=W + S + N + E, padx=5, pady=5) if week >= 1 and week <= 16: label1 = Label(self.fm, text='大学英语(经法楼107)', fg='black', background='#FFA07A', width=20) label1.grid(row=5, column=1, sticky=W + S + N + E, padx=5, pady=5) label1 = Label(self.fm, text='大学英语(经法楼107)', fg='black', background='#87CEFA', width=20) label1.grid(row=6, column=1, sticky=W + S + N + E, padx=5, pady=5) if (week >= 1 and week <= 6) or (week >= 8 and week <= 17): label1 = Label(self.fm, text='VC++(教1楼306)', fg='black', background='#00FFFF', width=20) label1.grid(row=7, column=1, sticky=W + S + N + E, padx=5, pady=5) label1 = Label(self.fm, text='VC++(教1楼306)', fg='black', background='#98FB98', width=20) label1.grid(row=8, column=1, sticky=W + S + N + E, padx=5, pady=5) if (week >= 1 and week <= 6) or (week >= 8 and week <= 17): label1 = Label(self.fm, text='VC++(计科楼203)', fg='black', background='#FFFF00', width=20) label1.grid(row=9, column=1, sticky=W + S + N + E, padx=5, pady=5) label1 = Label(self.fm, text='VC++(计科楼203)', fg='black', background='#D2691E', width=20) label1.grid(row=10, column=1, sticky=W + S + N + E, padx=5, pady=5) # 整理星期一************************************************* # 整理星期二************************************************* if (week >= 1 and week <= 6) or (week >= 8 and week <= 17): label2 = Label(self.fm, text='JSP(教1楼506)', fg='black', background='#7FFF00', width=20) label2.grid(row=1, column=2, sticky=W + S + N + E, padx=5, pady=5) label2 = Label(self.fm, text='JSP(教1楼506)', fg='black', background='#FFD700', width=20) label2.grid(row=2, column=2, sticky=W + S + N + E, padx=5, pady=5) if (week >= 5 and week <= 6) or (week >= 8 and week <= 17): label2 = Label(self.fm, text='JSP(计科楼203)', fg='black', background='#FF69B4', width=20) label2.grid(row=3, column=2, sticky=W + S + N + E, padx=5, pady=5) label2 = Label(self.fm, text='JSP(计科楼203)', fg='black', background='#BA2BE2', width=20) label2.grid(row=4, column=2, sticky=W + S + N + E, padx=5, pady=5) if (week >= 5 and week <= 6) or (week >= 8 and week <= 17): label2 = Label(self.fm, text='IOS(教1楼509)', fg='black', background='#FFA07A', width=20) label2.grid(row=5, column=2, sticky=W + S + N + E, padx=5, pady=5) label2 = Label(self.fm, text='IOS(教1楼509)', fg='black', background='#87CEFA', width=20) label2.grid(row=6, column=2, sticky=W + S + N + E, padx=5, pady=5) if week == 17: label2 = Label(self.fm, text='Java(计科楼203)', fg='black', background='#7FFF00', width=20) label2.grid(row=9, column=2, sticky=W + S + N + E, padx=5, pady=5) label2 = Label(self.fm, text='Java(计科楼203)', fg='black', background='#7FFF00', width=20) label2.grid(row=10, column=2, sticky=W + S + N + E, padx=5, pady=5) if (week <= 16) and (week % 2 == 0): label2 = Label(self.fm, text='计算机网络(计科楼104)', fg='black', background='#FFFF00', width=20) label2.grid(row=9, column=2, sticky=W + S + N + E, padx=5, pady=5) label2 = Label(self.fm, text='计算机网络(计科楼104)', fg='black', background='#D2691E', width=20) label2.grid(row=10, column=2, sticky=W + S + N + E, padx=5, pady=5) if (week <= 16) and (week % 2 == 0): label2 = Label(self.fm, text='计算机网络(计科楼104)', fg='black', background='#FF6347', width=20) label2.grid(row=11, column=2, sticky=W + S + N + E, padx=5, pady=5) # 整理星期二************************************************* # 整理星期三************************************************* if (week >= 9 and week <= 17) and (week % 2 != 0): label3 = Label(self.fm, text='计算机网络(教1楼308)', fg='black', background='#FF69B4', width=20) label3.grid(row=3, column=3, sticky=W + S + N + E, padx=5, pady=5) label3 = Label(self.fm, text='计算机网络(教1楼308)', fg='black', background='#BA2BE2', width=20) label3.grid(row=4, column=3, sticky=W + S + N + E, padx=5, pady=5) if (week >= 1 and week <= 6) or (week == 8): label3 = Label(self.fm, text='计算机网络(教1楼308)', fg='black', background='#FF69B4', width=20) label3.grid(row=3, column=3, sticky=W + S + N + E, padx=5, pady=5) label3 = Label(self.fm, text='计算机网络(教1楼308)', fg='black', background='#BA2BE2', width=20) label3.grid(row=4, column=3, sticky=W + S + N + E, padx=5, pady=5) if (week >= 10 and week <= 16) and (week % 2 == 0): label3 = Label(self.fm, text='IOS(计科楼203)', fg='black', background='#FF69B4', width=20) label3.grid(row=3, column=3, sticky=W + S + N + E, padx=5, pady=5) label3 = Label(self.fm, text='IOS(计科楼203)', fg='black', background='#BA2BE2', width=20) label3.grid(row=4, column=3, sticky=W + S + N + E, padx=5, pady=5) if (week >= 1 and week <= 6) or (week >= 8 and week <= 17): label3 = Label(self.fm, text='Java(教1楼509)', fg='black', background='#FFA07A', width=20) label3.grid(row=5, column=3, sticky=W + S + N + E, padx=5, pady=5) label3 = Label(self.fm, text='Java(教1楼509)', fg='black', background='#87CEFA', width=20) label3.grid(row=6, column=3, sticky=W + S + N + E, padx=5, pady=5) if (week >= 1 and week <= 6) or (week >= 8 and week <= 17): label3 = Label(self.fm, text='Java(计科楼203)', fg='black', background='#00FFFF', width=20) label3.grid(row=7, column=3, sticky=W + S + N + E, padx=5, pady=5) label3 = Label(self.fm, text='Java(计科楼203)', fg='black', background='#98FB98', width=20) label3.grid(row=8, column=3, sticky=W + S + N + E, padx=5, pady=5) # 整理星期三************************************************* # 整理星期四************************************************* if (week >= 1 and week <= 6) or (week >= 8 and week <= 17): label4 = Label(self.fm, text='数据库(教1楼406)', fg='black', background='#7FFF00', width=20) label4.grid(row=1, column=4, sticky=W + S + N + E, padx=5, pady=5) label4 = Label(self.fm, text='数据库(教1楼406)', fg='black', background='#FFD700', width=20) label4.grid(row=2, column=4, sticky=W + S + N + E, padx=5, pady=5) if (week >= 4 and week <= 6) or (week >= 8 and week <= 16): label4 = Label(self.fm, text='JavaScript(计科楼104)', fg='black', background='#FF69B4', width=20) label4.grid(row=3, column=4, sticky=W + S + N + E, padx=5, pady=5) label4 = Label(self.fm, text='JavaScript(计科楼104)', fg='black', background='#BA2BE2', width=20) label4.grid(row=4, column=4, sticky=W + S + N + E, padx=5, pady=5) if week == 6 or week == 8: label4 = Label(self.fm, text='IOS(计科楼203)', fg='black', background='#FFA07A', width=20) label4.grid(row=5, column=4, sticky=W + S + N + E, padx=5, pady=5) label4 = Label(self.fm, text='IOS(计科楼203)', fg='black', background='#87CEFA', width=20) label4.grid(row=6, column=4, sticky=W + S + N + E, padx=5, pady=5) if week >= 6 and week <= 11: label4 = Label(self.fm, text='心理健康(教1楼211)', fg='black', background='#FFFF00', width=20) label4.grid(row=9, column=4, sticky=W + S + N + E, padx=5, pady=5) label4 = Label(self.fm, text='心理健康(教1楼211)', fg='black', background='#D2691E', width=20) label4.grid(row=10, column=4, sticky=W + S + N + E, padx=5, pady=5) if week >= 6 and week <= 11: label4 = Label(self.fm, text='心理健康(教1楼211)', fg='black', background='#FF6347', width=20) label4.grid(row=11, column=4, sticky=W + S + N + E, padx=5, pady=5) # 整理星期四************************************************* # 整理星期五************************************************* if (week <= 17 and week % 2 != 0) and (week != 7): label5 = Label(self.fm, text='数据库(教1楼408)', fg='black', background='#7FFF00', width=20) label5.grid(row=1, column=5, sticky=W + S + N + E, padx=5, pady=5) label5 = Label(self.fm, text='数据库(教1楼408)', fg='black', background='#FFD700', width=20) label5.grid(row=2, column=5, sticky=W + S + N + E, padx=5, pady=5) if (week >= 5 and week <= 16) and (week % 2 == 0): label5 = Label(self.fm, text='数据库(计科楼203)', fg='black', background='#7FFF00', width=20) label5.grid(row=1, column=5, sticky=W + S + N + E, padx=5, pady=5) label5 = Label(self.fm, text='数据库(计科楼203)', fg='black', background='#FFD700', width=20) label5.grid(row=2, column=5, sticky=W + S + N + E, padx=5, pady=5) if (week <= 17 and week % 2 != 0) and (week != 7): label5 = Label(self.fm, text='Python(教1楼507)', fg='black', background='#FF69B4', width=20) label5.grid(row=3, column=5, sticky=W + S + N + E, padx=5, pady=5) label5 = Label(self.fm, text='Python(教1楼507)', fg='black', background='#BA2BE2', width=20) label5.grid(row=4, column=5, sticky=W + S + N + E, padx=5, pady=5) if (week >= 4 and week <= 6) or (week >= 8 and week <= 16): label5 = Label(self.fm, text='Python(计科楼303)', fg='black', background='#FFA07A', width=20) label5.grid(row=5, column=5, sticky=W + S + N + E, padx=5, pady=5) label5 = Label(self.fm, text='Python(计科楼303)', fg='black', background='#87CEFA', width=20) label5.grid(row=6, column=5, sticky=W + S + N + E, padx=5, pady=5) # 整理星期五************************************************* # 点击确定按钮 def confirmBtn(self): value = self.listbox.get(self.listbox.curselection()) # messagebox.showinfo('提示', '你刚才点击了' + str(value))confirmBtn self.fm.place_forget() if str(value) == '自动': self.initClasses(self.week) self.root.title("课表(当前是第" + str(self.week) + "周)—— 作者:逸轩") else: self.initClasses(value) self.root.title("课表(当前是第" + str(value) + "周)—— 作者:逸轩") # 初始化滑动列表 def initListbox(self): label = Label(self.root, text='手动选择周数查看:') label.place(x=500, y=450) self.listbox = Listbox(self.root, width=5, height=4, background='yellow') self.listbox.place(x=630, y=420) self.listbox.insert(1, '自动') for i in range(1, 18): self.listbox.insert(17, i) self.listbox.selection_set(0) scroll = Scrollbar(self.root, relief='ridge', command=self.listbox.yview) scroll.place(x=670, y=420, height=65) self.listbox.configure(yscrollcommand=scroll.set) button = Button(self.root, text='确定', width=6, command=self.confirmBtn) button.place(x=720, y=450)
class LoggedUI: def __init__(self, master, user_name): self.master = master self.user_name = user_name self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if server_connection: try: self.client.connect(ADDR) except socket.error as ConnectionAbortedError: self.master.quit() self.connection_info = messagebox.showerror(title='Connection Error', message=f'{ConnectionAbortedError}') master.title("Password Master") master.geometry('1280x720') master.resizable(0, 0) self.background = PhotoImage(file='Images/background.png') self.background_label = Label(master, image=self.background).pack() self.user_account_label = Label(master, text='Logged in: {}'.format(user_name), font=LABEL_FONT).place(x=100, y=100) self.user_pass_label = Label(master, text='Passwords: ', font=LABEL_FONT).place(x=100, y=150) # Adding passwords self.user_add_passw_label = Label(master, text='Password Name Password', font=LABEL_FONT).place(x=772, y=150) self.user_pass_name_entry = Entry(master, width=12, font=ENTRY_FONT) self.user_pass_name_entry.place(x=780, y=230) self.user_password_entry = Entry(master, width=12, font=ENTRY_FONT) self.user_password_entry.place(x=1000, y=230) self.submit_button = Button(master, text="Add Password", height=BUTTON_HEIGHT, width=BUTTON_WIDTH, font=BUTTON_FONT, command=self.add_password).place(x=1045, y=300) # Deleting Passwords self.user_add_passw_label = Label(master, text='ID of Password', font=LABEL_FONT).place(x=982, y=420) self.pass_id_entry = Entry(master, width=12, font=ENTRY_FONT) self.pass_id_entry.place(x=1000, y=500) self.delete_button = Button(master, text="Delete", height=BUTTON_HEIGHT, width=BUTTON_WIDTH, font=BUTTON_FONT, command=self.delete_password).place(x=1045, y=550) # Logut button self.submit_button = Button(master, text="Log out", height=BUTTON_HEIGHT, width=BUTTON_WIDTH, font=BUTTON_FONT, command=self.logout).place(x=50, y=625) self.testt = '1 Netflix xsd@xd# \n 2 Email xsddasd23sda ' # Password holder self.show_password_button = Button(master, text="Show Passwords", height=BUTTON_HEIGHT, width=13, font=BUTTON_FONT, command=self.display_passwords).place(x=350, y=625) self.pass_list = Listbox(self.master, width=75, height=22) self.pass_list.place(x=100, y=220) def logout(self): self.send_request('Q') self.master.destroy() def delete_password(self): pass_id = self.pass_id_entry.get() pass_request = 'D' + ';' + self.user_name + ';' + pass_id self.send_request(pass_request) server_response = self.client.recv(HEADER).decode(FORMAT) if int(server_response): messagebox.showinfo(message='Password Deleted!') self.display_passwords() else: messagebox.showerror(title='Invalid Input!', message='Index of pass does not exist') def add_password(self): password_name = self.user_pass_name_entry.get() password = self.user_password_entry.get() password_data = 'A' + ';' + self.user_name + ';' + password_name + ';' + password self.send_request(password_data) server_response = self.client.recv(HEADER).decode(FORMAT) if int(server_response): messagebox.showinfo(message='Password Added!') self.display_passwords() else: messagebox.showerror(message='Failed when inserting the password') def display_passwords(self): self.send_request(f'S;{self.user_name}') final = [] counter = 0 row = [] string_data = self.client.recv(HEADER).decode(FORMAT) data_separeted = string_data.split(';') self.pass_list.delete(0, END) for i in range(len(data_separeted) - 1): if counter < 3: row.append(data_separeted[i]) counter += 1 if counter == 3: final.append(row) row = [] counter = 0 for i in range(len(final)): self.pass_list.insert(END, final[i]) def send_request(self, request): request = request.encode(FORMAT) self.client.send(request)
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)