class App_Progressbar(object): """docstring for App_Progressbar""" def __init__(self, master, root, below, styles): super(App_Progressbar, self).__init__() self.master = master self.root = root self.styles = styles self.below = below self.putProgressbar() def putProgressbar(self): self.bar = LabelFrame(self.master, width=0, bg=self.styles['fg'], height=10, borderwidth=0) def set_pct(self, pct): window_width = self.root.winfo_width() desired_px = int(window_width * pct * 0.01) self.bar.config(width=desired_px) def show(self, *args, **kwargs): self.bar.pack() self.bar.place(x=0, y=self.below.winfo_height()) def hide(self, *args, **kwargs): self.bar.place_forget(*args, **kwargs)
def right_frame(parent): rf_width = 300 rf_height = 360 # right side frame frame_right = LabelFrame( parent.building_pos_window, text="Building Position", width=rf_width - 10, height=rf_height - 10, ) frame_right.grid_rowconfigure(0, weight=1) frame_right.grid_columnconfigure(0, weight=1) frame_right.grid_propagate(False) canvas_right = Canvas(frame_right) canvas_right.grid(row=0, column=0, sticky=N + W) # Link a scrollbar to the canvas def on_mousewheel(event): canvas_right.yview_scroll(int(-1 * (event.delta / 120)), "units") def bound_to_mousewheel(event): canvas_right.bind_all("<MouseWheel>", on_mousewheel) def unbound_to_mousewheel(event): canvas_right.unbind_all("<MouseWheel>") y_scrollbar = Scrollbar(frame_right, orient="vertical", command=canvas_right.yview) y_scrollbar.grid(row=0, column=1, sticky='ns') canvas_right.configure(yscrollcommand=y_scrollbar.set) inner_frame_right = Frame(canvas_right) inner_frame_right.bind('<Enter>', bound_to_mousewheel) inner_frame_right.bind('<Leave>', unbound_to_mousewheel) canvas_right.create_window((0, 0), window=inner_frame_right, anchor='nw') idx = 0 for e_name in BuildingNames: building_name_xy_config_frame( inner_frame_right, idx, e_name.value, parent.bot_building_pos.get(e_name.value, [-1, -1]) if parent.bot_building_pos is not None else [-1, -1]) idx = idx + 1 inner_frame_right.update_idletasks() frame_right.config(width=rf_width - 10, height=360 - 10) canvas_right.config(width=rf_width - 10, height=360 - 10, scrollregion=canvas_right.bbox("all")) frame_right.grid(row=0, column=1, padx=5, pady=5, sticky=N + W) return inner_frame_right
def _configure_container(self, container: tk.LabelFrame): container.config(text='Host Game') tk.Label(container, text='Language:').grid(row=2, column=0, pady=(0, 6), sticky=tk.W) self.__lang = tk.StringVar() self.__lang.set('en') tk.OptionMenu(container, self.__lang, 'en', 'lv')\ .grid(row=2, column=1, pady=(0, 6), sticky=tk.W)
def config_frame(self): frame_canvas = LabelFrame(self, text='Config', width=self.windows_size[0], height=self.windows_size[1] - 200 ) frame_canvas.grid_rowconfigure(0, weight=1) frame_canvas.grid_columnconfigure(0, weight=1) frame_canvas.grid_propagate(False) # Add a canvas in that frame canvas = Canvas(frame_canvas) canvas.grid(row=0, column=0, sticky=N+W) # Link a scrollbar to the canvas def on_mousewheel(event): canvas.yview_scroll(int(-1*(event.delta/120)), "units") def bound_to_mousewheel(event): canvas.bind_all("<MouseWheel>", on_mousewheel) def unbound_to_mousewheel(event): canvas.unbind_all("<MouseWheel>") y_scrollbar = Scrollbar(frame_canvas, orient="vertical", command=canvas.yview) y_scrollbar.grid(row=0, column=1, sticky='ns') canvas.configure(yscrollcommand=y_scrollbar.set) inner_frame = Frame(canvas) inner_frame.bind('<Enter>', bound_to_mousewheel) inner_frame.bind('<Leave>', unbound_to_mousewheel) canvas.create_window((0, 0), window=inner_frame, anchor='nw') for i in range(len(atf.bot_config_title_fns)): title_fns, sub_fns = atf.bot_config_title_fns[i] check = section_frame( self, inner_frame, title_fns, sub_fns ) check.grid(row=i, column=0, sticky=N + W) inner_frame.update_idletasks() frame_canvas.config(width=self.windows_size[0] - 20, height=self.windows_size[1] - 350) canvas.config(width=self.windows_size[0] - 20, height=self.windows_size[1] - 350, scrollregion=canvas.bbox("all")) return frame_canvas
def initUI(self): self.dir_name = "" os.chdir(r"C:\Users\Csullivan\Documents\AutoCAD Publish") self.master.title("Cable Label Print Utility") Style().configure("TButton", padding=(3, 5, 3, 5), font='serif 10') self.columnconfigure(0, pad=3) self.rowconfigure(0, pad=3) grp = LabelFrame(self.master, text="Print to Brady printer from CSV or XML") grp.grid(row=0, column=0) grp.config(padx=50, pady=20) grp2 = LabelFrame(self.master, text="Print directly from XML") grp2.grid(row=1, column=0) grp2.config(padx=50, pady=20) self.lbls_csv = StringVar() self.lbls_csv.set(r".\sample.txt") self.lbls_xml = StringVar() self.lbls_xml.set(r".\sample.xml") # Choose file buttons btn_csv_file = Button(grp, text="Choose CSV File", command=self.choose_csv_file) btn_csv_file.grid(row=0, column=0) label_csv = Label(grp, textvariable=self.lbls_csv, width=40) label_csv.grid(row=0, column=1) btn_print_all = Button(grp, text="Print All", command=self.print_xml_files) btn_print_all.grid(row=1, column=0) #label_xml = Label(grp, textvariable = self.lbls_xml, width=40) #label_xml.grid(row=1, column=1) btn_xml_file = Button(grp2, text="Print XML File", command=self.print_xml_file) btn_xml_file.grid(row=0, column=0) self.lstbx_log = Listbox(grp, selectmode="extended") self.lstbx_log.grid(row=0, column=2)
class FormChildSection: def __init__(self, frm_parent, connection): self.connection = connection self.directive = Message() self.decide = True self.id_selected = 0 self.frm_child_list = LabelFrame(frm_parent) self.frm_child_crud = LabelFrame(frm_parent) self.frm_child_crud.config(fg=TEXT_COLOR, font=SUBTITLE_FONT) self.initialize_components() def initialize_components(self): """ Method that initialize the visual components for each form associated with the local administration """ # Resources for the Forms self.new_icon = PhotoImage(file=r"./Resources/create.png") self.view_icon = PhotoImage(file=r"./Resources/view.png") self.modify_icon = PhotoImage(file=r"./Resources/modify.png") self.remove_icon = PhotoImage(file=r"./Resources/delete.png") self.save_icon = PhotoImage(file=r"./Resources/save.png") self.cancel_icon = PhotoImage(file=r"./Resources/cancel.png") self.back_icon = PhotoImage(file=r"./Resources/back.png") # Components for List FRM lbl_sep1 = Label(self.frm_child_list) lbl_sep1.grid(row=0, column=0, padx=10, pady=25) self.trv_available = Treeview(self.frm_child_list, height=15, columns=('N', 'Name', 'Description', 'Data Type')) self.trv_available.heading('#0', text='ID', anchor=CENTER) self.trv_available.heading('#1', text='N', anchor=CENTER) self.trv_available.heading('#2', text='Name', anchor=CENTER) self.trv_available.heading('#3', text='Description', anchor=CENTER) self.trv_available.heading('#4', text='Data Type', anchor=CENTER) self.trv_available.column('#0', width=0, minwidth=50, stretch=NO) self.trv_available.column('#1', width=20, minwidth=20, stretch=NO) self.trv_available.column('#2', width=200, minwidth=200, stretch=NO) self.trv_available.column('#3', width=400, minwidth=400, stretch=NO) self.trv_available.column('#4', width=200, minwidth=200, stretch=NO) self.trv_available.grid(row=0, column=1, sticky=W, pady=25) vsb_trv_av = Scrollbar(self.frm_child_list, orient="vertical", command=self.trv_available.yview) vsb_trv_av.grid(row=0, column=2, pady=25, sticky=NS) self.trv_available.configure(yscrollcommand=vsb_trv_av.set) frm_aux4 = Frame(self.frm_child_list) btn_new = Button(frm_aux4, image=self.new_icon, command=self.click_new) btn_new.grid(row=0, column=0, pady=5, padx=5, sticky=E) btn_new_ttp = CreateToolTip(btn_new, 'New section') btn_view = Button(frm_aux4, image=self.view_icon, command=self.click_view) btn_view.grid(row=1, column=0, pady=5, padx=5, sticky=E) btn_view_ttp = CreateToolTip(btn_view, 'View section') btn_edit = Button(frm_aux4, image=self.modify_icon, command=self.click_update) btn_edit.grid(row=2, column=0, pady=5, padx=5, sticky=E) btn_edit_ttp = CreateToolTip(btn_edit, 'Edit section') btn_delete = Button(frm_aux4, image=self.remove_icon, command=self.click_delete) btn_delete.grid(row=3, column=0, pady=5, padx=5, sticky=E) btn_delete_ttp = CreateToolTip(btn_delete, 'Delete section') frm_aux4.grid(row=0, column=4, pady=25, padx=25, sticky=NW) # Components for CRUD FRM self.frm_aux1 = Frame(self.frm_child_crud) lbl_type = Label(self.frm_aux1, text='Data type*') lbl_type.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_type.grid(row=0, column=0, pady=10, padx=20, sticky=W) lbl_name = Label(self.frm_aux1, text='Name*') lbl_name.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_name.grid(row=1, column=0, pady=10, padx=20, sticky=W) lbl_description = Label(self.frm_aux1, text='Description*\t') lbl_description.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_description.grid(row=2, column=0, pady=10, padx=20, sticky=NW) self.cbx_data = Combobox(self.frm_aux1, state="readonly") self.cbx_data['values'] = ['Text', 'File', 'Classification'] self.cbx_data.grid(row=0, column=2, pady=10, sticky=W) self.cbx_data.bind("<<ComboboxSelected>>", self.cbx_data_selected) self.txt_name = Entry(self.frm_aux1, width=50, font=TEXT_FONT) self.txt_name.grid(row=1, column=2, pady=10, sticky=W) lbl_sep2 = Label(self.frm_aux1) lbl_sep2.grid(row=0, column=1, rowspan=3, padx=10, pady=10) self.txt_description = Text(self.frm_aux1, height=6, width=50, font=TEXT_FONT) self.txt_description.grid(row=2, column=2, pady=10, sticky=W) vsb_txt_desc = Scrollbar(self.frm_aux1, orient="vertical", command=self.txt_description.yview) vsb_txt_desc.grid(row=2, column=3, pady=10, sticky=NS) self.txt_description.configure(yscrollcommand=vsb_txt_desc.set) sep_aux1 = Separator(self.frm_aux1, orient=VERTICAL) sep_aux1.grid(row=0, column=4, sticky=NS, rowspan=4, padx=20) self.btn_save = Button(self.frm_aux1, image=self.save_icon, command=self.click_save) btn_save_ttp = CreateToolTip(self.btn_save, 'Save section') self.btn_back = Button(self.frm_aux1, image=self.back_icon, command=self.click_back) btn_back_ttp = CreateToolTip(self.btn_back, 'Go back') self.btn_cancel = Button(self.frm_aux1, image=self.cancel_icon, command=self.click_cancel) btn_cancel_ttp = CreateToolTip(self.btn_cancel, 'Cancel') self.frm_aux1.grid() # Frame for showing available classifications self.frm_aux2 = Frame(self.frm_aux1) lbl_class = Label(self.frm_aux2, text='Classification\t') lbl_class.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_class.grid(row=0, column=0, pady=10, padx=20, sticky=W) lbl_category = Label(self.frm_aux2, text='Categories') lbl_category.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_category.grid(row=1, column=0, pady=10, padx=20, sticky=NW) lbl_sep3 = Label(self.frm_aux2) lbl_sep3.grid(row=0, column=1, rowspan=2, padx=10, pady=10) self.cbx_classification = Combobox(self.frm_aux2, state="readonly") self.cbx_classification.bind("<<ComboboxSelected>>", self.cbx_class_selected) self.cbx_classification.grid(row=0, column=2, pady=10, sticky=NW) self.lbx_category = Listbox(self.frm_aux2, font=TEXT_FONT, height=10, width=50, selectmode='none') self.lbx_category.config(bg=DISABLED_COLOR) self.lbx_category.grid(row=1, column=2, pady=10, sticky=W) vsb_lbx_cat = Scrollbar(self.frm_aux2, orient="vertical", command=self.lbx_category.yview) vsb_lbx_cat.grid(row=1, column=3, pady=10, sticky=NS) self.lbx_category.configure(yscrollcommand=vsb_lbx_cat.set) def retrieve_list(self): # Remove existing elements in the list for item in self.trv_available.get_children(): self.trv_available.delete(item) self.directive = Message(action=32) self.connection = self.directive.send_directive(self.connection) # Adding elements into the list for index, item in enumerate(self.connection.message.information): elements = item.split('¥') self.trv_available.insert('', 'end', text=elements[0], values=(index + 1, summarize_text(elements[1], 200), summarize_text(elements[2], 400), summarize_text(elements[3], 200))) if len(self.trv_available.get_children()) != 0: self.trv_available.selection_set( self.trv_available.get_children()[0]) def show_frm(self): self.retrieve_list() self.frm_child_list.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def hide_frm(self): self.clear_fields() self.frm_child_list.grid_forget() self.frm_child_crud.grid_forget() def click_new(self): self.section = Section() self.txt_name.focus_set() self.frm_child_crud['text'] = 'New section' self.btn_save.grid(row=0, column=5, padx=20) self.btn_cancel.grid(row=1, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def click_view(self): if len(self.trv_available.selection()) == 1: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) self.directive = Message(action=35, information=[id_selected]) self.connection = self.directive.send_directive(self.connection) self.section = Section( section_id=id_selected, name=self.connection.message.information[0], description=self.connection.message.information[1], data_type=self.connection.message.information[2]) self.txt_name.insert(0, self.section.name) self.txt_description.insert('1.0', self.section.description) self.cbx_data.set(self.section.data_type) if self.section.data_type == 'Classification': self.section.classification_id = self.connection.message.information[ 3] self.retrieve_classifications() self.directive = Message( action=70, information=[self.section.classification_id]) self.connection = self.directive.send_directive( self.connection) self.cbx_classification.set( self.connection.message.information[0]) self.cbx_class_selected() self.frm_aux2.grid(row=3, column=0, columnspan=4, sticky=W) self.txt_name['bg'] = DISABLED_COLOR self.txt_description['bg'] = DISABLED_COLOR self.lbx_category['bg'] = DISABLED_COLOR self.txt_name['state'] = DISABLED self.txt_description['state'] = DISABLED self.cbx_data['state'] = DISABLED self.cbx_classification['state'] = DISABLED self.lbx_category['state'] = DISABLED self.frm_child_crud['text'] = 'View section' self.btn_back.grid(row=0, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_update(self): if len(self.trv_available.selection()) == 1: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) self.directive = Message(action=35, information=[id_selected, 'validate']) self.connection = self.directive.send_directive(self.connection) if self.connection.message.action == 5: # An error ocurred while trying to update the item messagebox.showerror( parent=self.frm_child_list, title='Can not update the item', message=self.connection.message.information[0]) else: self.section = Section( section_id=id_selected, name=self.connection.message.information[0], description=self.connection.message.information[1], data_type=self.connection.message.information[2]) self.txt_name.insert(0, self.section.name) self.txt_description.insert('1.0', self.section.description) self.cbx_data.set(self.section.data_type) if self.section.data_type == 'Classification': self.section.classification_id = self.connection.message.information[ 3] self.retrieve_classifications() self.directive = Message( action=70, information=[self.section.classification_id]) self.connection = self.directive.send_directive( self.connection) self.cbx_classification.set( self.connection.message.information[0]) self.cbx_class_selected() self.frm_aux2.grid(row=3, column=0, columnspan=4, sticky=W) self.frm_child_crud['text'] = 'Update section' self.btn_save.grid(row=0, column=5, padx=20) self.btn_cancel.grid(row=1, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_delete(self): if len(self.trv_available.selection()) == 1: decision = messagebox.askyesno( parent=self.frm_child_list, title='Confirmation', message='Are you sure you want to delete the item?') if decision: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) self.directive = Message(action=34, information=[id_selected]) self.connection = self.directive.send_directive( self.connection) if self.connection.message.action == 5: # An error ocurred while deleting the item messagebox.showerror( parent=self.frm_child_list, title='Can not delete the item', message=self.connection.message.information[0]) else: self.retrieve_list() else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_save(self): if self.validate_fields(): self.section.name = self.txt_name.get() self.section.description = self.txt_description.get( '1.0', 'end-1c') self.section.data_type = self.cbx_data.get() if self.section.section_id == 0: # If creating a section if self.section.data_type == 'Classification': id_class = self.classifications[ self.cbx_classification.current()] self.directive = Message(action=31, information=[ self.section.name, self.section.description, self.section.data_type, id_class ]) else: self.directive = Message(action=31, information=[ self.section.name, self.section.description, self.section.data_type ]) else: # If updating a section if self.section.data_type == 'Classification': id_class = self.classifications[ self.cbx_classification.current()] self.directive = Message(action=33, information=[ self.section.section_id, self.section.name, self.section.description, self.section.data_type, id_class ]) else: self.directive = Message(action=33, information=[ self.section.section_id, self.section.name, self.section.description, self.section.data_type ]) self.connection = self.directive.send_directive(self.connection) self.click_back() def click_back(self): self.clear_fields() self.frm_child_crud.grid_forget() self.show_frm() def click_cancel(self): decision = True if self.txt_name.get() != self.section.name or \ self.txt_description.get('1.0', 'end-1c') != self.section.description or \ self.cbx_data.get() != self.section.data_type: decision = messagebox.askyesno( parent=self.frm_child_crud, title='Cancel', message='Are you sure you want to cancel?') if decision: self.click_back() def cbx_data_selected(self, event): if self.cbx_data.get() == 'Classification': self.retrieve_classifications() self.frm_aux2.grid(row=3, column=0, columnspan=4, sticky=W) else: self.frm_aux2.grid_forget() self.txt_name.focus_set() def cbx_class_selected(self, event=None): id_class = self.classifications[self.cbx_classification.current()] self.directive = Message(action=72, information=[id_class]) self.connection = self.directive.send_directive(self.connection) self.lbx_category.delete(0, END) for index, item in enumerate(self.connection.message.information): item = item.split('¥') self.lbx_category.insert(END, '{}) {}'.format(index + 1, item[1])) def retrieve_classifications(self): self.classifications = [] self.lbx_category.delete(0, END) self.directive = Message(action=67) self.connection = self.directive.send_directive(self.connection) classifications = [] for item in self.connection.message.information: elements = item.split('¥') classifications.append(elements[1]) self.classifications.append(int(elements[0])) self.cbx_classification['values'] = [] self.cbx_classification['values'] = classifications def validate_fields(self): if len(self.txt_name.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert a name for the section') return False if len(self.txt_description.get('1.0', 'end-1c')) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert a description for the section') return False if len(self.cbx_data.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must select data type for the section') return False if self.cbx_data.get() == 'Classification' and len( self.cbx_classification.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must select a classification for this section') return False return True def clear_fields(self): self.btn_save.grid_forget() self.btn_cancel.grid_forget() self.btn_back.grid_forget() self.txt_name['state'] = NORMAL self.txt_description['state'] = NORMAL self.cbx_data['state'] = NORMAL self.cbx_classification['state'] = NORMAL self.lbx_category['state'] = NORMAL self.txt_name['bg'] = ENABLED_COLOR self.txt_description['bg'] = ENABLED_COLOR self.lbx_category['bg'] = ENABLED_COLOR self.txt_name.delete(0, END) self.txt_description.delete('1.0', 'end-1c') self.cbx_data.set('') self.cbx_classification.set('') self.lbx_category.delete(0, END) self.frm_aux2.grid_forget()
write_entry_header('w') web.open('diary.txt') msg_box() open_diary() # Comment out this line if you want scheduler only. schedule.every().day.at("23:59").do(open_diary) while True: schedule.run_pending() time.sleep(1) break main_frame = LabelFrame(root, fg='white', text='Choose your option') main_frame.grid(padx=10, pady=10) main_frame.config(background='black') tempmail_btn = Button(main_frame, bg='white', text='Create Your Temp..Email', command=Tempmal) tempmail_btn.grid(pady=10, padx=10, row=1, column=0) diary_btn = Button(main_frame, bg='white', text='Make Your Midnight diary ', command=tmd) diary_btn.grid(pady=10, padx=10, row=1, column=2) exit_btn1 = Button(main_frame, bg='ivory',
class App: #----------------------------------------------------------------------------------- def ShowListFrame(self): self.listFrame.pack(fill=BOTH, side=TOP, padx=10, pady=0, expand=1) self.frameBottom.pack(fill=X, side=TOP, padx=10, pady=5, expand=0) #----------------------------------------------------------------------------------- def HideListFrame(self): self.listFrame.pack_forget() self.frameBottom.pack_forget() #----------------------------------------------------------------------------------- def PopulateListWithLinks(self): self.links = self.PowerPointApp.GetLinksFromSlides( int(self.root.winfo_x()) + int(self.root.winfo_width() / 2), int(self.root.winfo_y()) + int(self.root.winfo_height() / 2)) #print('back to index') if len(self.links) != 0: for item in self.links: #print(dict(item)) self.listbox.insert(END, str(item['link'])) #print('filled list') self.frameTopLabelSrc.config(text=self.PowerPointApp.FileName, ) #print('changed name') self.frameTopButtonFileOpen.config(text='Close file', command=self.ClosePPT) self.ShowListFrame() #print('end populate') #----------------------------------------------------------------------------------- def ReplaceSelected(self): for item in self.listbox.curselection(): text = self.listbox.get(item) text = text.replace(self.frameBottomFromInput.get(), self.frameBottomToInput.get()) #print(self.listbox.get(item), text) self.listbox.delete(item) self.listbox.insert(item, text) self.links[item]['link'] = text self.listbox.update() self.PowerPointApp.SetLinksInSlides( self.links, int(self.root.winfo_x()) + int(self.root.winfo_width() / 2), int(self.root.winfo_y()) + int(self.root.winfo_height() / 2)) #----------------------------------------------------------------------------------- def ClosePPT(self): if self.PowerPointApp.FileName != "": self.PowerPointApp.Close() self.listbox.delete(0, END) #print("Deleted list") self.frameTopLabelSrc.config(text='No file have been choosen') self.frameTopButtonFileOpen.config(text='Choose File', command=self.PopulateListWithLinks) self.HideListFrame() #print("Reset File Name") #----------------------------------------------------------------------------------- def ExitApp(self): if messagebox.askokcancel( title="Quit", message= "This action will close the powerpoint file and exit the program. Do you want to quit now?", parent=self.root): if self.PowerPointApp.FileName != "": self.PowerPointApp.Close() #print("Closed powerpoint") del self.frameBottomButton del self.frameBottomFromInput del self.frameBottomFromLabel del self.frameBottomToInput del self.frameBottomToLabel del self.frameBottom del self.frameTopLabelSrc del self.frameTopButtonFileOpen del self.frameTop del self.scrollbar del self.listbox del self.listFrame self.root.destroy() del self.root #print('Exiting now') return True #print('Didn\'t exit') #----------------------------------------------------------------------------------- def monitor_changes(self): registry = ConnectRegistry(None, HKEY_CURRENT_USER) key = OpenKey( registry, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize') mode = QueryValueEx(key, "AppsUseLightTheme") cnf = { 'mainWindow': { 'light': { 'bg': '#ddd' }, 'dark': { 'bg': '#0A2342' } }, 'frame': { 'light': { 'bg': '#ddd', 'fg': '#006ADF' }, 'dark': { 'bg': '#0A2342', 'fg': '#E8E6E1' } }, 'scrollbar': { 'light': { 'width': 12, 'elementborderwidth': 5 }, 'dark': { 'width': 12, 'elementborderwidth': 5 } }, 'label': { 'light': { 'bg': '#ddd', 'fg': '#000' }, 'dark': { 'bg': '#0A2342', 'fg': '#fff' } }, 'input': { 'light': { 'bg': '#EEEEEE', 'fg': '#212121' }, 'dark': { 'bg': '#798797', 'fg': '#FAFAFA' } }, 'button': { 'light': { 'bg': '#006ADF', 'fg': '#fff' }, 'dark': { 'bg': '#006ADF', 'fg': '#fff' } }, 'list': { 'light': { 'bg': '#ccc', 'fg': '#000', 'selectbackground': '#FF0056', 'selectforeground': '#FFFFFF' }, 'dark': { 'bg': '#07172A', 'fg': '#E8E6E1', 'selectbackground': '#A30037', 'selectforeground': '#FFFFFF' } } } if (self.root['bg'] != '#ddd' and mode[0]) or (self.root['bg'] != '#0A2342' and mode[0] == False): theme = 'light' if mode[0] else 'dark' color = cnf['mainWindow']['light'] if mode[0] else cnf[ 'mainWindow']['dark'] self.root.config(color) self.mainWindow.config(color) self.frameBottomGet.config(color) color = cnf['frame'][theme] self.frameBottom.config(color) self.frameTop.config(color) color = cnf['list'][theme] self.listbox.config(color) color = cnf['scrollbar'][theme] self.scrollbar.config(color) color = cnf['label'][theme] self.frameBottomToLabel.config(color) self.frameBottomFromLabel.config(color) self.frameTopLabelSrc.config(color) color = cnf['input'][theme] self.frameBottomFromInput.config(color) self.frameBottomToInput.config(color) color = cnf['button'][theme] self.frameTopButtonFileOpen.config(color) self.frameBottomButton.config(color) if len(self.listbox.curselection()) >= 1 and len( self.frameBottomFromInput.get()) > 0: self.frameBottomButton.config(state='normal') else: self.frameBottomButton.config(state=DISABLED) self.root.after(1000, self.monitor_changes) #----------------------------------------------------------------------------------- def __init__(self): # Initialize app container self.cnf = { 'font': { 'font': ('Inter', '9', 'bold') }, } self.root = Tk() self.root.title("Powerpoint Presentations Link Updater") self.root.geometry('650x350') self.root.minsize(650, 325) self.root.iconbitmap(r'.\trendence_black.ico') self.PowerPointApp = OfficeApp("PowerPoint.Application") self.FileName = 'No file have been choosen yet' # Create Main Window self.mainWindow = Frame(self.root) self.mainWindow.pack_propagate(0) self.mainWindow.pack(fill=BOTH, expand=1, side=LEFT, pady=5) self.mainWindow.grid_rowconfigure(0, weight=1) self.mainWindow.grid_columnconfigure(0, weight=1) # Links listbox self.listFrame = Frame(self.mainWindow) self.listbox = Listbox(self.listFrame) self.listbox.pack(expand=1, fill=BOTH, side=LEFT) self.scrollbar = Scrollbar(self.listFrame) self.scrollbar.pack(fill=Y, side=LEFT) self.scrollbar.config(command=self.listbox.yview) self.listbox.config(selectmode=EXTENDED, exportselection=False, highlightthickness=0, yscrollcommand=self.scrollbar.set) self.listbox.config(self.cnf['font']) # File Frame self.frameTop = LabelFrame(self.mainWindow, text='Choose File') self.frameTopButtonFileOpen = Button(self.frameTop) self.frameTopButtonFileOpen.grid(in_=self.frameTop, column=0, row=0, padx=10, pady=5) self.frameTopLabelSrc = Label(self.frameTop) self.frameTopLabelSrc.grid(column=1, row=0, padx=10, pady=5) self.frameTopLabelSrc.config({'text': self.FileName}) self.frameTopLabelSrc.config(self.cnf['font']) # Find and Replace Frame self.frameBottom = LabelFrame(self.mainWindow, text='Selected Links') self.frameBottomGet = Frame(self.frameBottom) self.frameBottomGet.pack(fill=X, side=TOP, padx=10, pady=0, expand=1) self.frameBottomFromLabel = Label(self.frameBottomGet, text='Replace') self.frameBottomFromLabel.pack(side=LEFT, padx=0, pady=0) self.frameBottomFromLabel.config(self.cnf['font']) self.frameBottomFromInput = Entry(self.frameBottomGet) self.frameBottomFromInput.pack(side=LEFT, fill=X, padx=0, pady=0, expand=1) self.frameBottomFromInput.config(self.cnf['font']) self.frameBottomToLabel = Label(self.frameBottomGet, text='With ') self.frameBottomToLabel.pack(side=LEFT, padx=0, pady=0) self.frameBottomToLabel.config(self.cnf['font']) self.frameBottomToInput = Entry(self.frameBottomGet) self.frameBottomToInput.pack(side=LEFT, fill=X, padx=0, pady=0, expand=1) self.frameBottomToInput.config(self.cnf['font']) self.frameBottomButton = Button(self.frameBottom) self.frameBottomButton.pack(fill=X, side=TOP, padx=10, pady=5, expand=1) self.frameBottomButton.config(text='Replace Selected', command=self.ReplaceSelected, height=1) self.frameBottomButton.config(self.cnf['font']) self.frameTop.pack(fill=X, side=TOP, padx=10, pady=5) self.frameTop.config(height=50) self.frameTop.config(self.cnf['font']) self.frameBottom.config(self.cnf['font']) self.frameTopButtonFileOpen.config(text='Choose a PowerPoint file', command=self.PopulateListWithLinks) self.frameTopButtonFileOpen.config(self.cnf['font']) self.root.protocol("WM_DELETE_WINDOW", self.ExitApp) self.monitor_changes() self.root.mainloop()
class ConfigurationWindow: clusterName = "CLUSTER_NAME" zookeeperHost = "ZOOKEEPER_HOST" zookeeperPort = "ZOOKEEPER_PORT" def __init__(self): self.cluster_name = None self.zookeeper_host = None self.zookeeper_port = None self.kafka_window = None self.frame = Frame() self.frame.config(padx=10, pady=10) self.frame.grid(row=0, column=0, sticky="wn") self.cluster_frame = LabelFrame(self.frame, text="Clusters") self.cluster_frame.config(font=("Arial", 14), padx=10, pady=10) self.cluster_frame.grid(row=1, column=0) self.list_clusters_frame() def save(self, old_cluster_name): if (old_cluster_name == ""): insert_configuration(self.cluster_name.get(), self.zookeeper_host.get(), self.zookeeper_port.get()) else: update_configuration(self.cluster_name.get(), self.zookeeper_host.get(), self.zookeeper_port.get(), old_cluster_name) self.clean_frame(self.cluster_frame) self.list_clusters_frame() def delete(self, cluster_name): delete_configuration(cluster_name) self.clean_frame(self.cluster_frame) self.list_clusters_frame() def disconnect(self): self.clean_frame(self.cluster_frame) self.list_clusters_frame() self.kafka_window.destroy() def connect(self, cluster_name): self.clean_frame(self.cluster_frame) self.disconnect_cluster_frame(cluster_name) configuration = get_cluster(cluster_name) self.kafka_window = topic_list_window.KafkaWindow() self.kafka_window.open_window(configuration[0][1], configuration[0][2]) def settings(self, new_cluster_name=None): self.clean_frame(self.cluster_frame) cluster_name = "" cluster_host = "" cluster_port = "" if (new_cluster_name != None): configuration = get_cluster(new_cluster_name) cluster_name = configuration[0][0] cluster_host = configuration[0][1] cluster_port = configuration[0][2] # Cluster Name Fields Label(self.cluster_frame, text="Cluster Name").grid(row=0, column=0) self.cluster_name = Entry(self.cluster_frame, width=40) self.cluster_name.grid(row=0, column=1) self.cluster_name.insert('0', cluster_name) # Zookeeper Host Fields Label(self.cluster_frame, text="Zookeeper Host").grid(row=1, column=0) self.zookeeper_host = Entry(self.cluster_frame, width=40) self.zookeeper_host.grid(row=1, column=1) self.zookeeper_host.insert('0', cluster_host) # Zookeeper Port Fields Label(self.cluster_frame, text="Zookeeper Port").grid(row=2, column=0) self.zookeeper_port = Entry(self.cluster_frame, width=40) self.zookeeper_port.grid(row=2, column=1) self.zookeeper_port.insert('0', cluster_port) # Button Group Button(self.cluster_frame, text="Save & Close", command=lambda: self.save(cluster_name)).grid(row=3, column=1) def list_clusters_frame(self): configurations = get_all_clusters() connect_image = PhotoImage(file="resources/images/connect.gif") settings_image = PhotoImage(file="resources/images/settings.gif") delete_image = PhotoImage(file="resources/images/delete.gif") counter = 0 for configuration in configurations: configuration_cluster_name = configuration[0] cluster_name_label = Label(self.cluster_frame, text=configuration_cluster_name) cluster_name_label.config(font=("Arial", 12)) cluster_name_label.grid(row=counter, column=1) connect_button = Button(self.cluster_frame, text="connect", image=connect_image, command=partial( self.connect, configuration_cluster_name)) connect_button.image = connect_image connect_button.grid(row=counter, column=2) settings_button = Button(self.cluster_frame, text="settings", image=settings_image, command=partial( self.settings, configuration_cluster_name)) settings_button.image = settings_image settings_button.grid(row=counter, column=3) delete_button = Button(self.cluster_frame, text="delete", image=delete_image, command=partial(self.delete, configuration_cluster_name)) delete_button.image = delete_image delete_button.grid(row=counter, column=4) counter += 1 add_image = PhotoImage(file="resources/images/add.gif") add_button = Button(self.cluster_frame, text="add", image=add_image, command=lambda: self.settings()) add_button.image = add_image add_button.grid(row=counter, column=4, pady=10) def disconnect_cluster_frame(self, cluster_name): self.cluster_frame.pack_forget() disconnect_image = PhotoImage(file="resources/images/disconnect.gif") cluster_name_label = Label(self.cluster_frame, text=cluster_name) cluster_name_label.config(font=("Arial", 12)) cluster_name_label.grid(row=0, column=1) connect_button = Button(self.cluster_frame, text="disconnect", image=disconnect_image, command=lambda: self.disconnect()) connect_button.image = disconnect_image connect_button.grid(row=0, column=2) @staticmethod def clean_frame(frame): for widget in frame.winfo_children(): widget.destroy()
class GUI(Tk): 'Graphic user interface using Tkinter, main / root window' def __init__(self, root, worker): 'Generate object for main / root window.' self.root = root self.worker = worker ### "constants" for the gui ### if self.worker.storage.windows: self.JOBLISTLENGTH = 10 self.BUTTONWIDTH = 16 self.BIGENTRYWIDTH = 128 self.INTWIDTH = 6 self.TARGETWIDTH = 160 self.PADX = 8 self.PADY = 8 self.OPTPADX = 6 self.CHNGWIDTH = 144 self.CHNGHEIGHT = 12 self.MSGHEIGHT = 8 else: self.JOBLISTLENGTH = 10 self.BUTTONWIDTH = 16 self.BIGENTRYWIDTH = 96 self.INTWIDTH = 6 self.TARGETWIDTH = 120 self.PADX = 8 self.PADY = 8 self.OPTPADX = 6 self.CHNGWIDTH = 128 self.CHNGHEIGHT = 14 self.MSGHEIGHT = 8 ############################### self.__close2quit__() # handle closing of root window self.jobs = [] # start with empty list for the jobs self.root.title('Social Media Downloader') # window title for somedo self.__set_icon__( self.root) # give the window manager an application icon frame_jobs = LabelFrame( self.root, text=' \u25a4 Jobs ' ) # in this tk-frame the jobs will be displayed frame_jobs.pack(fill=X, expand=True, padx=self.PADX, pady=self.PADY) frame_jobs_inner = Frame(frame_jobs) frame_jobs_inner.pack(fill=X, expand=True, padx=self.PADX, pady=self.PADY) self.tk_jobbuttons = [] self.jobbuttons = [] self.upbuttons = [] self.downbuttons = [] for i in range(self.JOBLISTLENGTH): frame_row = Frame(frame_jobs_inner) frame_row.pack(fill=X, expand=True) self.tk_jobbuttons.append(StringVar(frame_row)) self.jobbuttons.append( Button(frame_row, textvariable=self.tk_jobbuttons[i], anchor=W, command=partial(self.__job_edit__, i))) self.jobbuttons[i].pack(side=LEFT, fill=X, expand=True) self.upbuttons.append( Button(frame_row, text='\u2191', command=partial(self.__job_up__, i))) self.upbuttons[i].pack(side=LEFT) self.downbuttons.append( Button(frame_row, text='\u2193', command=partial(self.__job_down__, i))) self.downbuttons[i].pack(side=LEFT) self.colour_fg = self.jobbuttons[0].cget('fg') self.colour_bg = self.jobbuttons[0].cget('bg') frame_row = Frame(frame_jobs_inner) frame_row.pack(fill=BOTH, expand=True) self.startbutton = Button(frame_row, text="\u25b9 Start jobs", width=self.BUTTONWIDTH, command=self.__start__) self.startbutton.pack(side=LEFT, pady=self.PADY) Label(frame_row, text=' ').pack(side=LEFT) self.stopbutton = Button(frame_row, text="\u25ad Stop / Abort", width=self.BUTTONWIDTH, state=DISABLED, command=self.__stop__) self.stopbutton.pack(side=LEFT, padx=self.PADX, pady=self.PADY) self.purgebutton = Button(frame_row, text='\u2672 Purge job list', width=self.BUTTONWIDTH, command=self.__purge_jobs__) self.purgebutton.pack(side=RIGHT, pady=self.PADY) frame_row = LabelFrame(self.root, text=' + Add Job ') # add job frame frame_row.pack(fill=X, expand=True, padx=self.PADX, pady=self.PADY) self.modulebuttons = dict() for i in self.worker.modulenames: # generate buttons for the modules self.modulebuttons[i] = Button(frame_row, text='\u271a %s' % i, font='bold', height=3, command=partial( self.__new_job__, i)) self.modulebuttons[i].pack(side=LEFT, fill=BOTH, expand=True, padx=self.PADX, pady=self.PADY) self.frame_changeling = LabelFrame( self.root) # frame for configuration or messages self.frame_changeling.pack(fill=X, expand=True, padx=self.PADX, pady=self.PADY) self.frame_messages = Frame(self.frame_changeling) # message frame self.text_messages = scrolledtext.ScrolledText(self.frame_messages, padx=self.PADX, pady=self.PADY, height=self.MSGHEIGHT) self.text_messages.pack(fill=BOTH, expand=True, padx=self.PADX, pady=self.PADY) self.text_messages.bind("<Key>", lambda e: "break") self.worker.logger.addHandler(GUILogHandler( self.text_messages)) # give tk loghandler to worker self.frame_config = Frame(self.frame_changeling) # config frame nb_config = ttk.Notebook( self.frame_config) # here is the tk-notebook for the modules nb_config.pack(padx=self.PADX, pady=self.PADY) frame_nb = ttk.Frame(nb_config) nb_config.add(frame_nb, text='General') frame_row = Frame(frame_nb) frame_row.pack(fill=BOTH, expand=True) Label(frame_row, text='Output directory:', anchor=E, width=self.BUTTONWIDTH).pack(side=LEFT, padx=self.PADX) self.tk_outdir = StringVar(frame_row, self.worker.storage.outdir) self.tk_outdir_entry = Entry(frame_row, textvariable=self.tk_outdir, width=self.BIGENTRYWIDTH) self.tk_outdir_entry.pack(side=LEFT) Button(frame_row, text='...', command=self.__output_dir__).pack(side=LEFT, padx=self.PADX, pady=self.PADY) frame_row = Frame(frame_nb) frame_row.pack(fill=BOTH, expand=True) Label(frame_row, text='Chrome path:', anchor=E, width=self.BUTTONWIDTH).pack(side=LEFT, padx=self.PADX, pady=self.PADY) self.tk_chrome = StringVar(frame_row, self.worker.chrome.path) self.tk_chrome_entry = Entry(frame_row, textvariable=self.tk_chrome, width=self.BIGENTRYWIDTH) self.tk_chrome_entry.pack(side=LEFT) Button(frame_row, text='...', command=self.__chrome__).pack(side=LEFT, padx=self.PADX) self.tk_logins = dict() # login credentials self.tk_login_entries = dict() for i in self.worker.MODULES: # notebook tabs for the module configuration if i['login'] != None: frame_nb = ttk.Frame(nb_config) nb_config.add(frame_nb, text=i['name']) self.tk_logins[i['name']], self.tk_login_entries[ i['name']] = self.__login_frame__( frame_nb, i['name'], self.worker.logins[i['name']]) frame_row = Frame(self.frame_config) frame_row.pack(side=LEFT, anchor=N) Button(frame_row, text="\u2912 Save configuration", width=self.BUTTONWIDTH, command=self.__save_config__).pack(side=LEFT, padx=self.PADX, pady=self.PADY) Button(frame_row, text="\u2913 Load configuration", width=self.BUTTONWIDTH, command=self.__load_config__).pack(side=LEFT, padx=self.PADX, pady=self.PADY) Label(self.frame_changeling, width=self.CHNGWIDTH).grid(row=1, column=0) Label(self.frame_changeling, height=self.CHNGHEIGHT).grid(row=0, column=1) frame_row = LabelFrame(self.root, text=' \u2191\u2193 ') frame_row.pack(fill=X, expand=True, padx=self.PADX, pady=self.PADY) self.button_toggle = Button(frame_row, command=self.__toggle_config__, width=self.BUTTONWIDTH) self.button_toggle.pack(side=LEFT, padx=self.PADX, pady=self.PADY) self.button_clear = Button(frame_row, text='\u2610 Clear messages', command=self.__clear_messages__, width=self.BUTTONWIDTH) self.button_clear.pack(side=LEFT, padx=self.PADX, pady=self.PADY) self.__enable_config__() frame_row = Frame(self.root) frame_row.pack(fill=X, expand=True) for i in ('README.md', 'README.txt', 'README.md.txt', 'README'): try: with open(self.worker.storage.rootdir + self.worker.storage.slash + i, 'r', encoding='utf-8') as f: self.about_help = f.read() Button(frame_row, text="\u2370 About / Help", width=self.BUTTONWIDTH, command=self.__help__).pack(side=LEFT, padx=self.PADX, pady=self.PADY) break except: continue self.quitbutton = Button(frame_row, text="\u2297 Quit", width=self.BUTTONWIDTH, command=self.__quit__) self.quitbutton.pack(side=RIGHT, padx=self.PADX, pady=self.PADY) def __set_icon__(self, master): 'Try to Somedo icon for the window' try: master.call( 'wm', 'iconphoto', master._w, PhotoImage( file='%s%ssomedo.png' % (self.worker.storage.icondir, self.worker.storage.slash))) except: pass def __quit__(self): 'Close the app' if messagebox.askyesno('Quit', 'Close this Application?'): self.__terminate__() def __close2quit__(self): 'Ask to quit on close windows by "X"' self.root.protocol("WM_DELETE_WINDOW", self.__quit__) def __close2stop__(self): 'Ask to stop job(s) on close windows by "X"' self.root.protocol("WM_DELETE_WINDOW", self.__stop__) def __close2kill__(self): 'Ask to kill Somedo immediatly on close windows by "X"' self.root.protocol("WM_DELETE_WINDOW", self.__kill__) def __login_frame__(self, frame, module, login): 'Create Tk Frame for login credentials' tk_login = dict() tk_login_entry = dict() for i in login: frame_row = Frame(frame) frame_row.pack(fill=BOTH, expand=True) Label(frame_row, text=i, anchor=E, padx=self.PADX, width=self.BUTTONWIDTH).pack(side=LEFT) tk_login[i] = StringVar(frame_row) if self.worker.logins[module] != None: tk_login[i].set(login[i]) tk_login_entry[i] = Entry(frame_row, textvariable=tk_login[i], show='*', width=self.BIGENTRYWIDTH) tk_login_entry[i].pack(side=LEFT) tk_hide = BooleanVar(frame_row, True) Checkbutton(frame_row, text='hide', variable=tk_hide, command=partial(self.__hide_entry__, tk_login_entry[i], tk_hide)).pack(side=LEFT) return tk_login, tk_login_entry def __hide_entry__(self, entry, check): 'Toggle hidden login credentials' if check.get(): entry.config(show='*') else: entry.config(show='') def __job_dialog__(self, job, row): 'Open window to edit a job' self.__disable_jobbuttons__() self.job_dialog_root.title(job['module']) frame_row = LabelFrame(self.job_dialog_root, text=' \u229a Target(s) ') frame_row.pack(fill=BOTH, expand=True, padx=self.PADX, pady=self.PADY) tk_job = { 'module': job['module'], 'target': StringVar(frame_row, job['target']) } # tk variables for the job configuration tk_target_entry = Entry(frame_row, textvariable=tk_job['target'], width=self.TARGETWIDTH) tk_target_entry.pack(side=LEFT, padx=self.PADX, pady=self.PADY) tk_job['options'] = dict() # tk variables for the options if job['options'] != None: frame_grid = LabelFrame(self.job_dialog_root, text=' \u2714 Options ') frame_grid.pack(fill=BOTH, expand=True, padx=self.PADX, pady=self.PADY) for i in self.worker.options[job['module']]: definition = self.worker.options[job['module']][i] value = job['options'][i] Label(frame_grid, text=definition['name']).grid( row=definition['row'], column=definition['column'] * 2, sticky=E, pady=self.PADY) if isinstance(value, bool): # checkbutton for boolean tk_job['options'][i] = BooleanVar(frame_grid, value) Checkbutton(frame_grid, variable=tk_job['options'][i]).grid( row=definition['row'], column=definition['column'] * 2 + 1, sticky=W) width = 0 elif isinstance(value, int): # integer tk_job['options'][i] = IntVar(frame_grid, value) width = self.INTWIDTH elif isinstance(value, str): # string tk_job['options'][i] = StringVar(frame_grid, value) width = self.BUTTONWIDTH if width != 0: Entry(frame_grid, textvariable=tk_job['options'][i], width=width).grid(row=definition['row'], column=definition['column'] * 2 + 1, sticky=W, padx=self.OPTPADX) if job['login'] != None: frame_login = LabelFrame(self.job_dialog_root, text=' \u2737 Login') frame_login.pack(fill=BOTH, expand=True, padx=self.PADX, pady=self.PADY) tk_job['login'], dummy = self.__login_frame__( frame_login, job['module'], job['login']) frame_row = Frame(self.job_dialog_root) frame_row.pack(fill=BOTH, expand=True) if row == len(self.jobs): Button(frame_row, text="Add job", width=self.BUTTONWIDTH, command=partial(self.__add_job__, tk_job)).pack(side=LEFT, padx=self.PADX, pady=self.PADY) else: Button(frame_row, text="Update job", width=self.BUTTONWIDTH, command=partial(self.__update_job__, tk_job, row)).pack(side=LEFT, padx=self.PADX, pady=self.PADY) Button(frame_row, text="Remove job", width=self.BUTTONWIDTH, command=partial(self.__remove_job__, row)).pack(side=LEFT, padx=self.PADX, pady=self.PADY) Button(frame_row, text="Quit, do nothing", width=self.BUTTONWIDTH, command=self.__quit_job_dialog__).pack(side=RIGHT, padx=self.PADX, pady=self.PADY) def __quit_job_dialog__(self): 'Close the job configuration window' self.job_dialog_root.destroy() self.__enable_jobbuttons__() def __get_login__(self, module): 'Get login credentials for a module from root window' if self.worker.logins[module] == None: return None return { i: self.tk_logins[module][i].get() for i in self.worker.logins[module] } def __new_job__(self, module): 'Create new job to add to job list' if len(self.jobs ) == self.JOBLISTLENGTH - 1: # check if free space in job list return job = self.worker.new_job(module) if self.worker.logins[module] != None: job['login'] = self.__get_login__(module) self.job_dialog_root = Tk() self.__job_dialog__(job, len(self.jobs)) def __job_edit__(self, row): 'Edit or remove jobin job list' if row >= len(self.jobs): return self.job_dialog_root = Tk() self.__job_dialog__(self.jobs[row], row) def __tk2job__(self, tk_job): 'Get Tk values for a job' job = { 'module': tk_job['module'], 'target': tk_job['target'].get(), 'options': {i: tk_job['options'][i].get() for i in tk_job['options']} } try: job['login'] = { i: tk_job['login'][i].get() for i in tk_job['login'] } except: job['login'] = None return job def __add_job__(self, tk_job): 'Add job to list' if tk_job['target'].get() == '': # no target, no job return self.job_dialog_root.destroy() self.__enable_jobbuttons__() self.jobs.append(self.__tk2job__(tk_job)) self.__update_joblist__() def __update_job__(self, tk_job, row): 'Update job in list' if tk_job['target'].get() == '': # no target, no job return self.job_dialog_root.destroy() self.__enable_jobbuttons__() self.jobs[row] = self.__tk2job__(tk_job) self.__update_joblist__() def __purge_jobs__(self): 'Purge job list' if len(self.jobs) < 1: return if messagebox.askyesno('Purge job list', 'Are you sure to remove all jobs fromk list?'): self.jobs = [] self.__update_joblist__() def __job_text__(self, row): 'Generate string for one job button' if row >= len(self.jobs): return '' return '%s - %s' % (self.jobs[row]['module'], self.jobs[row]['target']) def __update_joblist__(self): 'Update the list of jobs' for i in range(self.JOBLISTLENGTH): self.tk_jobbuttons[i].set(self.__job_text__(i)) def __job_up__(self, row): 'Move job up in list' if row > 0: self.jobs[row], self.jobs[row - 1] = self.jobs[row - 1], self.jobs[row] self.__update_joblist__() def __job_down__(self, row): 'Move job down in list' if row < (len(self.jobs) - 1): self.jobs[row], self.jobs[row + 1] = self.jobs[row + 1], self.jobs[row] self.__update_joblist__() def __remove_job__(self, row): 'Remove job from list' if messagebox.askyesno('Remove job', 'Are you sure?'): self.job_dialog_root.destroy() self.__enable_jobbuttons__() self.jobs.pop(row) self.__update_joblist__() def __output_dir__(self): 'Set path to output directory.' path = filedialog.askdirectory(initialdir="~/", title='Destination directory') if path != (): self.tk_outdir_entry.delete(0, END) self.tk_outdir_entry.insert(0, path) self.worker.storage.outdir = path def __chrome__(self): 'Set path to chrome.' path = filedialog.askopenfilename(title='chrome', filetypes=[('All files', '*.*')]) if path != () and path != '': self.tk_chrome_entry.delete(0, END) self.tk_chrome_entry.insert(0, path) self.worker.chrome.path = path def __save_config__(self): 'Save configuration to file.' path = filedialog.asksaveasfilename(title='Configuration file', filetypes=[ ('Somedo configuration files', '*.smdc') ]) if path[-5:] != '.smdc': path += '.smdc' try: self.worker.storage.json_dump( { 'Output': self.tk_outdir.get(), 'Chrome': self.tk_chrome.get(), 'Modules': { i: self.__get_login__(i) for i in self.worker.modulenames if self.worker.logins[i] != None } }, path) except: messagebox.showerror('Error', 'Could not save configuration file') def __load_config__(self): 'Load configuration from file.' path = filedialog.askopenfilename(title='Configuration file', filetypes=[ ('Somedo configuration files', '*.smdc'), ('All files', '*.*') ]) if path != () and path != '': try: config = self.worker.storage.json_load(path) except: messagebox.showerror('Error', 'Could not load configuration file') return try: self.tk_outdir_entry.delete(0, END) self.tk_outdir_entry.insert(0, config['Output']) self.worker.storage.outdir = config['Output'] self.tk_chrome_entry.delete(0, END) self.tk_chrome_entry.insert(0, config['Chrome']) self.worker.chrome.path = config['Chrome'] for i in config['Modules']: for j in config['Modules'][i]: self.tk_login_entries[i][j].delete(0, END) self.tk_login_entries[i][j].insert( 0, config['Modules'][i][j]) except: messagebox.showerror('Error', 'Could not decode configuration file') def __help__(self): 'Open window to show About / Help' help_win = Tk() help_win.wm_title('About / Help') text = scrolledtext.ScrolledText(help_win, padx=self.PADX, pady=self.PADY, width=self.TARGETWIDTH) text.bind("<Key>", lambda e: "break") text.insert(END, self.about_help) text.pack() Button(help_win, text="Close", width=self.BUTTONWIDTH, command=help_win.destroy).pack(padx=self.PADX, pady=self.PADY, side=RIGHT) def __disable_jobbuttons__(self): 'Disable the job related buttons except Abort' for i in range(self.JOBLISTLENGTH): self.jobbuttons[i].config(state=DISABLED) self.upbuttons[i].config(state=DISABLED) self.downbuttons[i].config(state=DISABLED) self.startbutton.config(state=DISABLED) self.purgebutton.config(state=DISABLED) for i in self.worker.modulenames: self.modulebuttons[i].config(state=DISABLED) def __enable_jobbuttons__(self): 'Enable the job related buttons except Abort' for i in range(self.JOBLISTLENGTH): self.jobbuttons[i].config(state='normal') self.upbuttons[i].config(state='normal') self.downbuttons[i].config(state='normal') self.startbutton.config(state='normal') self.purgebutton.config(state='normal') for i in self.worker.modulenames: self.modulebuttons[i].config(state='normal') def __disable_quitbutton__(self): 'Disable the button Quit and enable Abort' self.quitbutton.config(state=DISABLED) self.stopbutton.config(state='normal') def __enable_quitbutton__(self): 'Enable the button Quit and disable Abort' self.quitbutton.config(state='normal') self.stopbutton.config(state=DISABLED) def __enable_config__(self): 'Enable configuration frame' self.config_visible = True self.frame_changeling.config(text=' \u2737 Configuration ') self.frame_config.grid(row=0, column=0, sticky=W + E + N + S) self.frame_messages.grid_remove() self.button_toggle.config(text='\u2609 Show Messages') self.button_clear.config(state=DISABLED) def __enable_messages__(self): 'Enable configuration frame' self.config_visible = False self.frame_changeling.config(text=' \u2709 Messages') self.frame_config.grid_remove() self.frame_messages.grid(row=0, column=0, sticky=W + E + N + S) self.button_toggle.config(text='\u2609 Show Configuration') self.button_clear.config(state='normal') def __toggle_config__(self): 'Toggle Configuration / Messages' if self.config_visible: self.__enable_messages__() else: self.__enable_config__() def __clear_messages__(self): 'Clear message / logging output fild' if messagebox.askyesno('Somedo', 'Clear messages?'): self.text_messages.delete('1.0', END) def __write_message__(self, msg): 'Write to message fiels' self.text_messages.insert(END, msg + '\n') self.text_messages.yview(END) def __start__(self): 'Start the jobs' if len(self.jobs) < 1: messagebox.showerror('Error', 'Nothing to do') return try: # check if task is running if self.thread_worker.isAlive(): return except: pass self.__disable_jobbuttons__() self.__disable_quitbutton__() self.__enable_messages__() self.__close2stop__() self.stop = Event() # to stop working thread self.stop_set = False self.running_job = 0 self.thread_worker = Thread(target=self.__worker__) self.thread_worker.start() # start work self.thread_showjob = Thread(target=self.__showjob__) self.thread_showjob.start() # start work def __stop__(self): 'Stop running job but give results based on already optained data' if self.stop_set: self.__kill__() return try: # check if task is running if self.thread_worker.isAlive() and messagebox.askyesno( 'Somedo', 'Stop running task?'): self.stop.set() except: pass self.running_job = -1 self.stop_set = True def __kill__(self): 'Kill Somedo immediatly' if messagebox.askyesno( 'Somedo', 'Kill Somedo as fast as possible?\n\nAlready downloaded data mightbe lost!' ): self.__terminate__() def __worker__(self): 'Execute jobs' if len(self.jobs) > 1: self.__write_message__('\n--- Executing jobs ---\n') while self.running_job < len(self.jobs): self.worker.execute_job(self.jobs[self.running_job], jobnumber=self.running_job + 1, stop=self.stop) self.running_job += 1 else: self.__write_message__('\n--- Executing job ---\n') self.worker.execute_job(self.jobs[self.running_job], stop=self.stop) self.__write_message__('\n--- Done ---\n') self.__close2quit__() self.__enable_jobbuttons__() self.__enable_quitbutton__() def __showjob__(self): 'Show what the worker is doing' while self.thread_worker.isAlive(): running = self.running_job self.jobbuttons[running].config(fg=self.colour_bg) self.jobbuttons[running].config(bg=self.colour_fg) sleep(0.75) self.jobbuttons[running].config(fg=self.colour_fg) self.jobbuttons[running].config(bg=self.colour_bg) sleep(0.75) def __terminate__(self): 'Terminate GUI' try: if self.thread_worker.isAlive(): raise SystemExit('Worker thread was still running') except: pass try: if self.thread_showjob.isAlive(): raise SystemExit('Thread that indicates job was still running') except: pass self.root.quit()
class ListWidget: def __init__(self, command=None): self.topic_list = None outsideFrame = Frame() outsideFrame.config(padx=10, pady=10) outsideFrame.grid(row=1, column=0, sticky="wn") self.frame = LabelFrame(outsideFrame, text="Topics") self.frame.config(font=("Arial", 14), padx=10, pady=10) self.frame.grid(row=0, column=0) self._command = command self.topic_filter_input = Entry(self.frame, width=33) self.topic_filter_input.grid(row=0, column=0, pady=10) self.topic_filter_input.bind("<KeyRelease>", self.filter_topic) treeFrame = Frame(self.frame) treeFrame.grid(row=1, column=0) self.tree = Treeview(treeFrame, style="Custom.Treeview") self.tree.heading('#0', text='Topic') self.tree.pack() self.tree.bind("<ButtonRelease-1>", self.OnClick) self.tree.tag_configure('odd', background='#f9f9f9') self.tree.tag_configure('even', background='#DFDFDF') scroll_bar = Scrollbar(self.frame, orient="vertical", command=self.tree.yview) scroll_bar.grid(row=1, column=1, sticky='nsew') self.tree.configure(yscrollcommand=scroll_bar.set) def filter_topic(self, *args): inputed_topic = self.topic_filter_input.get() list = filter(lambda k: inputed_topic.lower() in k.lower(), self.topic_list) self.prepare_list(list) def OnClick(self, event): item = self.tree.identify('item', event.x, event.y) if item == '': return selectedItem = self.tree.item(item, "text") self._command(selectedItem) def prepare_list(self, sorted_topic_list): self.clean() for topic in sorted_topic_list: self.insert(topic) def insert(self, line): type = 'even' if (len(self.tree.get_children()) % 2 == 1): type = 'odd' self.tree.insert("", "end", text=line, tags=(type, )) def clean(self): for i in self.tree.get_children(): self.tree.delete(i) def destroy(self): self.frame.destroy()
def initUI(self): self.home_dir = os.getcwd() self.master.title("Veraxx SOFASTe PDAL Manager") # Menu Bar menu = Menu(self.master) self.master.config(menu=menu) # File Menu file = Menu(menu, tearoff=0) file.add_command(label="Open PDAL", command=self.open_pdal) # add File Menu to Menu Bar menu.add_cascade(label="File", menu=file) # Actions Menu edit = Menu(menu, tearoff=0) edit.add_command(label="Scan for PDFs", command=self.pdfs_exist) edit.add_command(label="Remove .bak files", command=self.remove_bak) edit.add_command(label="Scan all for superseded", command=self.find_superseded) edit.add_command(label="Scan folder for superseded", command=self.find_superseded_in_folder) edit.add_command(label="Scan CAE filenames", command=self.CAE_filenames_valid) edit.add_command(label="Find \"forgot to introduce\"", command=self.find_files_not_introduced) # Add Validate Menu to Menu Bar menu.add_cascade(label="Actions", menu=edit) # Help Menu helpmenu = Menu(menu, tearoff=0) helpmenu.add_command(label="How to", command=self.howto_popup) menu.add_cascade(label="Help",menu=helpmenu) # Style and padding Style().configure("TButton", padding=(3, 5, 3, 5), font='serif 10') self.columnconfigure(0, pad=3) self.rowconfigure(0, pad=3) # Widget variables # Full path to PDAL self.pdal_dir = StringVar() # Name of PDAL TLD self.pdal_name = StringVar() self.pdal_name.set("No PDAL selected") self.load_persistent() # Listbox for drawing filenames self.lstbox_lbl = StringVar() self.lstbox_lbl.set("Files:") self.lstbox_export_fn = "export.txt" # Full path to cable CSV file self.cable_csv_path = StringVar() self.cable_csv_path.set("No CSV file selected") # Cable assy dwg number self.cable_assy_num = StringVar() self.cable_assy_num.set("No cable labels") # Configure the main widget group grp_main = LabelFrame(self.master, text="PDAL") grp_main.grid(row=0, column=0) grp_main.config(padx=50, pady=20) # PDAL directory label_pdal_name = Label(grp_main, textvariable = self.pdal_name, width=40) label_pdal_name.grid(row=0, column=1) # Listbox lstbx_files_lbl = Label(grp_main, textvariable = self.lstbox_lbl) lstbx_files_lbl.grid(row=0, column=2) self.lstbx_files = Listbox(grp_main, selectmode="extended", width=80) self.lstbx_files.grid(row=1, column=2) btn_export_lstbx = Button(grp_main, text="Export Listbox", command=self.export_listbox) btn_export_lstbx.grid(row=2, column=2) # Configure the cable labels widget group grp_cbllbl = LabelFrame(self.master, text="Cable Labels") grp_cbllbl.grid(row=1, column=0) grp_cbllbl.config(padx=50, pady=20) # Cable label file path cable_label_file = Label(grp_cbllbl, textvariable = self.cable_csv_path, width=40) cable_label_file.grid(row=0, column=0) btn_open_cable_csv = Button(grp_cbllbl, text="Open cable label CSV", command=self.open_cable_csv) btn_open_cable_csv.grid(row=1, column=0) # Cable Label Listbox lstbx_cables_lbl = Label(grp_cbllbl, textvariable = self.cable_assy_num) lstbx_cables_lbl.grid(row=0, column=1) self.lstbx_cables = Listbox(grp_cbllbl, selectmode="extended", width=80) self.lstbx_cables.grid(row=1, column=1) btn_print_labels = Button(grp_cbllbl, text="Print labels", command=self.print_labels) btn_print_labels.grid(row=2, column=1) btn_quit = Button(self.master, text="Quit", command=self.master.destroy) btn_quit.grid(row=3, column=0)
def _configure_container(self, container: tk.LabelFrame): container.config(text='Join Game')
class Emulatore(object): """ Interfaccia grafica per l'emulatore del pdp8 """ def __init__(self, master, codice, calcolatore, emulatore): """ Inizializza i frame per l'interfaccia dell'emulatore """ self.CD = calcolatore self.codice = codice self.delay = 100 self.master = Frame(master) self.root = emulatore # Memoria Ram self.ram = LabelFrame( self.master, text="Memoria RAM", relief=RIDGE, borderwidth=5, labelanchor="n", pady=5, ) self.ram.rowconfigure(0, weight=1) self.ram.columnconfigure(0, weight=1) self.ram.grid(row=0, column=0, rowspan=3, columnspan=5, sticky=W + E + N + S) # Controlli self.controlli = Frame(self.master, padx=10, pady=10) self.controlli.grid(row=0, column=5, rowspan=1) # Status CD self.registri = LabelFrame( self.master, text="REGISTRI", relief=RIDGE, borderwidth=5, labelanchor="n", padx=25, pady=10, ) self.registri.grid(row=0, column=6, rowspan=1, sticky=W + E + N + S) self.unita = LabelFrame( self.master, text="UC", relief=RIDGE, borderwidth=5, labelanchor="n", padx=10, pady=10, ) self.unita.grid(row=2, column=6, rowspan=1, sticky=N) # Var self.variabili = Frame(self.master) self.variabili.grid(row=2, column=5) self.nstep = LabelFrame( self.variabili, text="Num. Step", relief=RIDGE, borderwidth=5, labelanchor="n", ) self.nstep.grid(row=0, column=5, sticky=W + E) self.delays = LabelFrame( self.variabili, text="Delay", relief=RIDGE, borderwidth=5, labelanchor="n" ) self.delays.grid(row=1, column=5, sticky=W + E) self.tempo = LabelFrame( self.variabili, text="Tempo", relief=RIDGE, borderwidth=5, labelanchor="n" ) self.tempo.grid(row=1, column=6, sticky=W + E) # Unita' di controllo self.unitas = LabelFrame(self.unita, text="S", labelanchor="s", padx=10) self.unitas.grid(row=0, column=0, sticky=N) self.unitaf = LabelFrame(self.unita, text="F", labelanchor="s", padx=10) self.unitaf.grid(row=0, column=1, sticky=N) self.unitar = LabelFrame(self.unita, text="R", labelanchor="s", padx=10) self.unitar.grid(row=0, column=2, sticky=N) self.unitaint = LabelFrame(self.unita, text="Int.", labelanchor="s", padx=10) self.unitaint.grid(row=0, column=3, sticky=N) # Registri self.programc = LabelFrame( self.registri, text="PC", relief=FLAT, labelanchor="e", padx=5 ) self.programc.grid(row=0, column=0, sticky=W + E) self.mar = LabelFrame( self.registri, text="MAR", relief=FLAT, labelanchor="e", padx=5 ) self.mar.grid(row=1, column=0, sticky=W + E) self.mbr = LabelFrame( self.registri, text="MBR", relief=FLAT, labelanchor="e", padx=5 ) self.mbr.grid(row=2, column=0, sticky=W + E) self.lopr = LabelFrame( self.registri, text="OPR", relief=FLAT, labelanchor="e", padx=5 ) self.lopr.grid(row=3, column=0, sticky=W + E) self.vari = LabelFrame( self.registri, text="I", relief=FLAT, labelanchor="e", padx=5 ) self.vari.grid(row=4, column=0, sticky=W + E) self.vare = LabelFrame( self.registri, text="E", relief=FLAT, labelanchor="e", padx=5 ) self.vare.grid(row=5, column=0, sticky=W + E) self.lac = LabelFrame( self.registri, text="AC", relief=FLAT, labelanchor="e", padx=5 ) self.lac.grid(row=6, column=0, sticky=W + E) self.lacint = LabelFrame( self.registri, text="INT AC", relief=FLAT, labelanchor="e", padx=5 ) self.lacint.grid(row=7, column=0, sticky=W + E) self.lachex = LabelFrame( self.registri, text="HEX AC", relief=FLAT, labelanchor="e", padx=5 ) self.lachex.grid(row=8, column=0, sticky=W + E) # Microistruzioni self.micro = LabelFrame( self.master, text="Microistruzioni eseguite", relief=RIDGE, borderwidth=5, labelanchor="n", pady=5, ) self.micro.rowconfigure(0, weight=1) self.micro.columnconfigure(0, weight=1) self.micro.grid(row=3, column=4, rowspan=5, columnspan=5, sticky=W + E + N + S) # Inout self.inout = LabelFrame( self.master, text="Input & Output", relief=RIDGE, borderwidth=5, labelanchor="n", pady=5, ) self.inout.rowconfigure(0, weight=1) self.inout.columnconfigure(0, weight=1) self.inout.grid(row=3, column=0, columnspan=4, sticky=W + E + N + S) self.create_widgets() def create_widgets(self): """ Crea il layout del programma, finestra dell'emulatore """ # Memoria RAM self.Visualizza = Text(self.ram, width=80) self.Visualizzascrollbar = Scrollbar(self.ram) self.Visualizzascrollbar.config(command=self.Visualizza.yview) self.Visualizza.config(yscrollcommand=self.Visualizzascrollbar.set) self.Visualizzascrollbar.grid(row=0, column=1, sticky=N + S) self.Visualizza.grid(row=0, column=0, sticky=W) # INOUT self.Visualizzainout = Text( self.inout, width=62, height=7, fg="green", bg="black" ) self.Visualizzascrollbar_inout = Scrollbar(self.inout) self.Visualizzascrollbar_inout.config(command=self.Visualizzainout.yview) self.Visualizzainout.config(yscrollcommand=self.Visualizzascrollbar_inout.set) self.Visualizzascrollbar_inout.grid(row=0, column=1, sticky=N + S) self.Visualizzainout.grid(row=0, column=0, sticky=W) # Mircroistruzioni self.Visualizzamicro = Text(self.micro, width=55, height=7) self.Visualizzascrollbar_m = Scrollbar(self.micro) self.Visualizzascrollbar_m.config(command=self.Visualizzamicro.yview) self.Visualizzamicro.config(yscrollcommand=self.Visualizzascrollbar_m.set) self.Visualizzascrollbar_m.grid(row=0, column=1, sticky=N + S) self.Visualizzamicro.grid(row=0, column=0, sticky=W) # Pulsanti self.butload = Button( self.controlli, text="LOAD", anchor=CENTER, width=15, command=self.loading, bg="SkyBlue", ) self.butload.grid(row=0, column=0) self.butstep = Button( self.controlli, text="Step", anchor=CENTER, width=15, command=self.step, bg="linen", ) self.butstep.grid(row=1, column=0) self.butminstep = Button( self.controlli, text="miniStep", anchor=CENTER, width=15, command=self.mini_step, bg="linen", ) self.butminstep.grid(row=2, column=0) self.butstep = Button( self.controlli, text="microStep", anchor=CENTER, width=15, command=self.micro_step, bg="linen", ) self.butstep.grid(row=3, column=0) self.butsetstep = Button( self.controlli, text="Set n Step", anchor=CENTER, width=15, command=self.setnstep, bg="linen", ) self.butsetstep.grid(row=4, column=0) self.butsetdelay = Button( self.controlli, text="Set Delay", anchor=CENTER, width=15, command=self.setdelay, bg="linen", ) self.butsetdelay.grid(row=5, column=0) self.butstart = Button( self.controlli, text="START", anchor=CENTER, width=15, command=self.start, bg="DarkOliveGreen3", ) self.butstart.grid(row=6, column=0) self.butreset = Button( self.controlli, text="RESET", anchor=CENTER, width=15, command=self.resetCD, bg="Orange3", ) self.butreset.grid(row=7, column=0) self.butstop = Button( self.controlli, text="STOP", anchor=CENTER, width=15, command=self.stop, bg="IndianRed", ) self.butstop.grid(row=8, column=0) self.butbreak = Button( self.controlli, text="BREAK", anchor=CENTER, width=15, command=self.breakpoint, bg="Magenta2", ) self.butbreak.grid(row=9, column=0) self.butcontinue = Button( self.controlli, text="CONTINUA", anchor=CENTER, width=15, command=self.continua, bg="Magenta2", ) self.butcontinue.grid(row=10, column=0) self.butesegui = Button( self.controlli, text="ESEGUI", anchor=CENTER, width=15, command=self.esegui, bg="Yellow", ) self.butesegui.grid(row=11, column=0) # Labels self.labelprogramc = Label( self.programc, text="00000000000", relief=SUNKEN, bg="red" ) self.labelprogramc.grid() self.labelmar = Label(self.mar, text="00000000000", relief=SUNKEN, bg="yellow") self.labelmar.grid() self.labelmbr = Label(self.mbr, text="000000000000000", relief=SUNKEN) self.labelmbr.grid() self.labelvari = Label(self.vari, text="0", relief=SUNKEN) self.labelvari.grid() self.labelopr = Label(self.lopr, text="000", relief=SUNKEN) self.labelopr.grid() self.labelucs = Label(self.unitas, text="0") self.labelucs.grid() self.labelucf = Label(self.unitaf, text="0") self.labelucf.grid() self.labelucr = Label(self.unitar, text="0") self.labelucr.grid() self.labelucint = Label(self.unitaint, text="0") self.labelucint.grid() self.labelnstep = Label(self.nstep, text="1") self.labelnstep.grid() self.labeldelay = Label(self.delays, text=str(self.delay)) self.labeldelay.grid() self.labeltempo = Label(self.tempo, text=str(self.CD.tempo)) self.labeltempo.grid() self.labelac = Label(self.lac, text="000000000000000", relief=SUNKEN) self.labelac.grid() self.labelacint = Label(self.lacint, text="000000000000000", relief=SUNKEN) self.labelacint.grid() self.labelachex = Label(self.lachex, text="000000000000000", relief=SUNKEN) self.labelachex.grid() self.labelvare = Label(self.vare, text="0", relief=SUNKEN) self.labelvare.grid() def continua(self): """ Continua l'esecuzione dopo un break """ self.CD.S = True self.esegui() def micro_step(self): """ Esegue il metodo step del calcolatore didattico ed aggiorna """ if self.CD.S: self.CD.step(self.root, self.codice) if self.CD.tempo == 0 and not self.CD.F and not self.CD.R: self.CD.previstr = self.CD.nextistr self.aggiornaall() def step(self): """ Esegue il metodo step del calcolatore didattico ed aggiorna """ var = True if self.CD.S and self.CD.nstep > 0: while var and self.CD.S: self.CD.step(self.root, self.codice) if not self.CD.F and not self.CD.R and self.CD.tempo == 0: self.CD.nstep -= 1 self.aggiornaall() self.CD.previstr = self.CD.nextistr var = False if self.CD.nstep > 0: self.butstep.after(self.delay, self.step) else: self.CD.setnstep(1) else: self.CD.setnstep(1) self.aggiornaall() def esegui(self): """ Esegue il programma fino all'arresto della macchina tramite l'istruzione HLT """ while self.CD.S: self.CD.step(self.root, self.codice) if not self.CD.F and not self.CD.R and self.CD.tempo == 0: self.aggiornaall() self.CD.previstr = self.CD.nextistr break if self.CD.S: self.butesegui.after(self.delay, self.esegui) else: self.CD.setnstep(1) self.aggiornaall() def mini_step(self): """ Esegue un singolo ciclo della macchina """ if self.CD.S: for x in range(0, 4): self.CD.step(self.root, self.codice) self.CD.nstep = 1 self.aggiornaall() if self.CD.F is False and self.CD.R is False: self.CD.previstr = self.CD.nextistr def cerca_istr_prev(self): """ Evidenzia di VERDE l'ultima istruzione eseguita """ if self.CD.PC == "000000000000": return try: if self.CD.previstr == "" and int(self.CD.PC, 2) == self.CD.START: return else: pospc = str(3.0 + self.CD.previstr) self.Visualizza.tag_add( "PISTR", str(pospc[:-1] + "16"), str(pospc[:-1] + "end") ) self.Visualizza.tag_config("PISTR", background="green") self.Visualizza.see(pospc) except TypeError: pass # Errore che si ottiene durante il reset del CD # NOTA : METODO NON NECESSARIO NEL PROGRAMMA FINALE # def cerca_istr_corr(self): # """ # Evidenzia di verde l'istruzione che si dovrà eseguire # """ # if self.CD.PC == '000000000000': # return # try: # if int(self.CD.PC,2) == self.CD.START: # Inizio esecuzione del programma # Il PC e l'istruzione da eseguire sono allo stesso 'livello' # pos = str(3.0) # self.Visualizza.tag_add("ISTR", str(pos[0]+'.16'), str(pos[:-1]+'end')) # self.Visualizza.tag_config("ISTR", background = "green") # else: # pospc = str(3.0 + self.CD.nextistr) # self.Visualizza.tag_add("ISTR", str(pospc[:-1]+'16'), str(pospc[:-1]+'end')) # self.Visualizza.tag_config("ISTR", background = "green") # self.Visualizza.see(pospc) # except TypeError: # pass ## Errore che si ottiene durante il reset del CD def cerca_MAR(self): """ Evidenzia di giallo l'indirizzo puntato dal MAR """ try: pos = 3.0 stringa = self.Visualizza.get(str(pos), "end") while ( stringa[:12] != self.CD.MAR and int(pos) < len(self.CD.RAM) + 3 and len(self.CD.RAM) > 0 ): pos += 1 stringa = self.Visualizza.get(str(pos), "end") if int(pos) >= len(self.CD.RAM) + 3: return self.Visualizza.tag_add("MAR", pos, str(float(pos) + 0.12)) self.Visualizza.tag_config("MAR", background="yellow") except TypeError: pass # Errore che si ottiene durante il reset del CD def cerca_PC(self): """ Evidenzia di rosso l'indirizzo puntato da PC """ try: pos = 3.0 stringa = self.Visualizza.get(str(pos), "end") while ( stringa[:12] != self.CD.PC and int(pos) < len(self.CD.RAM) + 3 and len(self.CD.RAM) > 0 ): pos += 1 stringa = self.Visualizza.get(str(pos), "end") if int(pos) >= len(self.CD.RAM) + 3: return self.Visualizza.tag_add("PC", pos, str(float(pos) + 0.12)) self.Visualizza.tag_config("PC", background="red") except TypeError: pass # Errore che si ottiene durante il reset del CD def aggiornaout(self): """ Aggiorna micro e input/output """ self.aggiornamicro() self.aggiornainout() def aggiornamicro(self): """ Aggiorna le microistruzioni eseguite """ self.Visualizzamicro.delete(1.0, END) stringa = self.CD.microistruzioni self.Visualizzamicro.insert(INSERT, stringa) self.Visualizzamicro.see(END) def aggiornainout(self): """ Aggiorna gli input ed output di sistema """ self.Visualizzainout.delete(1.0, END) stringa = self.CD.inout self.Visualizzainout.insert(INSERT, stringa) self.Visualizzainout.see(END) def aggiornaram(self): """ Aggiorna lo stato della RAM """ self.Visualizza.delete(1.0, END) stringa = self.CD.statusRAM() self.Visualizza.insert(INSERT, stringa) self.cerca_MAR() self.cerca_PC() self.cerca_istr_prev() # self.cerca_istr_corr() #Non più necessaria nella versione finale def aggiornareg(self): """ Aggiorna lo stato dei Registri """ self.labelprogramc.config(text=self.CD.PC) self.labelmar.config(text=self.CD.MAR) self.labelmbr.config(text=self.CD.MBR) self.labelac.config(text=self.CD.AC) self.labelacint.config(text=str(self.CD.range(int(self.CD.AC, 2)))) self.labelachex.config(text=str((hex(int(self.CD.AC, 2))[2:].upper())).zfill(4)) self.labelvare.config(text=self.CD.E) self.labelvari.config(text=self.CD.I) self.labelopr.config(text=self.CD.OPR) def aggiornauc(self): """ Aggiorna lo stato dell'unita' di controllo """ if self.CD.S and not self.CD.breaks: self.labelucs.config(text=self.CD.S, bg="green") self.unitas.config(bg="green") elif not self.CD.S and self.CD.breaks: self.labelucs.config(text=self.CD.S, bg="Magenta2") self.unitas.config(bg="Magenta2") else: self.labelucs.config(text=self.CD.S, bg="red") self.unitas.config(bg="red") self.labelucf.config(text=self.CD.F) self.labelucr.config(text=self.CD.R) self.labelucint.config(text=self.CD.Interrupt) self.labeltempo.config(text=self.CD.tempo) def aggiornaall(self): """ Aggiorna tutto """ self.aggiornaram() self.aggiornareg() self.aggiornauc() self.aggiornamicro() self.aggiornaout() self.labelnstep.config(text=self.CD.nstep) def loading(self): """ Carica il contenuto del codice assembly decodificandolo in binario nella RAM """ contenuto = self.codice.Inserisci.get(1.0, END) if len(contenuto) > 1: self.resetCD() if self.CD.carica(contenuto, self) is not None: self.CD.S = 0 self.aggiornaall() def resetCD(self): """ Resetta il calcolatore didattico """ self.CD = pdp8() self.aggiornaall() def start(self): """ Mette la variabile Start (S) ad 1, cioe' True """ self.CD.S = True if self.CD.breaks == True: self.CD.breaks = False self.aggiornauc() def stop(self): """ Mette la variabile Start (S) ad 0, cioe' False """ self.CD.S = False self.aggiornauc() def setnstep(self): """ Setta, in base al valore passato, il numero di cicli da eseguire """ temp = askinteger( "Num Step", "Numero di step da eseguire", initialvalue=1, minvalue=1, parent=self.root, ) if temp is None: self.CD.setnstep(1) else: self.CD.setnstep(temp) self.labelnstep.config(text=self.CD.nstep) def setdelay(self): """ Setta, in base al valore passato, il ritardo di esecuzione. Il valore è espresso in millisecondi, di default = 1000 """ temp = askinteger( "Set Delay", "Ritardo in millisecondi", initialvalue=100, minvalue=1, parent=self.root, ) if temp is not None: self.delay = temp self.labeldelay.config(text=self.delay) def breakpoint(self): """ Setta o elimina i breakpoint dal programma caricato in memoria """ temp = askstring("Cella di memoria", "Indirizzo esadecimale", parent=self.root) if temp is not None: temp = self.CD.binario(int(temp, 16)).zfill(12) self.CD.breakpoint(temp) self.aggiornaram() def exit(self): """ Esce dal programma """ if askquestion("Exit", "Sicuro di voler uscire?", parent=self.master) == YES: self.codice.master.quit() self.codice.master.destroy() else: showinfo( "Suggerimento", """Forse e' meglio fare una pausa!""", icon=WARNING, parent=self.master, )
class FormChildTemplate: def __init__(self, frm_parent, connection): self.connection = connection self.directive = Message() self.decide_template = True self.id_selected = 0 self.frm_child_list = LabelFrame(frm_parent) self.frm_child_crud = LabelFrame(frm_parent) self.frm_child_crud.config(fg=TEXT_COLOR, font=SUBTITLE_FONT) self.initialize_components() def initialize_components(self): """ Method that initialize the visual components for each form associated with the local administration """ # Resources for the Forms self.new_icon = PhotoImage(file=r"./Resources/create.png") self.modify_icon = PhotoImage(file=r"./Resources/modify.png") self.remove_icon = PhotoImage(file=r"./Resources/delete.png") self.save_icon = PhotoImage(file=r"./Resources/save.png") self.cancel_icon = PhotoImage(file=r"./Resources/cancel.png") self.add_icon = PhotoImage(file=r"./Resources/right.png") self.delete_icon = PhotoImage(file=r"./Resources/left.png") self.up_arrow = PhotoImage(file=r"./Resources/up_arrow.png") self.down_arrow = PhotoImage(file=r"./Resources/down_arrow.png") self.star_icon = PhotoImage(file=r"./Resources/star.png") self.back_icon = PhotoImage(file=r"./Resources/back.png") self.view_icon = PhotoImage(file=r"./Resources/view.png") # Components for List FRM lbl_sep1 = Label(self.frm_child_list) lbl_sep1.grid(row=0, column=0, padx=10, pady=25) self.trv_available = Treeview(self.frm_child_list, height=20, columns=('N', 'Name')) self.trv_available.heading('#0', text='ID', anchor=CENTER) self.trv_available.heading('#1', text='N', anchor=CENTER) self.trv_available.heading('#2', text='Name', anchor=CENTER) self.trv_available.column('#0', width=0, minwidth=50, stretch=NO) self.trv_available.column('#1', width=20, minwidth=20, stretch=NO) self.trv_available.column('#2', width=375, minwidth=375, stretch=NO) self.trv_available.bind("<ButtonRelease-1>", self.select_template_summary) self.trv_available.grid(row=0, column=1, sticky=W, pady=25) vsb_trv_av = Scrollbar(self.frm_child_list, orient="vertical", command=self.trv_available.yview) vsb_trv_av.grid(row=0, column=2, pady=25, sticky=NS) self.trv_available.configure(yscrollcommand=vsb_trv_av.set) frm_aux4 = Frame(self.frm_child_list) btn_new = Button(frm_aux4, image=self.new_icon, command=self.click_new) btn_new.grid(row=0, column=0, pady=5, padx=5, sticky=E) btn_new_ttp = CreateToolTip(btn_new, 'New template') btn_view = Button(frm_aux4, image=self.view_icon, command=self.click_view) btn_view.grid(row=1, column=0, pady=5, padx=5, sticky=E) btn_view_ttp = CreateToolTip(btn_new, 'View template') btn_edit = Button(frm_aux4, image=self.modify_icon, command=self.click_update) btn_edit.grid(row=2, column=0, pady=5, padx=5, sticky=E) btn_edit_ttp = CreateToolTip(btn_edit, 'Edit template') btn_delete = Button(frm_aux4, image=self.remove_icon, command=self.click_delete) btn_delete.grid(row=3, column=0, pady=5, padx=5, sticky=E) btn_delete_ttp = CreateToolTip(btn_delete, 'Delete template') frm_aux4.grid(row=0, column=3, pady=25, padx=25, sticky=NW) sep_template = Separator(self.frm_child_list, orient=VERTICAL) sep_template.grid(row=0, column=4, sticky=NS, padx=25) frm_aux3 = Frame(self.frm_child_list) lbl_sep3 = Label(frm_aux3) lbl_sep3.grid(row=0, column=0, padx=10, pady=25, rowspan=3) lbl_details = Label(frm_aux3, text='Details') lbl_details.config(fg=TEXT_COLOR, font=SUBTITLE_FONT) lbl_details.grid(row=0, column=1, sticky=W, pady=25, columnspan=2) self.txt_summary = Text(frm_aux3, height=22, width=50) self.txt_summary.config(font=TEXT_FONT, bg=DISABLED_COLOR) self.txt_summary.grid(row=1, column=1) vsb_txt_sum = Scrollbar(frm_aux3, orient="vertical", command=self.txt_summary.yview) vsb_txt_sum.grid(row=1, column=2, sticky=NS) self.txt_summary.configure(yscrollcommand=vsb_txt_sum.set) lbl_sep4 = Label(frm_aux3) lbl_sep4.grid(row=0, column=3, padx=10, pady=25, rowspan=3) lbl_sep5 = Label(frm_aux3) lbl_sep5.grid(row=2, column=1, pady=5, columnspan=2) frm_aux3.grid(row=0, column=5) # Components for CRUD FRM lbl_sep6 = Label(self.frm_child_crud) lbl_sep6.grid(row=0, column=0, padx=10, pady=25, rowspan=10) lbl_name = Label(self.frm_child_crud, text='Name*') lbl_name.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_name.grid(row=0, column=1, pady=25, sticky=NW) lbl_description = Label(self.frm_child_crud, text='Description*') lbl_description.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_description.grid(row=0, column=6, pady=25, sticky=NW) lbl_sep3 = Label(self.frm_child_crud) lbl_sep3.grid(row=0, column=2, padx=10, pady=25) self.txt_name = Entry(self.frm_child_crud, width=30, font=TEXT_FONT) self.txt_name.grid(row=0, column=3, pady=25, sticky=NW) lbl_sep4 = Label(self.frm_child_crud) lbl_sep4.grid(row=0, column=7, padx=10, pady=25) self.txt_description = Text(self.frm_child_crud, height=5, width=49) self.txt_description.config(font=TEXT_FONT) self.txt_description.grid(row=0, column=8, pady=25, sticky=W) vsb_txt_desc = Scrollbar(self.frm_child_crud, orient="vertical", command=self.txt_description.yview) vsb_txt_desc.grid(row=0, column=9, pady=25, sticky=NS) self.txt_description.configure(yscrollcommand=vsb_txt_desc.set) lbl_sep7 = Label(self.frm_child_crud) lbl_sep7.grid(row=0, column=5, padx=10, pady=25, rowspan=3) lbl_sep8 = Label(self.frm_child_crud) lbl_sep8.grid(row=0, column=10, padx=10, pady=25, rowspan=2) lbl_available_d = Label(self.frm_child_crud, text='Available sections') lbl_available_d.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_available_d.grid(row=1, column=1, pady=10, sticky=W, columnspan=4) lbl_selected_d = Label(self.frm_child_crud, text='Selected sections*') lbl_selected_d.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_selected_d.grid(row=1, column=6, pady=10, sticky=W, columnspan=4) self.trv_available_sections = Treeview(self.frm_child_crud, height=10, columns=('N', 'Name', 'Data Type')) self.trv_available_sections.heading('#0', text='ID', anchor=CENTER) self.trv_available_sections.heading('#1', text='N', anchor=CENTER) self.trv_available_sections.heading('#2', text='Name', anchor=CENTER) self.trv_available_sections.heading('#3', text='Data Type', anchor=CENTER) self.trv_available_sections.column('#0', width=0, minwidth=20, stretch=NO) self.trv_available_sections.column('#1', width=20, minwidth=20, stretch=NO) self.trv_available_sections.column('#2', width=150, minwidth=150, stretch=NO) self.trv_available_sections.column('#3', width=120, minwidth=120, stretch=NO) self.trv_available_sections.bind("<Button-1>", self.click_trv_asections) self.trv_available_sections.grid(row=2, column=1, rowspan=7, columnspan=3, sticky=W, pady=10) vsb_trv_avs = Scrollbar(self.frm_child_crud, orient="vertical", command=self.trv_available_sections.yview) vsb_trv_avs.grid(row=2, column=4, rowspan=7, pady=10, sticky=NS) self.trv_available_sections.configure(yscrollcommand=vsb_trv_avs.set) self.trv_selected_sections = Treeview(self.frm_child_crud, height=10, columns=('N', 'Name', 'Data type', 'Mandatory', 'Main')) self.trv_selected_sections.heading('#0', text='ID', anchor=CENTER) self.trv_selected_sections.heading('#1', text='N', anchor=CENTER) self.trv_selected_sections.heading('#2', text='Name', anchor=CENTER) self.trv_selected_sections.heading('#3', text='Data type', anchor=CENTER) self.trv_selected_sections.heading('#4', text='Mandatory', anchor=CENTER) self.trv_selected_sections.heading('#5', text='Main', anchor=CENTER) self.trv_selected_sections.column('#0', width=0, minwidth=20, stretch=NO) self.trv_selected_sections.column('#1', width=20, minwidth=20, stretch=NO) self.trv_selected_sections.column('#2', width=150, minwidth=150, stretch=NO) self.trv_selected_sections.column('#3', width=120, minwidth=120, stretch=NO) self.trv_selected_sections.column('#4', width=80, minwidth=80, stretch=NO) self.trv_selected_sections.column('#5', width=80, minwidth=80, stretch=NO) self.trv_selected_sections.bind("<Button-1>", self.click_trv_ssections) self.trv_selected_sections.bind("<Double-1>", self.click_switch_mandatory) self.trv_selected_sections.grid(row=2, column=6, rowspan=7, columnspan=3, sticky=W, pady=10) vsb_trv_ses = Scrollbar(self.frm_child_crud, orient="vertical", command=self.trv_selected_sections.yview) vsb_trv_ses.grid(row=2, column=9, rowspan=7, pady=10, sticky=NS) self.trv_selected_sections.configure(yscrollcommand=vsb_trv_ses.set) self.lbl_note_optional = Label( self.frm_child_crud, text= 'NOTES:\tTo switch between optional and mandatory, double click ' 'on selected section.\n\tChoose one or up to three main sections ' 'by first selecting the target sections\n\tand then clicking the ' 'star button.\n') self.lbl_note_optional.config(fg=TEXT_COLOR, font=NOTE_FONT, justify=LEFT) self.btn_add = Button(self.frm_child_crud, image=self.add_icon, command=self.click_add) btn_add_ttp = CreateToolTip(self.btn_add, 'Add section') self.btn_remove = Button(self.frm_child_crud, image=self.delete_icon, command=self.click_remove) btn_remove_ttp = CreateToolTip(self.btn_remove, 'Remove section') self.btn_main_section = Button(self.frm_child_crud, image=self.star_icon, command=self.click_main_section) btn_main_section_ttp = CreateToolTip(self.btn_main_section, 'Main section(s)') self.btn_up = Button(self.frm_child_crud, image=self.up_arrow, command=self.click_up) btn_up_ttp = CreateToolTip(self.btn_up, 'Move up') self.btn_down = Button(self.frm_child_crud, image=self.down_arrow, command=self.click_down) btn_down_ttp = CreateToolTip(self.btn_down, 'Move down') sep_aux1 = Separator(self.frm_child_crud, orient=VERTICAL) sep_aux1.grid(row=0, column=11, sticky=NS, rowspan=10) frm_aux1 = Frame(self.frm_child_crud) self.btn_save = Button(frm_aux1, image=self.save_icon, command=self.click_save) btn_save_ttp = CreateToolTip(self.btn_save, 'Save template') self.btn_back = Button(frm_aux1, image=self.back_icon, command=self.click_back) btn_back_ttp = CreateToolTip(self.btn_back, 'Go back') self.btn_cancel = Button(frm_aux1, image=self.cancel_icon, command=self.click_cancel) btn_cancel_ttp = CreateToolTip(self.btn_cancel, 'Cancel') frm_aux1.grid(row=0, column=12, pady=10, padx=25, sticky=NW, rowspan=10) def retrieve_list(self): # Remove existing elements in the list for item in self.trv_available.get_children(): self.trv_available.delete(item) self.directive = Message(action=37) self.connection = self.directive.send_directive(self.connection) # Adding elements into the list for index, item in enumerate(self.connection.message.information): elements = item.split('¥') self.trv_available.insert('', 'end', text=elements[0], values=(index + 1, summarize_text(elements[1], 375))) if len(self.trv_available.get_children()) != 0: self.trv_available.selection_set( self.trv_available.get_children()[0]) self.select_template_summary() def select_template_summary(self, event=None): """ Function activated when the event of selecting an item in the available templates TV is generated. It fills the summary text box with information of the selected template :param event: """ if self.trv_available.item( self.trv_available.selection())['text'] != '': # Clear summary txt box self.txt_summary['state'] = NORMAL self.txt_summary.delete('1.0', 'end-1c') self.id_selected = int( self.trv_available.item(self.trv_available.selection()) ['text']) # Retrieve id of selected item from TreeView self.directive = Message(action=40, information=[self.id_selected ]) # ask for the template self.connection = self.directive.send_directive(self.connection) # Insert template's name and description self.txt_summary.insert( 'end-1c', "Name:\n{}\n\n".format(self.connection.message.information[0])) self.txt_summary.insert( 'end-1c', "Description:\n{}\n\nSections:\n".format( self.connection.message.information[1])) self.directive = Message(action=77, information=[ self.id_selected ]) # ask for the sections of the selected template self.connection = self.directive.send_directive(self.connection) # Adding elements in the summary text box index = 0 for item in self.connection.message.information: elements = item.split('¥') self.txt_summary.insert('end-1c', "{}) {}\t\t{}\t\t{}\n".format(index + 1, elements[3], 'optional' \ if elements[7] == '' else 'mandatory', '' if elements[8] == '' else '(MAIN)')) index += 1 self.txt_summary['state'] = DISABLED def show_frm(self): self.retrieve_list() self.frm_child_list.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def hide_frm(self): self.clear_fields() self.frm_child_list.grid_forget() self.frm_child_crud.grid_forget() def click_new(self): self.view_decision = False # Decision when viewing a template self.template = Template() self.retrieve_sections() self.txt_name.focus_set() self.show_cu_buttons() self.frm_child_crud['text'] = 'New template' self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def click_view(self): if len(self.trv_available.selection()) == 1: self.view_decision = True # Decision when viewing a template self.directive = Message(action=40, information=[self.id_selected]) self.connection = self.directive.send_directive(self.connection) self.template = Template( id=self.id_selected, name=self.connection.message.information[0], description=self.connection.message.information[1], sections=self.connection.message.information[2]) self.txt_name.insert(0, self.template.name) self.txt_description.insert('1.0', self.template.description) self.retrieve_sections(self.template.sections) self.txt_name.focus_set() self.disable_visual_components() self.btn_back.grid(row=0, column=0, padx=5, pady=5, sticky=W) self.frm_child_list.grid_forget() self.frm_child_crud['text'] = 'View template' self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_update(self): if len(self.trv_available.selection()) == 1: self.view_decision = False # Decision when viewing a template self.directive = Message( action=40, information=[self.id_selected, 'validate']) self.connection = self.directive.send_directive(self.connection) if self.connection.message.action == 5: # An error ocurred while trying to update the item messagebox.showerror( parent=self.frm_child_list, title='Can not edit the template', message=self.connection.message.information[0]) else: self.template = Template( id=self.id_selected, name=self.connection.message.information[0], description=self.connection.message.information[1], sections=self.connection.message.information[2]) self.txt_name.insert(0, self.template.name) self.txt_description.insert('1.0', self.template.description) self.retrieve_sections(self.template.sections) self.txt_name.focus_set() self.show_cu_buttons() self.frm_child_crud['text'] = 'Update template' self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_delete(self): if len(self.trv_available.selection()) == 1: decision = messagebox.askyesno( parent=self.frm_child_list, title='Confirmation', message='Are you sure you want to delete the item?') if decision: self.directive = Message(action=39, information=[self.id_selected]) self.connection = self.directive.send_directive( self.connection) if self.connection.message.action == 5: # An error ocurred while deleting the item messagebox.showerror( parent=self.frm_child_list, title='Can not delete the item', message=self.connection.message.information[0]) else: self.retrieve_list() else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def show_cu_buttons(self): self.btn_add.grid(row=5, column=5, padx=25) self.btn_remove.grid(row=6, column=5, padx=25) self.btn_main_section.grid(row=2, column=10, padx=25) self.btn_down.grid(row=6, column=10, padx=25) self.btn_up.grid(row=5, column=10, padx=25) self.btn_save.grid(row=0, column=0, padx=5, pady=5, sticky=W) self.btn_cancel.grid(row=1, column=0, padx=5, pady=5, sticky=W) self.lbl_note_optional.grid(row=9, column=6, columnspan=4, sticky=W) def disable_visual_components(self): self.txt_name['bg'] = DISABLED_COLOR self.txt_description['bg'] = DISABLED_COLOR self.txt_name['state'] = DISABLED self.txt_description['state'] = DISABLED self.btn_add.grid_forget() self.btn_remove.grid_forget() self.btn_main_section.grid_forget() self.btn_down.grid_forget() self.btn_up.grid_forget() def retrieve_sections(self, s_sections=None): if s_sections is None: s_sections = [] self.directive = Message(action=32) self.connection = self.directive.send_directive(self.connection) a_sections = self.connection.message.information for item in self.trv_available_sections.get_children(): self.trv_available_sections.delete(item) for item in self.trv_selected_sections.get_children(): self.trv_selected_sections.delete(item) for item in s_sections: item_aux1 = item.split('¥')[2:6] item_aux2 = [item.split('¥')[-1]] item = item_aux1 + item_aux2 item = '¥'.join(item) if item in a_sections: a_sections.remove(item) for index, item in enumerate(a_sections): elements = item.split('¥') self.trv_available_sections.insert( '', 'end', text=elements[0], values=(index + 1, summarize_text(elements[1], 150), summarize_text(elements[3], 120))) for index, item in enumerate(s_sections): elements = item.split('¥') self.trv_selected_sections.insert( '', 'end', text=elements[2], values=(index + 1, summarize_text(elements[3], 150), summarize_text(elements[5], 120), elements[7], elements[8])) def click_add(self): """ Function that moves a 'Section' from available tree view to selected tree view (in frm_child_crud) """ if len(self.trv_available_sections.selection()) != 0 and len( self.trv_selected_sections.selection()) == 0: if len(self.trv_selected_sections.get_children()) != 0: index = self.trv_selected_sections.item( self.trv_selected_sections.get_children()[-1])['values'][0] else: index = 0 for row in self.trv_available_sections.selection(): index += 1 values = self.trv_available_sections.item(row)['values'] self.trv_selected_sections.insert( '', 'end', text=self.trv_available_sections.item(row)['text'], values=(index, values[1], values[2], '✓', '')) self.trv_available_sections.delete(row) def click_remove(self): """ Function that moves a 'Section' from selected tree view to available tree view (in frm_child_crud) """ if len(self.trv_selected_sections.selection()) != 0 and len( self.trv_available_sections.selection()) == 0: if len(self.trv_available_sections.get_children()) != 0: index = self.trv_available_sections.item( self.trv_available_sections.get_children() [-1])['values'][0] else: index = 0 for row in self.trv_selected_sections.selection(): index += 1 values = self.trv_selected_sections.item(row)['values'] self.trv_available_sections.insert( '', 'end', text=self.trv_selected_sections.item(row)['text'], values=(index, values[1], values[2])) self.trv_selected_sections.delete(row) def click_up(self): # Make sure only one item in 'selected sections' is selected if len(self.trv_selected_sections.selection()) == 1 and len( self.trv_available_sections.selection()) == 0: item = self.trv_selected_sections.selection() index = self.trv_selected_sections.index(item) self.trv_selected_sections.move(item, '', index - 1) def click_down(self): # Make sure only one item in 'selected sections' is selected if len(self.trv_selected_sections.selection()) == 1 and len( self.trv_available_sections.selection()) == 0: item = self.trv_selected_sections.selection() index = self.trv_selected_sections.index(item) self.trv_selected_sections.move(item, '', index + 1) def click_main_section(self): # Make sure a max of three items of 'selected sections' are selected if 4 > len(self.trv_selected_sections.selection()) > 0 and len( self.trv_available_sections.selection()) == 0: # First change all sections as normal (not main) for item in self.trv_selected_sections.get_children(): if self.trv_selected_sections.item(item)['values'][3] != '': values = self.trv_selected_sections.item(item)['values'] self.trv_selected_sections.item( item, values=(values[0], values[1], values[2], values[3], '')) # Set new main sections cont_error = False for row in self.trv_selected_sections.selection(): values = self.trv_selected_sections.item(row)['values'] if values[2] == 'Classification' or values[2] == 'Text': self.trv_selected_sections.item( row, values=(values[0], values[1], values[2], values[3], '✓')) else: # File sections can not be main cont_error = True if cont_error: messagebox.showwarning( parent=self.frm_child_crud, title='Main section(s)', message= "Main section(s) must be of 'Text' or 'Classification' data type" ) else: messagebox.showwarning( parent=self.frm_child_crud, title='Main section(s)', message= 'You must select a minimum of one and a maximum of three sections' ) def click_trv_asections(self, event): """ Function that removes selection from 'available' tree view when 'selected' tree view is selected (in frm_child_crud) """ self.trv_selected_sections.selection_remove( self.trv_selected_sections.selection()) def click_trv_ssections(self, event): """ Function that removes selection from 'selected' tree view when 'available' tree view is selected (in frm_child_crud) """ self.trv_available_sections.selection_remove( self.trv_available_sections.selection()) def click_save(self): if self.validate_fields(): self.template.name = self.txt_name.get() self.template.description = self.txt_description.get( '1.0', 'end-1c') if self.template.id == 0: # Creating a template self.directive = Message(action=36, information=[ self.template.name, self.template.description, [], [], [] ]) for item in self.trv_selected_sections.get_children(): values = self.trv_selected_sections.item(item)['values'] self.directive.information[2].append( int(self.trv_selected_sections.item(item)['text'])) self.directive.information[3].append(values[4]) if values[4] != '': self.directive.information[4].append('✓') else: self.directive.information[4].append(values[3]) else: # Updating a template self.directive = Message(action=38, information=[ self.template.id, self.template.name, self.template.description, [], [], [] ]) for item in self.trv_selected_sections.get_children(): values = self.trv_selected_sections.item(item)['values'] self.directive.information[3].append( int(self.trv_selected_sections.item(item)['text'])) self.directive.information[4].append(values[4]) if values[4] != '': self.directive.information[5].append('✓') else: self.directive.information[5].append(values[3]) self.connection = self.directive.send_directive(self.connection) self.clear_fields() self.frm_child_crud.grid_forget() self.show_frm() def click_cancel(self): decision = True if self.txt_name.get() != self.template.name or \ self.txt_description.get('1.0', 'end-1c') != self.template.description or \ len(self.trv_selected_sections.get_children()) != len(self.template.sections): decision = messagebox.askyesno( parent=self.frm_child_crud, title='Cancel', message='Are you sure you want to cancel?') if decision: self.click_back() def click_back(self): self.clear_fields() self.frm_child_crud.grid_forget() self.show_frm() def validate_fields(self): text_section = False if len(self.txt_name.get()) == 0: messagebox.showwarning(parent=self.frm_child_crud, title='Missing information', message='You must provide a name') return False if len(self.txt_description.get('1.0', 'end-1c')) == 0: messagebox.showwarning(parent=self.frm_child_crud, title='Missing information', message='You must provide a description') return False if len(self.trv_selected_sections.get_children()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must select at least one section') return False for item in self.trv_selected_sections.get_children(): values = self.trv_selected_sections.item(item)['values'] if values[2] == 'Text' or values[2] == 'Classification': text_section = True break if not text_section: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='At least one section has to be of text type') return False for item in self.trv_selected_sections.get_children(): values = self.trv_selected_sections.item(item)['values'] if values[4] == '✓': if values[2] == 'Text' or values[2] == 'Classification': return True else: messagebox.showwarning( parent=self.frm_child_crud, title='Main section', message= 'The main section has to be of text or classification type' ) return False messagebox.showwarning( parent=self.frm_child_crud, title='Main section', message='You must set one of the selected section as main') return False def clear_fields(self): self.txt_name['state'] = NORMAL self.txt_description['state'] = NORMAL self.txt_name['bg'] = ENABLED_COLOR self.txt_description['bg'] = ENABLED_COLOR self.txt_name.delete(0, END) self.txt_description.delete('1.0', 'end-1c') self.btn_save.grid_forget() self.btn_cancel.grid_forget() self.btn_back.grid_forget() self.lbl_note_optional.grid_forget() def click_switch_mandatory(self, event): if not self.view_decision: # Only if not viewing a template # Make sure only one item in 'selected sections' is selected if len(self.trv_selected_sections.selection()) == 1 and len( self.trv_available_sections.selection()) == 0: values = self.trv_selected_sections.item( self.trv_selected_sections.focus())['values'] if values[3] == '': self.trv_selected_sections.item( self.trv_selected_sections.focus(), values=(values[0], values[1], values[2], '✓', values[4])) else: self.trv_selected_sections.item( self.trv_selected_sections.focus(), values=(values[0], values[1], values[2], '', values[4]))
class FontChooser(tkfontchooser.FontChooser): def __init__(self, master, font_dict=None, text='AaBbYyZz', title='Font', **kwargs): Toplevel.__init__(self, master, **kwargs) self.title(title) try: self.wm_iconbitmap('transparent.ico') except TclError: pass self.resizable(False, False) self.protocol('WM_DELETE_WINDOW', self.quit) self._validate_family = self.register(self.validate_font_family) self._validate_size = self.register(self.validate_font_size) # --- variable storing the chosen font self.res = '' style = Style(self) style.configure('prev.TLabel') bg = style.lookup('TLabel', 'background') self.configure(bg=bg) # --- family list self.fonts = list(set(families())) self.fonts.append('TkDefaultFont') self.fonts.sort() for i in range(len(self.fonts)): self.fonts[i] = self.fonts[i].replace(' ', '\\ ') max_length = int(2.5 * max([len(font) for font in self.fonts])) // 3 - 2 self.sizes = ['%i' % i for i in (list(range(6, 17)) + list(range(18, 32, 2)) + list(range(36, 48, 4)))] # --- font default font_dict['weight'] = font_dict.get('weight', 'normal') font_dict['slant'] = font_dict.get('slant', 'roman') font_dict['underline'] = font_dict.get('underline', False) font_dict['overstrike'] = font_dict.get('overstrike', False) font_dict['family'] = font_dict.get('family', self.fonts[0].replace('\\ ', ' ')) font_dict['size'] = font_dict.get('size', 10) # --- format list self.formats = ['Regular', 'Italic', 'Bold', 'Bold Italic'] # --- creation of the widgets self.font_family = StringVar(self, ' '.join(self.fonts)) self.font_size = StringVar(self, ' '.join(self.sizes)) self.format_type = StringVar(self, self.formats) self.var_bold = BooleanVar(self, font_dict['weight'] == 'bold') self.var_italic = BooleanVar(self, font_dict['slant'] == 'italic') # ------ Size and family self.var_size = StringVar(self) self.entry_family = Entry(self, width=max_length, validate='key', validatecommand=(self._validate_family, '%d', '%S', '%i', '%s', '%V')) self.entry_size = Entry(self, width=8, validate='key', textvariable=self.var_size, validatecommand=(self._validate_size, '%d', '%P', '%V')) self.entry_format = Entry(self) self.list_family = Listbox(self, selectmode='browse', listvariable=self.font_family, highlightthickness=0, exportselection=False, width=max_length, height=6) self.list_size = Listbox(self, selectmode='browse', listvariable=self.font_size, highlightthickness=0, exportselection=False, width=6, height=6) self.list_format = Listbox(self, selectmode='browse', listvariable=self.format_type, highlightthickness=0, exportselection=False, width=12, height=6) self.scroll_family = Scrollbar(self, orient='vertical', command=self.list_family.yview) self.scroll_size = Scrollbar(self, orient='vertical', command=self.list_size.yview) self.scroll_format = Scrollbar(self, orient='vertical', command=self.list_format.yview) self.family_label = Label(self, text='Font:') self.style_label = Label(self, text='Font style:') self.size_label = Label(self, text='Size:') self.script_label = Label(self, text='Script:') self.script_box = Combobox(self, values=['Western']) self.more_fonts_label = Lbl(self, text='Show more fonts', underline=1, fg='blue', cursor='hand2') f = Font(self.more_fonts_label, self.more_fonts_label.cget("font")) f.configure(underline=True) self.more_fonts_label.configure(font=f) self.preview_font = Font(self, **font_dict) if len(text) > 30: text = text[:30] self.preview_window = LabelFrame(self, relief='groove', text='Sample', bd=1) # --- widget configuration self.list_family.configure(yscrollcommand=self.scroll_family.set) self.list_size.configure(yscrollcommand=self.scroll_size.set) self.list_format.configure(yscrollcommand=self.scroll_format.set) self.entry_family.insert(0, font_dict['family']) self.entry_family.selection_clear() self.entry_family.icursor('end') self.entry_format.insert(0, self.formats[1]) self.entry_format.selection_clear() self.entry_format.icursor('end') self.entry_size.insert(0, font_dict['size']) try: i = self.fonts.index(self.entry_family.get().replace(' ', '\\ ')) except ValueError: # unknown font i = 0 self.list_family.selection_clear(0, 'end') self.list_family.selection_set(i) self.list_family.see(i) try: i = self.sizes.index(self.entry_size.get()) self.list_size.selection_clear(0, 'end') self.list_size.selection_set(i) self.list_size.see(i) except ValueError: # size not in listtsg pass # font family location config self.family_label.grid(row=0, column=0, sticky='nsew', pady=(10, 1), padx=(10, 1)) self.entry_family.grid(row=1, column=0, sticky='nsew', pady=(1, 1), padx=(10, 0), columnspan=2) self.list_family.grid(row=2, column=0, sticky='nsew', pady=(1, 10), padx=(10, 0)) self.scroll_family.grid(row=2, column=1, sticky='ns', pady=(1, 10)) # font style/format location config self.style_label.grid(row=0, column=2, sticky='nsew', pady=(10, 1), padx=(15, 1)) self.entry_format.grid(row=1, column=2, sticky='nsew', pady=(1, 1), padx=(15, 0), columnspan=2) self.list_format.grid(row=2, column=2, sticky='nsew', pady=(1, 10), padx=(15, 0)) self.scroll_format.grid(row=2, column=3, sticky='ns', pady=(1, 10)) # font size location config self.size_label.grid(row=0, column=4, sticky='nsew', pady=(10, 1), padx=(15, 1)) self.entry_size.grid(row=1, column=4, sticky='nsew', pady=(1, 1), padx=(15, 10), columnspan=2) self.list_size.grid(row=2, column=4, sticky='nsew', pady=(1, 10), padx=(15, 0)) self.scroll_size.grid(row=2, column=5, sticky='nsew', pady=(1, 10), padx=(0, 10)) # font preview location config self.preview_window.grid(row=4, column=2, columnspan=4, sticky='nsew', rowspan=2, padx=15, pady=(0, 10), ipadx=10, ipady=10) self.preview_window.config(height=75) preview = Label(self.preview_window, text=text, font=self.preview_font, anchor='center') preview.place(relx=0.5, rely=0.5, anchor='center') self.script_label.grid(row=6, column=2, sticky='nsw', padx=(15, 0)) self.script_box.grid(row=7, column=2, sticky='nsw', pady=(1, 30), padx=(15, 0)) self.script_box.current(0) self.more_fonts_label.grid(row=8, column=0, pady=(35, 20), padx=(15, 0), sticky='nsw') button_frame = Frame(self) button_frame.grid(row=9, column=2, columnspan=4, pady=(0, 10), padx=(10, 0)) Button(button_frame, text='Ok', command=self.ok).grid(row=0, column=0, padx=4, sticky='ew') Button(button_frame, text='Cancel', command=self.quit).grid(row=0, column=1, padx=4, sticky='ew') self.list_family.bind('<<ListboxSelect>>', self.update_entry_family) self.list_format.bind('<<ListboxSelect>>', self.update_entry_format) self.list_size.bind('<<ListboxSelect>>', self.update_entry_size, add=True) self.list_family.bind('<KeyPress>', self.keypress) self.entry_family.bind('<Return>', self.change_font_family) self.entry_family.bind('<Tab>', self.tab) self.entry_size.bind('<Return>', self.change_font_size) self.more_fonts_label.bind('<Button-1>', search_fonts) self.entry_family.bind('<Down>', self.down_family) self.entry_size.bind('<Down>', self.down_size) self.entry_family.bind('<Up>', self.up_family) self.entry_size.bind('<Up>', self.up_size) self.bind_class('TEntry', '<Control-a>', self.select_all) self.wait_visibility(self) self.grab_set() self.entry_family.focus_set() self.lift() def update_entry_format(self, _): style = self.list_format.get(self.list_format.curselection()[0]) self.entry_format.delete(0, 'end') self.entry_format.insert(0, style) self.entry_format.selection_clear() self.entry_format.icursor('end') if style == self.formats[0]: self.var_italic = FALSE self.var_bold = FALSE elif style == self.formats[1]: self.var_italic = TRUE self.var_bold = FALSE elif style == self.formats[2]: self.var_italic = FALSE self.var_bold = TRUE elif style == self.formats[3]: self.var_italic = TRUE self.var_bold = TRUE else: log.error('invalid style') self.preview_font.configure(weight=['normal', 'bold'][self.var_bold], slant=['roman', 'italic'][self.var_italic])
class RollerGroup(LabelFrame): def __init__(self, mainframe, index): LabelFrame.__init__(self, mainframe) self.mainframe = mainframe self.index = index self.hist_index = 0 self.collapsed = False self.rollers = [] self.control_frame = Frame(None) default_font = ('Verdana', 10) self.name = StringVar() self.name.trace('w', self.mainframe.set_unsaved_title) self.expand_img = PhotoImage( data= b'R0lGODlhEAAQAIABAAAAAP///yH5BAEKAAEALAAAAAAQABAAAAIlhI+pq+EPHYo0TGjifRkfDYAdI33WUnZc6KmlyK5wNdMrg+dJAQA7' ) self.collapse_img = PhotoImage( data= b'R0lGODlhEAAQAIABAAAAAP///yH5BAEKAAEALAAAAAAQABAAAAIfhI+pq+EPHYo0zAovlme/y3CGmJCeeWqbirEVA8dLAQA7' ) self.collapse_btn = Button(self.control_frame, bd=0, image=self.collapse_img, command=self.show_hide) self.menu_btn = Menubutton(self.control_frame, bd=1, relief='solid', font=('Courier', 8), text='\u25e2', takefocus=1, highlightthickness=1) self.name_entry = Entry(self.control_frame, bd=1, relief='solid', font=('Verdana', 12), width=16, textvariable=self.name) self.history_frame = LabelFrame(self.control_frame, bd=1, text='History', relief='solid', font=default_font, labelanchor='w') self.roll_frame = LabelFrame(self.control_frame, bd=1, text='Roll', relief='solid', font=default_font, labelanchor='w') self.roll_img = PhotoImage( data= b'R0lGODlhDgARAIABAAAAAP///yH5BAEKAAEALAAAAAAOABEAAAIkjB+Ai6C83GOy0iqjM7ltPoFhKEKeKZJadynfVa6HlbAp3ZIFADs=' ) self.left_arrow = PhotoImage( data= b'R0lGODlhBwANAIABAAAAAP///yH5BAEKAAEALAAAAAAHAA0AAAITjA9nkMj+Apty2lvt0jt2VYFSAQA7' ) self.right_arrow = PhotoImage( data= b'R0lGODlhBwANAIABAAAAAP///yH5BAEKAAEALAAAAAAHAA0AAAITRI5gGLrnXlzT1NsidEkx/zFHAQA7' ) self.roll_btn = Button(self.roll_frame, bd=0, image=self.roll_img, height=24, command=self.roll_group) self.hist_prev_btn = Button( self.history_frame, bd=0, image=self.left_arrow, height=24, width=16, repeatdelay=250, repeatinterval=100, command=lambda: self.navigate_history(offset=-1)) self.hist_next_btn = Button( self.history_frame, bd=0, image=self.right_arrow, height=24, width=16, repeatdelay=250, repeatinterval=100, command=lambda: self.navigate_history(offset=1)) self.menu_btn.config(menu=self.create_menu()) self.collapse_btn.grid(row=0, column=0, padx=(4, 0)) self.menu_btn.grid(row=0, column=1, padx=(4, 0)) self.name_entry.grid(row=0, column=2, padx=(4, 0)) self.history_frame.grid(row=0, column=3, padx=(6, 0)) self.hist_prev_btn.grid(row=0, column=0, padx=(6, 0)) self.hist_next_btn.grid(row=0, column=1, padx=(0, 2)) self.roll_frame.grid(row=0, column=4, padx=(6, 4)) self.roll_btn.grid(row=0, column=0, padx=(6, 2)) self.config(relief='solid', labelwidget=self.control_frame) self.name.set('Group {}'.format(len(roller_groups) + 1)) self.grid(row=index, padx=4, pady=4, sticky='w') def show_hide(self): if self.collapsed: for roller in self.rollers: roller.grid() self.collapse_btn.config(image=self.collapse_img) self.collapsed = False else: for roller in self.rollers: roller.grid_remove() self.collapse_btn.config(image=self.expand_img) width = 28 + self.collapse_btn.winfo_width( ) + self.menu_btn.winfo_width() + self.name_entry.winfo_width() self.config(height=36, width=width) self.collapsed = True def create_menu(self): menu = Menu(self.menu_btn, tearoff=0, postcommand=maintain_group_indices) menu.add_command(label='Add', underline=0, command=self.add_group) menu.add_command(label='Clone', underline=0, command=lambda: self.add_group(clone=True)) menu.add_command(label='Up', underline=0, command=lambda: self.move_group(offset=-1)) menu.add_command(label='Down', underline=0, command=lambda: self.move_group(offset=1)) menu.add_separator() # ------------- menu.add_command(label='Clear history', underline=6, command=self.clear_history) menu.add_command(label='Remove', underline=0, command=self.remove_group) return menu def add_group(self, clone=False): destination_index = self.index + 1 group = RollerGroup(self.mainframe, destination_index) roller_groups.insert(group.index, group) for i in range(destination_index, len(roller_groups)): roller_groups[i].grid(row=i + 1) if clone: for roller in self.rollers: new_roller = Roller(group, self.rollers.index(roller)) new_roller.name.set(roller.name.get()) new_roller.dice_qty.set(roller.dice_qty.get()) new_roller.die_faces.set(roller.die_faces.get()) new_roller.modifier.set(roller.modifier.get()) new_roller.finalmod.set(roller.finalmod.get()) group.rollers.append(new_roller) group.name.set(self.name.get()) else: group.rollers.append(Roller(group, 0)) group.name.set(group.name.get()) maintain_tabstops() self.mainframe.editmenu.entryconfigure( self.mainframe.editmenu.index('end'), command=lambda: self.add_group(clone=clone)) self.mainframe.bind_all('<Control-r>', lambda e: self.add_group(clone=clone)) def move_group(self, offset=0, destination_index=0): if not destination_index: destination_index = self.index + offset if destination_index >= 0: group = roller_groups.pop(self.index) roller_groups.insert(destination_index, group) maintain_group_indices() self.name.set(self.name.get()) self.mainframe.editmenu.entryconfigure( self.mainframe.editmenu.index('end'), command=lambda: self.move_group(offset=offset)) self.mainframe.bind_all('<Control-r>', lambda e: self.move_group(offset=offset)) def clear_history(self): for roller in self.rollers: roller.reset() roller.history = [] self.history_frame.config(text='History') def remove_group(self, override=False): if len(roller_groups) > 1 or override: self.grid_remove() roller_groups.remove(self) self.name.set('') def maintain_roller_indices(self): for roller in self.rollers: roller.index = self.rollers.index(roller) roller.grid(row=roller.index) def roll_group(self): for roller in self.rollers: roller.roll() self.navigate_history() self.mainframe.editmenu.entryconfigure( self.mainframe.editmenu.index('end'), command=lambda: self.roll_group()) self.mainframe.bind_all('<Control-r>', lambda e: self.roll_group()) def navigate_history(self, offset=0, desired_index=0): hist_len = len(self.rollers[0].history) if not hist_len: return if not desired_index: desired_index = self.hist_index + offset if desired_index >= -1 and desired_index <= hist_len: if desired_index == -1: desired_index = 0 if desired_index == hist_len: desired_index = hist_len - 1 for roller in self.rollers: hist_dict = roller.history[desired_index] roller.results = hist_dict['results'] roller.dice_qty.set(hist_dict['dice_qty']) roller.die_faces.set(hist_dict['die_faces']) roller.modifier.set(hist_dict['modifier']) roller.results_text.set(hist_dict['results_text']) roller.finalmod.set(hist_dict['finalmod']) self.history_frame.config(text=hist_dict['timestamp']) self.hist_index = desired_index self.maintain_result_widths() def maintain_result_widths(self): for roller in self.rollers: w = len(roller.results_text.get()) if w > 80: w = 80 roller.results_entry.config(width=w)
class FormChildAED: def __init__(self, frm_parent, title, connection): self.connection = connection self.directive = Message() self.title = title self.decide = True self.id_selected = 0 self.frm_child_list = LabelFrame(frm_parent) self.frm_child_crud = LabelFrame(frm_parent) self.frm_child_crud.config(fg=TEXT_COLOR, font=SUBTITLE_FONT) self.initialize_components() def initialize_components(self): """ Method that initialize the visual components for each form associated with the local administration """ # Resources for the Forms self.new_icon = PhotoImage(file=r"./Resources/create.png") self.modify_icon = PhotoImage(file=r"./Resources/modify.png") self.remove_icon = PhotoImage(file=r"./Resources/delete.png") self.save_icon = PhotoImage(file=r"./Resources/save.png") self.cancel_icon = PhotoImage(file=r"./Resources/cancel.png") # Components for List Form lbl_sep1 = Label(self.frm_child_list) lbl_sep1.grid(row=0, column=0, padx=10, pady=25) self.trv_available = Treeview(self.frm_child_list, height=15, columns=('N', 'Name', 'Surname', 'E-mail')) self.trv_available.heading('#0', text='ID', anchor=CENTER) self.trv_available.heading('#1', text='N', anchor=CENTER) self.trv_available.heading('#2', text='Name', anchor=CENTER) self.trv_available.heading('#3', text='Surname', anchor=CENTER) self.trv_available.heading('#4', text='E-mail', anchor=CENTER) self.trv_available.column('#0', width=0, minwidth=50, stretch=NO) self.trv_available.column('#1', width=20, minwidth=20, stretch=NO) self.trv_available.column('#2', width=200, minwidth=200, stretch=NO) self.trv_available.column('#3', width=200, minwidth=200, stretch=NO) self.trv_available.column('#4', width=400, minwidth=400, stretch=NO) self.trv_available.grid(row=0, column=1, sticky=W, pady=25) vsb_trv_av = Scrollbar(self.frm_child_list, orient="vertical", command=self.trv_available.yview) vsb_trv_av.grid(row=0, column=2, pady=25, sticky=NS) self.trv_available.configure(yscrollcommand=vsb_trv_av.set) frm_aux4 = Frame(self.frm_child_list) btn_new = Button(frm_aux4, image=self.new_icon, command=self.click_new) btn_new.grid(row=0, column=0, pady=5, padx=5, sticky=E) btn_new_ttp = CreateToolTip(btn_new, 'New ' + self.title.lower()) btn_edit = Button(frm_aux4, image=self.modify_icon, command=self.click_update) btn_edit.grid(row=1, column=0, pady=5, padx=5, sticky=E) btn_edit_ttp = CreateToolTip(btn_edit, 'Edit ' + self.title.lower()) btn_delete = Button(frm_aux4, image=self.remove_icon, command=self.click_delete) btn_delete.grid(row=2, column=0, pady=5, padx=5, sticky=E) btn_delete_ttp = CreateToolTip(btn_delete, 'Delete ' + self.title.lower()) frm_aux4.grid(row=0, column=3, pady=25, padx=25, sticky=NW) # Components for CRUD FRM lbl_name = Label(self.frm_child_crud, text='Name*') lbl_name.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_name.grid(row=0, column=0, pady=10, padx=20, sticky=W) lbl_surname = Label(self.frm_child_crud, text='Surname*') lbl_surname.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_surname.grid(row=1, column=0, pady=10, padx=20, sticky=W) lbl_email = Label(self.frm_child_crud, text='E-mail*') lbl_email.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_email.grid(row=2, column=0, pady=10, padx=20, sticky=W) self.lbl_old_passwd = Label(self.frm_child_crud, text='Old password*') self.lbl_old_passwd.config(fg=TEXT_COLOR, font=LABEL_FONT) self.lbl_passwd = Label(self.frm_child_crud, text='New password*') self.lbl_passwd.config(fg=TEXT_COLOR, font=LABEL_FONT) self.lbl_passwd_conf = Label(self.frm_child_crud, text='Confirm new password*') self.lbl_passwd_conf.config(fg=TEXT_COLOR, font=LABEL_FONT) self.txt_name = Entry(self.frm_child_crud) self.txt_name.grid(row=0, column=1, pady=10, padx=20, sticky=W) self.txt_surname = Entry(self.frm_child_crud) self.txt_surname.grid(row=1, column=1, pady=10, padx=20, sticky=W) self.txt_email = Entry(self.frm_child_crud) self.txt_email.grid(row=2, column=1, pady=10, padx=20, sticky=W) self.txt_old_passwd = Entry(self.frm_child_crud, show="*") self.txt_passwd = Entry(self.frm_child_crud, show="*") self.txt_passwd_conf = Entry(self.frm_child_crud, show="*") sep_aux2 = Separator(self.frm_child_crud, orient=VERTICAL) sep_aux2.grid(row=0, column=2, sticky=NS, rowspan=6) frm_aux = Frame(self.frm_child_crud) btn_save = Button(frm_aux, image=self.save_icon, command=self.click_save) btn_save.grid(row=0, column=0, padx=5, pady=5, sticky=E) btn_save_ttp = CreateToolTip(btn_save, 'Save ' + self.title.lower()) btn_cancel = Button(frm_aux, image=self.cancel_icon, command=self.click_cancel) btn_cancel.grid(row=1, column=0, padx=5, pady=5, sticky=E) btn_cancel_ttp = CreateToolTip(btn_cancel, 'Cancel') frm_aux.grid(row=0, column=3, pady=10, padx=25, sticky=N, rowspan=6) def retrieve_list(self): """ Method that retrieve users information from the server and displays them in the TreeView from the List Form """ # Remove existing elements in the list for item in self.trv_available.get_children(): self.trv_available.delete(item) # Retrieve information from the server if self.title == 'Experimenter': self.directive = Message(action=17) elif self.title == 'Designer': self.directive = Message(action=22) elif self.title == 'Administrator': self.directive = Message(action=12) else: raise Exception('Error en recuperacion: tipo de usuario') self.connection = self.directive.send_directive(self.connection) # Adding elements in the list for index, item in enumerate(self.connection.message.information): elements = item.split('¥') self.trv_available.insert('', 'end', text=elements[0], values=(index + 1, elements[1], elements[2], elements[3])) # Mark first element of the treeview if exist if len(self.trv_available.get_children()) != 0: self.trv_available.selection_set( self.trv_available.get_children()[0]) def show_frm(self): """ Show the List form when the User administration is called """ self.retrieve_list() self.frm_child_list.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def hide_frm(self): """ Hide the User administration Forms """ self.clear_fields() self.frm_child_list.grid_forget() self.frm_child_crud.grid_forget() def click_new(self): """ Initialize CRUD Form for creating a new user. """ self.user = Designer() self.frm_child_list.grid_forget() self.txt_name.focus_set() self.frm_child_crud['text'] = 'New ' + self.title.lower() self.lbl_passwd.grid(row=3, column=0, pady=10, padx=20, sticky=W) self.lbl_passwd_conf.grid(row=4, column=0, pady=10, padx=20, sticky=W) self.txt_passwd.grid(row=3, column=1, pady=10, padx=20, sticky=W) self.txt_passwd_conf.grid(row=4, column=1, pady=10, padx=20, sticky=W) self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def click_update(self): """ Initialize CRUD Form for updating a user. It loads information of selected User into visual components """ if len(self.trv_available.selection()) == 1: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) if self.title == 'Experimenter': self.directive = Message(action=20, information=[id_selected]) elif self.title == 'Designer': self.directive = Message(action=25, information=[id_selected]) else: self.directive = Message(action=15, information=[id_selected]) self.connection = self.directive.send_directive(self.connection) if self.connection.message.action == 5: # An error ocurred while trying to update the item messagebox.showerror( parent=self.frm_child_list, title='Can not update the item', message=self.connection.message.information[0]) else: self.user = Designer( id=id_selected, name=self.connection.message.information[0], surname=self.connection.message.information[1], user=self.connection.message.information[2], password=self.connection.message.information[3]) self.txt_name.insert(0, self.user.name) self.txt_surname.insert(0, self.user.surname) self.txt_email.insert(0, self.user.user) self.frm_child_list.grid_forget() self.txt_name.focus_set() self.frm_child_crud['text'] = 'Update ' + self.title.lower() self.lbl_old_passwd.grid(row=3, column=0, pady=10, padx=20, sticky=W) self.lbl_passwd.grid(row=4, column=0, pady=10, padx=20, sticky=W) self.lbl_passwd_conf.grid(row=5, column=0, pady=10, padx=20, sticky=W) self.txt_old_passwd.grid(row=3, column=1, pady=10, padx=20, sticky=W) self.txt_passwd.grid(row=4, column=1, pady=10, padx=20, sticky=W) self.txt_passwd_conf.grid(row=5, column=1, pady=10, padx=20, sticky=W) self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_delete(self): """ Method that removes a selected user from the initial list (changes are updated in DB) """ if len(self.trv_available.selection()) == 1: decision = messagebox.askyesno( parent=self.frm_child_list, title='Confirmation', message='Are you sure you want to delete the item?') if decision: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) if self.title == 'Experimenter': self.directive = Message(action=19, information=[id_selected]) elif self.title == 'Designer': self.directive = Message(action=24, information=[id_selected]) else: self.directive = Message(action=14, information=[id_selected]) self.connection = self.directive.send_directive( self.connection) if self.connection.message.action == 5: # An error ocurred while deleting the item messagebox.showerror( parent=self.frm_child_list, title='Can not delete the item', message=self.connection.message.information[0]) else: self.retrieve_list() else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_save(self): """ Saves information of the user inserted into the visual components and sends to the server """ if self.validate_fields(): self.user.name = self.txt_name.get() self.user.surname = self.txt_surname.get() self.user.user = self.txt_email.get() self.user.password = self.txt_passwd.get() if self.user.id == 0: # Creating an user if self.title == 'Experimenter': self.directive = Message( action=16, information=[ self.user.name, self.user.surname, self.user.user, hashlib.sha1( self.user.password.encode()).hexdigest() ]) elif self.title == 'Designer': self.directive = Message( action=21, information=[ self.user.name, self.user.surname, self.user.user, hashlib.sha1( self.user.password.encode()).hexdigest() ]) else: self.directive = Message( action=11, information=[ self.user.name, self.user.surname, self.user.user, hashlib.sha1( self.user.password.encode()).hexdigest() ]) else: # Updating an user if self.title == 'Experimenter': self.directive = Message( action=18, information=[ self.user.id, self.user.name, self.user.surname, self.user.user, hashlib.sha1( self.user.password.encode()).hexdigest() ]) elif self.title == 'Designer': self.directive = Message( action=23, information=[ self.user.id, self.user.name, self.user.surname, self.user.user, hashlib.sha1( self.user.password.encode()).hexdigest() ]) else: self.directive = Message(action=13, information=[ self.user.id, self.user.name, self.user.surname, self.user.user, self.user.password ]) self.connection = self.directive.send_directive(self.connection) if self.connection.message.action == 5: messagebox.showwarning(parent=self.frm_child_crud, title='Repeated e-mail', message=self.connection.message.comment) else: self.clear_fields() self.frm_child_crud.grid_forget() self.show_frm() def click_cancel(self): """ Function activated when 'Cancel' button is pressed in frm_child_crud """ decision = True if self.txt_name.get() != self.user.name or \ self.txt_surname.get() != self.user.surname or \ self.txt_email.get() != self.user.user or len(self.txt_passwd.get()) != 0 or \ len(self.txt_passwd_conf.get()) != 0: if self.user.id != 0 and len( self.txt_passwd_conf.get()) != 0 or self.user.id == 0: decision = messagebox.askyesno( parent=self.frm_child_crud, title='Cancel', message='Are you sure you want to cancel?') if decision: self.clear_fields() self.frm_child_crud.grid_forget() self.show_frm() def validate_fields(self): if len(self.txt_name.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert a name for the {}'.format( self.title.lower())) return False if len(self.txt_surname.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert a surname for the {}'.format( self.title.lower())) return False if len(self.txt_email.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert an e-mail for the {}'.format( self.title.lower())) return False # If updating an user if self.user.id != 0 and len(self.txt_old_passwd.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert the old password for the {}'.format( self.title.lower())) return False if len(self.txt_passwd.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert a new password for the {}'.format( self.title.lower())) return False if len(self.txt_passwd_conf.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must confirm the new password for the {}'.format( self.title.lower())) return False if self.txt_passwd.get() != self.txt_passwd_conf.get(): messagebox.showwarning( parent=self.frm_child_crud, title='Password field', message= 'The new password you provided does not match the confirmation' ) return False # If updating an user if self.user.id != 0 and self.user.password != hashlib.sha1( self.txt_old_passwd.get().encode()).hexdigest(): messagebox.showwarning(parent=self.frm_child_crud, title='Old password field', message='The old password is incorrect') return False return True def clear_fields(self): self.txt_name.delete(0, END) self.txt_surname.delete(0, END) self.txt_email.delete(0, END) self.txt_old_passwd.delete(0, END) self.txt_passwd.delete(0, END) self.txt_passwd_conf.delete(0, END) self.lbl_old_passwd.grid_forget() self.lbl_passwd.grid_forget() self.lbl_passwd_conf.grid_forget() self.txt_old_passwd.grid_forget() self.txt_passwd.grid_forget() self.txt_passwd_conf.grid_forget()
class FormChildClassification: def __init__(self, frm_parent, connection): self.connection = connection self.directive = Message() self.decide = True self.id_selected = 0 self.frm_child_list = LabelFrame(frm_parent) self.frm_child_crud = LabelFrame(frm_parent) self.frm_child_crud.config(fg=TEXT_COLOR, font=SUBTITLE_FONT) self.initialize_components() def initialize_components(self): """ Method that initialize the visual components for each form associated with the local administration """ # Resources for the Forms self.new_icon = PhotoImage(file=r"./Resources/create.png") self.view_icon = PhotoImage(file=r"./Resources/view.png") self.modify_icon = PhotoImage(file=r"./Resources/modify.png") self.remove_icon = PhotoImage(file=r"./Resources/delete.png") self.save_icon = PhotoImage(file=r"./Resources/save.png") self.back_icon = PhotoImage(file=r"./Resources/back.png") self.cancel_icon = PhotoImage(file=r"./Resources/cancel.png") # Components for List FRM lbl_sep1 = Label(self.frm_child_list) lbl_sep1.grid(row=0, column=0, padx=10, pady=25) self.trv_available = Treeview(self.frm_child_list, height=15, columns=('N', 'Name', '# categories')) self.trv_available.heading('#0', text='ID', anchor=CENTER) self.trv_available.heading('#1', text='N', anchor=CENTER) self.trv_available.heading('#2', text='Name', anchor=CENTER) self.trv_available.heading('#3', text='# categories', anchor=CENTER) self.trv_available.column('#0', width=0, minwidth=50, stretch=NO) self.trv_available.column('#1', width=20, minwidth=20, stretch=NO) self.trv_available.column('#2', width=200, minwidth=200, stretch=NO) self.trv_available.column('#3', width=150, minwidth=150, stretch=NO) self.trv_available.grid(row=0, column=1, sticky=W, pady=25) vsb_trv_av = Scrollbar(self.frm_child_list, orient="vertical", command=self.trv_available.yview) vsb_trv_av.grid(row=0, column=2, pady=25, sticky=NS) self.trv_available.configure(yscrollcommand=vsb_trv_av.set) frm_aux4 = Frame(self.frm_child_list) btn_new = Button(frm_aux4, image=self.new_icon, command=self.click_new) btn_new.grid(row=0, column=0, pady=5, padx=5, sticky=E) btn_new_ttp = CreateToolTip(btn_new, 'New classification') btn_view = Button(frm_aux4, image=self.view_icon, command=self.click_view) btn_view.grid(row=1, column=0, pady=5, padx=5, sticky=E) btn_view_ttp = CreateToolTip(btn_view, 'View classification') btn_edit = Button(frm_aux4, image=self.modify_icon, command=self.click_update) btn_edit.grid(row=2, column=0, pady=5, padx=5, sticky=E) btn_edit_ttp = CreateToolTip(btn_edit, 'Edit classification') btn_delete = Button(frm_aux4, image=self.remove_icon, command=self.click_delete) btn_delete.grid(row=3, column=0, pady=5, padx=5, sticky=E) btn_delete_ttp = CreateToolTip(btn_delete, 'Delete classification') frm_aux4.grid(row=0, column=4, pady=25, padx=25, sticky=NW) # Components CRUD self.frm_class = LabelFrame(self.frm_child_crud) self.frm_class.config(fg=TEXT_COLOR, font=SUBTITLE_FONT) lbl_class = Label(self.frm_child_crud, text='Name*') lbl_class.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_class.grid(row=0, column=0, pady=10, padx=20, sticky=W) lbl_desc_categories = Label( self.frm_child_crud, text='Enter categories separated by an Enter (\\n)') lbl_desc_categories.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_desc_categories.grid(row=1, column=0, pady=10, padx=20, columnspan=4, sticky=W) lbl_categories = Label(self.frm_child_crud, text='Categories*') lbl_categories.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_categories.grid(row=2, column=0, pady=10, padx=20, sticky=NW) lbl_sep2 = Label(self.frm_child_crud) lbl_sep2.grid(row=2, column=1, padx=20, pady=10) self.txt_name_class = Entry(self.frm_child_crud, width=50, font=TEXT_FONT) self.txt_name_class.grid(row=0, column=2, columnspan=2, pady=10, sticky=W) self.txt_categories = Text(self.frm_child_crud, height=10, width=50, font=TEXT_FONT) self.txt_categories.grid(row=2, column=2, pady=10, sticky=W) vsb_txt_cat = Scrollbar(self.frm_child_crud, orient="vertical", command=self.txt_categories.yview) vsb_txt_cat.grid(row=2, column=3, pady=10, sticky=NS) self.txt_categories.configure(yscrollcommand=vsb_txt_cat.set) sep_aux1 = Separator(self.frm_child_crud, orient=VERTICAL) sep_aux1.grid(row=0, column=4, sticky=NS, rowspan=3, padx=20) self.btn_save = Button(self.frm_child_crud, image=self.save_icon, command=self.click_save) btn_save_ttp = CreateToolTip(self.btn_save, 'Save classification') self.btn_back = Button(self.frm_child_crud, image=self.back_icon, command=self.click_back) btn_back_ttp = CreateToolTip(self.btn_back, 'Go back') self.btn_cancel = Button(self.frm_child_crud, image=self.cancel_icon, command=self.click_cancel) btn_cancel_ttp = CreateToolTip(self.btn_cancel, 'Cancel') def retrieve_list(self): # Remove existing elements in the list for item in self.trv_available.get_children(): self.trv_available.delete(item) self.directive = Message(action=67) self.connection = self.directive.send_directive(self.connection) # Adding elements into the list for index, item in enumerate(self.connection.message.information): elements = item.split('¥') self.trv_available.insert('', 'end', text=elements[0], values=(index + 1, summarize_text(elements[1], 200), summarize_text(elements[2], 150))) if len(self.trv_available.get_children()) != 0: self.trv_available.selection_set( self.trv_available.get_children()[0]) def show_frm(self): self.retrieve_list() self.frm_child_list.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def hide_frm(self): self.clear_fields() self.frm_child_list.grid_forget() self.frm_child_crud.grid_forget() def click_new(self): self.classification = Classification() self.frm_child_crud['text'] = 'New Classification' self.txt_name_class.focus_set() self.btn_save.grid(row=0, column=5, padx=20) self.btn_cancel.grid(row=1, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) def click_view(self): if len(self.trv_available.selection()) == 1: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) # Retrieve selected classification from the database self.directive = Message(action=70, information=[id_selected]) self.connection = self.directive.send_directive(self.connection) self.classification = Classification( id=id_selected, name=self.connection.message.information[0], categories=self.connection.message.information[1]) # Insert information into visual components self.txt_name_class.insert(0, self.classification.name) # Section to insert categories in textbox length_string = 0 for item in self.classification.categories: elements = item.split('¥') self.txt_categories.insert('end-1c', elements[1] + '\n') length_string += len(elements[1]) + 1 self.txt_categories.delete('end-2c', 'end') self.frm_child_crud['text'] = 'View classification' self.txt_name_class['bg'] = DISABLED_COLOR self.txt_categories['bg'] = DISABLED_COLOR self.txt_name_class['state'] = DISABLED self.txt_categories['state'] = DISABLED self.btn_back.grid(row=0, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_update(self): if len(self.trv_available.selection()) == 1: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) self.directive = Message(action=70, information=[id_selected, 'validate']) self.connection = self.directive.send_directive(self.connection) if self.connection.message.action == 5: # An error ocurred while trying to update the item messagebox.showerror( parent=self.frm_child_list, title='Can not update the item', message=self.connection.message.information[0]) else: self.classification = Classification( id=id_selected, name=self.connection.message.information[0], categories=self.connection.message.information[1]) self.txt_name_class.insert(0, self.classification.name) # Section to insert categories in textbox length_string = 0 for item in self.classification.categories: elements = item.split('¥') self.txt_categories.insert('end-1c', elements[1] + '\n') length_string += len(elements[1]) + 1 self.txt_categories.delete('end-2c', 'end') self.frm_child_crud['text'] = 'Update classification' self.txt_name_class.focus_set() self.btn_save.grid(row=0, column=5, padx=20) self.btn_cancel.grid(row=1, column=5, padx=20) self.frm_child_list.grid_forget() self.frm_child_crud.grid(row=1, column=0, columnspan=9, rowspan=8, pady=10, padx=10) else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_delete(self): if len(self.trv_available.selection()) == 1: decision = messagebox.askyesno( parent=self.frm_child_list, title='Confirmation', message='Are you sure you want to delete the item?') if decision: id_selected = int( self.trv_available.item( self.trv_available.selection())['text']) self.directive = Message(action=69, information=[id_selected]) self.connection = self.directive.send_directive( self.connection) if self.connection.message.action == 5: # An error ocurred while deleting the item messagebox.showerror( parent=self.frm_child_list, title='Can not delete the item', message=self.connection.message.information[0]) else: self.retrieve_list() else: messagebox.showwarning(parent=self.frm_child_list, title='No selection', message='You must select one item') def click_save(self): if self.validate_fields(): self.classification.name = self.txt_name_class.get() if self.classification.id == 0: # Creating a new classification self.directive = Message( action=66, information=[self.classification.name]) self.connection = self.directive.send_directive( self.connection) self.classification.id = self.connection.message.information[0] self.classification.categories = self.txt_categories.get( '1.0', 'end-1c').split('\n') for item in self.classification.categories: if item: # None blank space will be saved self.directive = Message( action=71, information=[item, self.classification.id]) self.connection = self.directive.send_directive( self.connection) else: # Updating a classification self.directive = Message(action=68, information=[ self.classification.id, self.classification.name ]) self.connection = self.directive.send_directive( self.connection) # Delete categories associated with the current classification self.directive = Message(action=74, information=[self.classification.id]) self.connection = self.directive.send_directive( self.connection) # Create categories for the current classification self.classification.categories = self.txt_categories.get( '1.0', 'end-1c').split('\n') for item in self.classification.categories: if item: # None blank space will be saved self.directive = Message( action=71, information=[item, self.classification.id]) self.connection = self.directive.send_directive( self.connection) self.click_back() def click_back(self): self.clear_fields() self.frm_child_crud.grid_forget() self.show_frm() def click_cancel(self): decision = True categories_aux = len( self.txt_categories.get('1.0', 'end-1c').split('\n')) categories_aux = categories_aux - 1 if self.classification.id == 0 else categories_aux if self.txt_name_class.get() != self.classification.name or \ categories_aux != len(self.classification.categories): decision = messagebox.askyesno( parent=self.frm_child_crud, title='Cancel', message='Are you sure you want to cancel?') if decision: self.click_back() def validate_fields(self): if len(self.txt_name_class.get()) == 0: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert a name for the classification') return False if len(self.txt_categories.get('1.0', 'end-1c')) != 0: categories_aux = self.txt_categories.get('1.0', 'end-1c').split('\n') for item in categories_aux: for char in item: if char.isspace( ) or char == '\t' or not char or char == '\n': messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='A category can not be empty') return False return True else: messagebox.showwarning( parent=self.frm_child_crud, title='Missing information', message='You must insert at least one category') return False def clear_fields(self): self.btn_save.grid_forget() self.btn_cancel.grid_forget() self.btn_back.grid_forget() self.txt_name_class['state'] = NORMAL self.txt_categories['state'] = NORMAL self.txt_name_class['bg'] = ENABLED_COLOR self.txt_categories['bg'] = ENABLED_COLOR self.txt_name_class.delete(0, END) self.txt_categories.delete('1.0', 'end-1c')
class MyFirstGUI: def __init__(self, master): self.master = master master.minsize(width=640, height=480) master.title("Adove Fotoyop") self.release = True self.release2 = True self.next_canvas = 1 self.image_matrix = [] self.canvas = [ Canvas(master, width=200, height=200, cursor="crosshair"), Canvas(master, width=200, height=200, cursor="crosshair"), Canvas(master, width=200, height=200, cursor="crosshair"), Canvas(master, width=200, height=200, cursor="crosshair"), Canvas(master, width=200, height=200, cursor="crosshair"), Canvas(master, width=200, height=200, cursor="crosshair") ] self.saved_image = None self.true_image = None menubar = Menu(master) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Open", command=lambda: self.open(None, None)) filemenu.add_command(label="Open Video", command=lambda: self.open_video()) filemenu.add_command(label="Save", command=lambda: self.save(None)) filemenu.add_separator() filemenu.add_command(label="Exit", command=master.quit) menubar.add_cascade(label="File", menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label="Undo", command=self.undo, accelerator="Command+z") editmenu.add_command(label="Crop", command=lambda: actions.crop(self, master)) editmenu.add_command(label="Rotate", command=lambda: self.apply_method(actions.rotate)) editmenu.add_command( label="Grayscale", command=lambda: self.apply_method(actions.to_grayscale)) editmenu.add_separator() editmenu.add_command( label="Area Info", command=lambda: actions.get_area_info(self, master)) editmenu.add_command(label="To HSV", command=lambda: actions.rgb_to_hsv(self)) editmenu.add_separator() editmenu.add_command(label="Operations", command=lambda: actions.opr(self)) editmenu.add_command(label="Negative", command=lambda: actions.to_negative(self)) editmenu.add_command(label="Scalar Mult", command=lambda: actions.scalar_mult_textbox(self)) editmenu.add_command(label="Gamma", command=lambda: actions.gamma_textbox(self)) editmenu.add_command(label="Din. Range", command=lambda: actions.din_range(self, None)) menubar.add_cascade(label="Edit", menu=editmenu) datamenu = Menu(menubar, tearoff=0) datamenu.add_command(label="Histogram", command=lambda: actions.show_hist(self)) datamenu.add_command(label="Equalize", command=lambda: actions.equalize(self)) datamenu.add_command(label="Contrast", command=lambda: self.double_slider( "S1", "S2", actions.contrast, "Contrast")) menubar.add_cascade(menu=datamenu, label="Data") gimagemenu = Menu(menubar, tearoff=0) gimagemenu.add_command( label="Circle", command=lambda: self.apply_method(gen.generate_circle)) gimagemenu.add_command( label="Square", command=lambda: self.apply_method(gen.generate_square)) gimagemenu.add_command( label="Degrade", command=lambda: self.apply_method(gen.generate_degrade)) gimagemenu.add_command(label="Rayleigh", command=lambda: gen.generate_rayleigh(self)) gimagemenu.add_command(label="Gauss", command=lambda: gen.generate_gaussian(self)) gimagemenu.add_command(label="Exponential", command=lambda: gen.generate_exponential(self)) gimagemenu.add_command(label="Salt and Pepper", command=lambda: gen.generate_SAP(self)) menubar.add_cascade(label="Generate", menu=gimagemenu) filter_menu = Menu(menubar, tearoff=0) filter_menu.add_command(label="Mean", command=lambda: self.text_box( mesh.mean_filter, "Size", "Mean Filter")) filter_menu.add_command( label="Median", command=lambda: self.text_box(mesh.median_filter, "Size", "Median Filter")) filter_menu.add_command( label="Gauss", command=lambda: self.double_text_box(mesh.gauss_filter, "Size", "Sigma", "Gauss Filter")) filter_menu.add_command( label="Weighted Mean", command=lambda: self.apply_method(mesh.weighted_mean_filter, 3)) filter_menu.add_command( label="Weighted Median", command=lambda: self.apply_method(mesh.weighted_median_filter, 3)) filter_menu.add_command( label="High-Pass", command=lambda: self.apply_method(mesh.highpass_filter, 3)) menubar.add_cascade(menu=filter_menu, label="Filters") border_menu = Menu(menubar, tearoff=0) border_menu.add_command( label="Prewit", command=lambda: self.apply_method(border.prewit)) border_menu.add_command( label="Sobel", command=lambda: self.apply_method(border.sobel)) border_menu.add_command( label="Multi Prewit", command=lambda: self.apply_method(border.multi_prewit)) border_menu.add_command( label="Multi Sobel", command=lambda: self.apply_method(border.multi_sobel)) border_menu.add_separator() border_menu.add_command( label="Laplace", command=lambda: self.apply_method(border.laplace)) border_menu.add_command( label="Param Laplace", command=lambda: self.slider("Laplace", border.laplace)) border_menu.add_command( label="Intelligent Laplace", command=lambda: self.apply_method(border.intelligent_laplace)) border_menu.add_command( label="Laplace - Gauss", command=lambda: self.text_box(border.laplace_gauss, "Sigma", 'Laplace - Gauss')) border_menu.add_separator() border_menu.add_command(label="Hough", command=lambda: self.double_text_box( border.hough, "a", "b", "Hough", self)) border_menu.add_command(label="Contornos Activos", command=self.single_active_contours) border_menu.add_separator() border_menu.add_command( label="Harris", command=lambda: self.slider("Threshold", border.harris, "Harris")) menubar.add_cascade(menu=border_menu, label="Border") difansi = Menu(menubar, tearoff=0) difansi.add_command( label="Leclerc", command=lambda: self.double_text_box( anistropic.leclerc, "Iterations", "Sigma", "Leclerc")) difansi.add_command( label="Lorentziano", command=lambda: self.double_text_box( anistropic.lorentziano, "Iterations", "Sigma", "Lorentz")) difansi.add_command( label="Isotropic", command=lambda: self.text_box(anistropic.isotropic, "Iterations", "Isotropic")) menubar.add_cascade(menu=difansi, label="Dif") noise_menu = Menu(menubar, tearoff=0) noise_menu.add_command( label="Gaussian", command=lambda: actions.percentage_textbox(self, 'gaussian')) noise_menu.add_command( label="Rayleigh", command=lambda: actions.percentage_textbox(self, 'rayleigh')) noise_menu.add_command( label="Exponential", command=lambda: actions.percentage_textbox(self, 'exponential')) noise_menu.add_command(label="Salt & Pepper", command=lambda: actions.percentage_textbox( self, 'salt_and_pepper')) menubar.add_cascade(menu=noise_menu, label="Noise") threshold_menu = Menu(menubar, tearoff=0) threshold_menu.add_command( label="Global Threshold", command=lambda: self.apply_method(thresholds.global_threshold)) threshold_menu.add_command( label="Threshold", command=lambda: self.slider("Umbral", thresholds.threshold, "Threshold")) threshold_menu.add_command( label="Otsu", command=lambda: self.apply_method(thresholds.otsu)) menubar.add_cascade(menu=threshold_menu, label="Threshold") filemenu = Menu(menubar, tearoff=0) filemenu.add_command( label="Canny", command=lambda: self.apply_method(canny.canny_function)) filemenu.add_command( label="Susan All", command=lambda: self.apply_method(susan.susan_function)) menubar.add_cascade(label="Detector", menu=filemenu) video_menu = Menu(menubar, tearoff=0) video_menu.add_command(label="Contornos Activos", command=self.active_contours) menubar.add_cascade(label="Video", menu=video_menu) sift_menu = Menu(menubar, tearoff=0) sift_menu.add_command(label="SIFT", command=lambda: sift.main_sift_window(self)) menubar.add_cascade(label="Compare", menu=sift_menu) master.config(menu=menubar) self.menubar = menubar self.label_frame = LabelFrame(self.master, text="Operation") self.labels = [ Label(self.label_frame), Label(self.label_frame), Label(self.label_frame), Label(self.label_frame) ] self.entries = [ Entry(self.label_frame), Entry(self.label_frame), Entry(self.label_frame), Entry(self.label_frame) ] self.scales = [ Scale(self.label_frame, from_=0, to=255, orient="h", length=255), Scale(self.label_frame, from_=0, to=255, orient="h", length=255), Scale(self.label_frame, from_=0, to=255, orient="h", length=255), Scale(self.label_frame, from_=0, to=255, orient="h", length=255) ] self.accept = Button(self.label_frame, text="OK", width=10, height=1) self.cancel = Button(self.label_frame, text="Cancel", width=10, height=1) self.apply = Button(self.label_frame, text="Test", width=10, height=1) self.label_frame.grid(column=0, row=1) root.grid_columnconfigure(0, weight=1) root.grid_rowconfigure(1, weight=1) root.grid_rowconfigure(0, weight=1) root.bind_all("<Command-z>", self.undo) root.bind_all("<Command-c>", self.move_canvas) root.bind_all("<Command-n>", self.open) root.bind_all("<Command-b>", lambda e: self.open(e, "./src/BARCO.RAW")) root.bind_all("<Command-l>", lambda e: self.open(e, "./src/LENA.RAW")) root.bind_all("<Command-s>", self.save) self.canvas[0].grid(column=0, row=0) self.canvas[0].true_image = [] def open(self, event, name=None): if name is None: filename = filedialog.askopenfilename(parent=root) else: filename = name print(filename) if filename.find("RAW") != -1: with open('raw.json') as json_data: d = json.load(json_data) dim = d['data'][filename.rsplit(".", 1)[0].rsplit("/", 1)[1]] print(dim['x']) print(dim['y']) image = Image.frombytes('F', (dim['x'], dim['y']), open(filename, "rb").read(), 'raw', 'F;8') photo = ImageTk.PhotoImage(image) else: image = Image.open(filename) photo = ImageTk.PhotoImage(image) self.canvas[0].image = photo self.canvas[0].true_image = image self.true_image = image self.image_matrix = [] self.image_matrix.append(np.array(image)) width, height = image.size self.canvas[0].configure(width=width, height=height) self.image_on_canvas = self.canvas[0].create_image((0, 0), anchor="nw", image=photo) self.canvas[0].bind("<B1-Motion>", lambda e: self.set_area(e, 0, True)) self.canvas[0].bind("<ButtonRelease-1>", lambda e: self.release_left(e, 0, True)) self.canvas[0].bind("<B2-Motion>", lambda e: self.set_area(e, 0, False)) self.canvas[0].bind("<ButtonRelease-2>", lambda e: self.release_left(e, 0, False)) for i in range(len(self.canvas)): self.canvas[i].rect = self.canvas[i].create_rectangle( -1, -1, -1, -1, fill='', outline='#ff0000') self.canvas[i].rect2 = self.canvas[i].create_rectangle( -1, -1, -1, -1, fill='', outline='#0000ff') def open_video(self): filename = filedialog.askopenfilename(parent=root) self.video = [] i = 1 name = filename.rsplit(".", 1) try: while True: print(name[0][:(len(name[0]) - 1)] + str(i) + "." + name[1]) self.video.append( Image.open(name[0][:(len(name[0]) - 1)] + str(i) + "." + name[1])) i += 1 except FileNotFoundError: print(i) print(len(self.video)) self.canvas[0].image = ImageTk.PhotoImage(self.video[0]) self.canvas[0].true_image = self.video[0] self.true_image = self.video[0] self.image_matrix = [] self.image_matrix.append(np.array(self.video[0])) width, height = self.video[0].size self.canvas[0].configure(width=width, height=height) self.image_on_canvas = self.canvas[0].create_image( (0, 0), anchor="nw", image=self.canvas[0].image) self.canvas[0].bind("<B1-Motion>", lambda e: self.set_area(e, 0, True)) self.canvas[0].bind("<ButtonRelease-1>", lambda e: self.release_left(e, 0, True)) self.canvas[0].bind("<B2-Motion>", lambda e: self.set_area(e, 0, False)) self.canvas[0].bind("<ButtonRelease-2>", lambda e: self.release_left(e, 0, False)) for i in range(len(self.canvas)): self.canvas[i].rect = self.canvas[i].create_rectangle( -1, -1, -1, -1, fill='', outline='#ffff00') self.canvas[i].rect2 = self.canvas[i].create_rectangle( -1, -1, -1, -1, fill='', outline='#0000ff') def save(self, event): filename = filedialog.asksaveasfilename(parent=root) image = Image.fromarray( actions.linear_transform(np.array(self.true_image))) image.save(filename) print(filename) def text_box(self, callback, text, name="Operation"): def save(): self.forget() if self.entries[0].get() != "": self.load_on_canvas( callback(self.image_matrix[-1], int(self.entries[0].get()))) def apply(): self.true_image = Image.fromarray( callback(self.image_matrix[-1], int(self.entries[0].get()))) self.canvas[0].image = ImageTk.PhotoImage(self.true_image) self.canvas[0].create_image((0, 0), anchor="nw", image=self.canvas[0].image) self.cancel_gui() self.saved_image = Image.fromarray(self.image_matrix[-1]) self.set_label(text, 0) self.apply.grid(row=1, column=1) self.accept.grid(row=1, column=2) self.cancel.grid(row=1, column=0) self.apply.config(command=apply) self.accept.config(command=save) self.cancel.config(command=self.cancel_gui) self.label_frame.config(text=name) def double_text_box(self, callback, text1, text2, name="Operation", param1=None): def save(): if self.entries[0].get() != "" and self.entries[1].get() != "": if param1 is None: self.load_on_canvas( callback(np.array(self.saved_image), int(self.entries[0].get()), int(self.entries[1].get()))) elif param1 == self: callback(np.array(self.saved_image), int(self.entries[0].get()), int(self.entries[1].get()), param1) self.forget() def apply(): if param1 is None: self.true_image = Image.fromarray( callback(np.array(self.saved_image), int(self.entries[0].get()), int(self.entries[1].get()))) self.canvas[0].image = ImageTk.PhotoImage(self.true_image) self.canvas[0].create_image((0, 0), anchor="nw", image=self.canvas[0].image) elif param1 == self: callback(np.array(self.saved_image), int(self.entries[0].get()), int(self.entries[1].get()), param1) self.cancel_gui() self.saved_image = self.canvas[0].true_image self.set_label(text1, 0) self.set_label(text2, 1) self.apply.grid(row=2, column=1) self.accept.grid(row=2, column=2) self.cancel.grid(row=2, column=0) self.apply.config(command=apply) self.accept.config(command=save) self.cancel.config(command=self.cancel_gui) self.label_frame.config(text=name) def set_label(self, text, position): self.labels[position].config(text=text) self.labels[position].grid(row=position, column=0) self.entries[position].grid(row=position, column=1) def slider(self, text, callback, name="Operation"): def save(): self.load_on_canvas(np.asarray(self.true_image)) self.forget() def apply(event): self.true_image = Image.fromarray( callback(np.array(self.saved_image), int(self.scales[0].get()))) self.canvas[0].image = ImageTk.PhotoImage(self.true_image) self.canvas[0].create_image((0, 0), anchor="nw", image=self.canvas[0].image) self.cancel_gui() self.saved_image = self.canvas[0].true_image self.set_slider(0, text, apply) self.accept.grid(row=2, column=0) self.cancel.grid(row=2, column=1) self.accept.config(command=save) self.cancel.config(command=self.cancel_gui) self.label_frame.config(text=name) def double_slider(self, text1, text2, callback, name="Operation"): def save(): self.load_on_canvas(np.asarray(self.true_image)) self.forget() def apply(event): self.true_image = Image.fromarray( callback(np.array(self.saved_image), self.scales[0].get(), self.scales[1].get())) self.canvas[0].image = ImageTk.PhotoImage(self.true_image) self.canvas[0].create_image((0, 0), anchor="nw", image=self.canvas[0].image) self.cancel_gui() self.saved_image = self.canvas[0].true_image self.set_slider(0, text1, apply) self.set_slider(1, text2, apply) self.accept.grid(row=2, column=0) self.cancel.grid(row=2, column=1) self.accept.config(command=save) self.cancel.config(command=self.cancel_gui) self.label_frame.config(text=name) def set_slider(self, position, text, func): self.labels[position].config(text=text) self.labels[position].grid(row=0, column=position * 2, columnspan=2) self.scales[position].bind("<ButtonRelease-1>", func) self.scales[position].set(128) self.scales[position].grid(row=1, column=position * 2, columnspan=2) def apply_method(self, method, param=-1): if param == -1: self.load_on_canvas(method(np.array(self.canvas[0].true_image))) elif param == self: method(np.array(self.canvas[0].true_image), param) else: self.load_on_canvas( method(np.array(self.canvas[0].true_image), param)) def active_contours(self): # avg = actions.get_area_info(self, np.array(self.canvas[0].true_image)) self.canvas[0].coords(self.canvas[0].rect, -1, -1, -1, -1) self.canvas[0].coords(self.canvas[0].rect2, -1, -1, -1, -1) matrixes = [] self.canvas[0].rect for i in range(len(self.video)): matrixes.append(np.array(self.video[i], dtype=np.uint8)) start = timer() phi, lin, lout, theta0, theta1 = video.pixel_exchange_border_detect( matrixes[0], (self.x_start, self.x_finish, self.y_start, self.y_finish), (self.x2_start, self.x2_finish, self.y2_start, self.y2_finish)) end = timer() print("First time: " + str(end - start)) self.paint_pixels(matrixes[0], lout) start = timer() for i in range(1, len(self.video)): phi, lin, lout, theta0, theta1 = video.apply_pixel_exchange( matrixes[i], phi, lin, lout, theta0, theta1) self.paint_pixels(matrixes[i], lout) end = timer() print("Others: " + str(end - start)) def single_active_contours(self): self.canvas[0].coords(self.canvas[0].rect, -1, -1, -1, -1) self.canvas[0].coords(self.canvas[0].rect2, -1, -1, -1, -1) start = timer() phi, lin, lout, theta0, theta1 = video.pixel_exchange_border_detect( np.array(self.canvas[0].true_image), (self.x_start, self.x_finish, self.y_start, self.y_finish), (self.x2_start, self.x2_finish, self.y2_start, self.y2_finish)) end = timer() print(end - start) self.paint_pixels(np.array(self.canvas[0].true_image), lout) def paint_pixels(self, matrix, pixels): for i in pixels: matrix[i[0], i[1]] = (0, 0, 255) self.canvas[0].ti = Image.fromarray(matrix) self.canvas[0].i = ImageTk.PhotoImage(self.canvas[0].ti) self.canvas[0].itemconfig(self.image_on_canvas, image=self.canvas[0].i) self.canvas[0].update() def cancel_gui(self): if self.saved_image is not None: self.true_image = self.saved_image self.canvas[0].image = ImageTk.PhotoImage(self.true_image) self.canvas[0].create_image((0, 0), anchor="nw", image=self.canvas[0].image) self.forget() def forget(self): for e in self.labels: e.grid_forget() for e in self.entries: e.grid_forget() for e in self.scales: e.grid_forget() self.cancel.grid_forget() self.accept.grid_forget() self.apply.grid_forget() self.saved_image = None print("Forgotten") def load_on_canvas(self, matrix): self.image_matrix += [matrix] self.canvas[0].true_image = Image.fromarray(self.image_matrix[-1]) self.canvas[0].image = ImageTk.PhotoImage(self.canvas[0].true_image) self.canvas[0].create_image((0, 0), anchor="nw", image=self.canvas[0].image) def undo(self, event=None): self.image_matrix.pop() self.canvas[0].true_image = Image.fromarray(self.image_matrix[-1]) self.canvas[0].image = ImageTk.PhotoImage(self.canvas[0].true_image) self.canvas[0].create_image((0, 0), anchor="nw", image=self.canvas[0].image) def move_canvas(self, event): self.canvas[self.next_canvas].true_image = Image.fromarray( self.image_matrix[-1]) self.canvas[self.next_canvas].image = ImageTk.PhotoImage( self.canvas[self.next_canvas].true_image) self.canvas[self.next_canvas].create_image( (0, 0), anchor="nw", image=self.canvas[self.next_canvas].image) self.canvas[self.next_canvas].grid(row=0, column=self.next_canvas) self.canvas[self.next_canvas].configure( width=self.image_matrix[-1].shape[1], height=self.image_matrix[-1].shape[0]) index = self.next_canvas self.canvas[self.next_canvas].bind("<B1-Motion>", lambda e: self.set_area(e, index)) self.canvas[self.next_canvas].bind( "<ButtonRelease-1>", lambda e: self.release_left(e, index)) self.next_canvas += 1 def set_area(self, event, index, left): if (left): if self.release: self.x_start = event.x self.x_finish = event.x else: self.x_finish = event.x if self.release: self.y_start = event.y self.y_finish = event.y self.release = False else: self.y_finish = event.y self.canvas[index].coords(self.canvas[index].rect, self.x_start, self.y_start, self.x_finish, self.y_finish) self.canvas[index].tag_raise(self.canvas[index].rect) else: if self.release2: self.x2_start = event.x self.x2_finish = event.x else: self.x2_finish = event.x if self.release2: self.y2_start = event.y self.y2_finish = event.y self.release2 = False else: self.y2_finish = event.y self.canvas[index].coords(self.canvas[index].rect2, self.x2_start, self.y2_start, self.x2_finish, self.y2_finish) self.canvas[index].tag_raise(self.canvas[index].rect2) def release_left(self, event, index, left): if left: self.release = True actions.get_area_info(self, np.array(self.canvas[index].true_image), left) else: self.release2 = True actions.get_area_info(self, np.array(self.canvas[index].true_image), left)
class App_Photo(object): """docstring for App_Photo""" def __init__(self, master, pil_photo, styles, root, fullsize_path, hide_cmd=None, del_cmd=None): super(App_Photo, self).__init__() self.master = master self.pil_photo = pil_photo self.fullsize_path = fullsize_path self.photo = PIL.ImageTk.PhotoImage(pil_photo) self.styles = styles self.tool_styles = styles.copy() self.tool_styles['big_font'] = styles['font'] self.tool_styles['padx'] = 5 self.tool_styles['pady'] = 3 self.root = root self.hide_cmd = hide_cmd self.del_cmd = del_cmd self.putPhoto() def putPhoto(self): self.wrapper = LabelFrame(self.master, bg=self.styles['bg'], borderwidth=0) self.photo_label = Label(self.wrapper, image=self.photo, borderwidth=0, cursor="hand2") self.photo_label.bind("<Button-1>", self.zoom) self.photo_label.bind("<Enter>", self.show_tools) self.photo_label.bind("<Leave>", self.hide_tools) self.photo_label.image = self.photo self.photo_label.pack() self.minimize_tool = App_Button(self.wrapper, text="➖", styles=self.tool_styles, command=self.hide_cmd) self.minimize_tool.bind_wrapper("<Enter>", self.show_tools) self.minimize_tool.place(x=0, y=0) self.minimize_tool.place_forget() self.delete_tool = App_Button(self.wrapper, text="✕", styles=self.tool_styles, command=self.del_cmd) self.delete_tool.bind_wrapper("<Enter>", self.show_tools) self.delete_tool.place(x=0, y=0) self.delete_tool.place_forget() self.overlay = LabelFrame(self.root, bg=self.styles['overlay'], fg=self.styles['overlay'], borderwidth=0) self.overlay_close = App_Button(self.overlay, text="⩁", title="Close the zoomed view", styles=self.styles, command=self.un_zoom) self.overlay_close.place(x=0, y=0) def zoom(self, event): window_width = self.root.winfo_width() window_height = self.root.winfo_height() self.overlay.config(width=window_width) self.overlay.config(height=window_height) self.overlay.place(x=0, y=0) zoomed_width = int(window_width * 0.8) zoomed_height = int(window_height * 0.8) pil_photo = PIL.Image.open(self.fullsize_path) wpercent = (zoomed_width/float(pil_photo.size[0])) hsize = int((float(pil_photo.size[1])*float(wpercent))) zoomed_pil_photo = pil_photo.resize((zoomed_width,hsize), PIL.Image.ANTIALIAS) hpercent = (zoomed_height/float(pil_photo.size[1])) wsize = int((float(pil_photo.size[0])*float(hpercent))) zoomed_pil_photo = pil_photo.resize((wsize,zoomed_height), PIL.Image.ANTIALIAS) zoomed_photo = PIL.ImageTk.PhotoImage(zoomed_pil_photo) self.zoomed_photo_label = Label(self.root, image=zoomed_photo, borderwidth=0) self.zoomed_photo_label.image = zoomed_photo self.zoomed_photo_label.pack() photo_x_pos = (window_width / 2) - (wsize / 2) photo_y_pos = (window_height / 2) - (zoomed_height / 2) overlay_close_width = self.overlay_close.winfo_width() self.overlay_close.place(x=window_width-overlay_close_width-25, y=25) self.zoomed_photo_label.place(x=photo_x_pos, y=photo_y_pos) def un_zoom(self): self.overlay.place_forget() self.zoomed_photo_label.place_forget() def show_tools(self, event): photo_x = self.photo_label.winfo_x() photo_y = self.photo_label.winfo_y() photo_width = self.photo_label.winfo_width() minimize_tool_width = self.minimize_tool.winfo_width() delete_tool_width = self.delete_tool.winfo_width() minimize_tool_x_pos = photo_x + photo_width - minimize_tool_width - delete_tool_width - 5 delete_tool_x_pos = photo_x + photo_width - delete_tool_width tool_y_pos = photo_y + 5 self.minimize_tool.place(x=minimize_tool_x_pos, y=tool_y_pos) self.delete_tool.place(x=delete_tool_x_pos, y=tool_y_pos) def hide_tools(self, event): self.minimize_tool.place_forget() self.delete_tool.place_forget() def bind(self, *args, **kwargs): self.wrapper.bind(*args, **kwargs) def pack(self, *args, **kwargs): self.wrapper.pack(*args, **kwargs) def destroy(self, *args, **kwargs): self.wrapper.destroy(*args, **kwargs)