class StrategyShareToplevel(Parent): """ Toplevel to display a list of strategy with checkboxes to allow selecting which should be shared. """ def __init__(self, master, client, database, strategy_frame, **kwargs): """ :param master: master widget :param client: network.strategy.client.StrategyClient :param database: results.strategies.StrategyDataBase :param strategy_frame: frames.strategy.StrategyFrame :param kwargs: SnapToplevel keyword arguments """ resizable = kwargs.pop("resizable", False) self._client = client self._database = database self._frame = strategy_frame Parent.__init__(self, master, **kwargs) self.wm_title("GSF Parser: Strategy Sharing") self.wm_resizable(resizable, resizable) # Configure the Treeview self.tree = CheckboxTreeview(master=self, height=16) self.tree.column("#0", width=200) self.tree.heading("#0", text="Strategy") self.tree.config(show=("headings", "tree")) self.scroll_bar = ttk.Scrollbar(self, orient=tk.VERTICAL, command=self.tree.yview) self.tree.config(yscrollcommand=self.scroll_bar.set) self.update_strategy_tree() self.share_button = ttk.Button(self, text="Share Strategies", command=self.share_strategies) self.grid_widgets() def grid_widgets(self): self.tree.grid(row=1, column=1, sticky="nswe", padx=5, pady=5) self.scroll_bar.grid(row=1, column=2, sticky="ns", padx=(0, 5), pady=5) self.share_button.grid(row=2, column=1, columnspan=2, sticky="nswe", padx=5, pady=(0, 5)) def share_strategies(self): for strategy in self.strategies_to_share: self._client.send_strategy(strategy) messagebox.showinfo("Info", "Selected Strategies sent.") def update_strategy_tree(self): self.tree.delete(*self.tree.get_children("")) for strategy in sorted(self._database.keys()): self.tree.insert("", tk.END, iid=strategy, text=strategy) @property def strategies_to_share(self): for strategy in self.tree.get_checked(): yield self._database[strategy]
class TreeviewConstructor(object): logger = CustomAdapter(logging.getLogger(str(__name__)), None) @debug(lvl=logging.NOTSET, prefix='') def __init__(self, master, frame_main, checkwidth=0): self.master = master # Done self.frame = frame_main # Done self.col_obj_dict = {} # Done self.column_lst = [] # Done self.col_disp_lst = [] # Done self.item_obj_dict = {} self.treeview = CheckboxTreeview(self.frame) # Done self.ysb = ttk.Scrollbar(self.frame) # Done self.xsb = ttk.Scrollbar(self.frame) # Done self.checkwidth = checkwidth self.manager = BusyManager(self.frame) self.populate_frame() # Done @debug(lvl=logging.NOTSET, prefix='') def populate_frame(self): self.frame.columnconfigure(0, weight=1) # Done self.frame.rowconfigure(0, weight=1) # Done self.treeview.grid(row=0, column=0, sticky=tk.NSEW) # Done self.ysb.config(orient=tk.VERTICAL, command=self.treeview.yview) # Done self.xsb.config(orient=tk.HORIZONTAL, command=self.treeview.xview) # Done self.treeview['yscroll'] = self.ysb.set # Done self.treeview['xscroll'] = self.xsb.set # Done self.ysb.grid(row=0, column=1, sticky=tk.NS) # Done self.xsb.grid(row=1, column=0, sticky=tk.EW) # Done @debug(lvl=logging.NOTSET, prefix='') def populate_cols(self): col_obj = TreeColumn(order=0, col_id='#0', hdr_txt="", anchor=tk.W, stretch=tk.NO, minwidth=0, width=self.checkwidth, display=False) TreeviewConstructor.logger.log(logging.NOTSET, "Column ID: {col_id} Header Text: {hdr_txt}". format(col_id=col_obj.col_id, hdr_txt=col_obj.hdr_txt)) self.col_obj_dict[col_obj.col_id] = col_obj for col_key, column in sorted(self.col_obj_dict.items(), key=lambda x: x[1].order): self.column_lst.append(column.col_id) if column.display: self.col_disp_lst.append(column.col_id) self.treeview.config(columns=self.column_lst, displaycolumns=self.col_disp_lst) self.treeview.tag_configure('red', foreground='red2') self.treeview.tag_configure('evenrow', background='gray85') self.treeview.tag_configure('oddrow', background='white') for col in self.col_obj_dict.values(): TreeviewConstructor.logger.log( logging.NOTSET, "Column ID: {col_id} Header Text: {hdr_txt} Anchor: {anchor}".format( col_id=col.col_id, hdr_txt=col.hdr_txt, anchor=col.anchor)) if col.hdr_txt in (None, ""): header = col.col_id else: header = col.hdr_txt self.treeview.heading(column=col.col_id, text=header, anchor=col.anchor, command=lambda _col=col.col_id: self.treeview_sort_column(_col, False)) self.treeview.column(col.col_id, minwidth=col.minwidth, width=col.width, stretch=col.stretch) @debug(lvl=logging.DEBUG, prefix='') def populate_items(self): for item in self.item_obj_dict.values(): TreeRow.logger.log(logging.NOTSET, "Item Info: {0}".format(item.iid)) self.treeview.insert(item.parent, item.index, iid=item.iid, values=item.values_list) for tag in item.tags_list: self.treeview.tag_add(item.iid, tag) @debug(lvl=logging.DEBUG, prefix='') def stripe_rows(self): for item in self.item_obj_dict.values(): self.treeview.tag_del(item.iid, 'evenrow') self.treeview.tag_del(item.iid, 'oddrow') row_num = self.treeview.index(item.iid) if row_num % 2 == 0: self.treeview.tag_add(item.iid, 'evenrow') elif row_num % 2 != 0: self.treeview.tag_add(item.iid, 'oddrow') @debug(lvl=logging.DEBUG, prefix='') def treeview_sort_column(self, col, reverse): self.manager.busy() item_list = [(self.treeview.set(k, col), k) for k in self.treeview.get_children('')] item_list.sort(reverse=reverse) # rearrange items in sorted positions for index, (val, k) in enumerate(item_list): self.treeview.move(k, '', index) self.stripe_rows() # reverse sort next time self.treeview.heading(col, command=lambda: self.treeview_sort_column(col, not reverse)) self.manager.not_busy() @debug(lvl=logging.DEBUG, prefix='') def tv_refresh(self): # self.manager.busy() item_list = list(self.treeview.get_children('')) item_list.sort(key=lambda x: int(x)) for item_iid, item_obj in sorted(self.item_obj_dict.items()): TreeRow.logger.log(logging.NOTSET, "Item ID: {0}".format(item_iid)) # l = self.treeview.get_children('') for index, k in enumerate(item_list): TreeRow.logger.log(logging.NOTSET, "k: {0}".format(k)) if str(item_iid) == str(k): self.treeview.delete(k) item_obj.index = index self.treeview.insert(item_obj.parent, item_obj.index, iid=item_obj.iid, values=item_obj.values_list) item_list.remove(k) break self.stripe_rows()
class search_display(cache_maintenance): ######################### # Field Populators # ######################### def taxon_branch_builder(self,database,key): # Populates tree branches with data # Set Taxon Dictionary dictionary = database[key] # Create Root top=self.search_tree.insert("", "end", dictionary['iid'], text=dictionary['name'], values=(dictionary['type'],dictionary['definition']),open = True) def individual_branch_builder(child_dictionary,parent_branch): # Recursive Function to Go Through an Unknown Number of Layers alpha_child_taxonomy = self.database_alphabetiser(child_dictionary) for taxon in alpha_child_taxonomy: # Create Lambda Dictionary x, d = -1, {} # Go Through Every Key (Numerical Values) in Current "children" Dictionary for new_key,new_dictionary in child_dictionary.items(): if new_dictionary['iid'] == taxon: # Advance Branch Lambda Variable x = x + 1 # Create New Branch d[x+1]=self.search_tree.insert(parent_branch, "end", new_dictionary['iid'], text=new_dictionary['name'],values=(new_dictionary['type'],new_dictionary['definition']),open = False) # Re-Run Recursive Function with New "children" Dictionary individual_branch_builder(new_dictionary['children'],d[x+1]) # Begin Recursive Function individual_branch_builder(dictionary['children'],top) ######################### # Event Processing # ######################### def get_checked_annotations(self): self.annotation_list = (self.search_tree.get_checked()) for annotation in self.annotation_list: # If that Item has a Parent and that Parent is not Already in the List if self.search_tree.parent(annotation) != "" and self.search_tree.parent(annotation) not in self.annotation_list: # Add Parent Item to the List self.annotation_list.append(self.search_tree.parent(annotation)) self.taxon_list_displayer(self.taxonomy,self.annotation_list) def result_viewer(self,event): segment_event_data = event.widget segment_selection = segment_event_data.curselection()[0] selection_coordinates = self.export_list[segment_selection] self.segment_displayer(selection_coordinates) def taxon_informer(self,event): # Send Selected ID to Iterator # Get Selected ID from Click Event self.clicked_item = self.search_tree.identify('item',event.x,event.y) # Send to iid_iterator self.iid_iterator(self.taxonomy,self.annotation_list,self.taxon_list_displayer) ##################### # Panel Display # ##################### def note_displayer(self,selection_coordinates): # Display notes on segment self.note_text = Text(self.pane_two_bottom_right, wrap=WORD) self.note_text.configure(font=(10)) self.note_text.pack(anchor="nw", expand=Y, fill=BOTH) try: full_note = self.database[selection_coordinates[0]]['items'][selection_coordinates[1]]['segments'][selection_coordinates[2]]['nisaba:notes'] except(KeyError): pass else: note = full_note[0] signature = full_note[1] date = '{}/{}/{}'.format(full_note[2][6:8],full_note[2][4:6],full_note[2][:4]) notes = '{} -{} ({})'.format(note,signature,date) self.note_text.insert("0.0",notes) def segment_displayer(self,selection_coordinates): self.pane_two_bottom_left.destroy() self.pane_two_bottom_right.destroy() self.pane_two_bottom_left = ttk.Frame(self.search_window) self.pane_two_bottom_left.place(relx=.25, rely = .45, relwidth=.32, relheight=.4) self.pane_two_bottom_right = ttk.Frame(self.search_window) self.pane_two_bottom_right.place(relx=.65, rely = .45, relwidth=.32, relheight=.4) self.collection_index = selection_coordinates[0] self.item_index = selection_coordinates[1] self.segment_index = selection_coordinates[2] # If the Segment is Text if self.database[self.collection_index]['items'][self.item_index]['item_type'] == 't': # Pull segmentation data start = self.database[self.collection_index]['items'][self.item_index]['segments'][self.segment_index]['start'] end = self.database[self.collection_index]['items'][self.item_index]['segments'][self.segment_index]['end'] # Create Text Box self.transcription_text = Text(self.pane_two_bottom_left, wrap=WORD) # Populate Text Box # Pull Transcription from self.database self.transcription_words = self.database[self.collection_index]['items'][self.item_index]['transcription'][0].split() # Get Snippets pre_start = start-20 if start > 20 else 0 pre_transcription = ' '.join(self.transcription_words[pre_start:start]) + " " transcription = ' '.join(self.transcription_words[start:end]) + " " post_transcription = ' '.join(self.transcription_words[end:end+20]) # Set Highlighting / Background Colours self.transcription_text.tag_config("faded", foreground="light gray", font=(10)) self.transcription_text.tag_config("normal", font=(10)) # Clear Existing Text self.transcription_text.insert(END,"...") self.transcription_text.delete("0.0",END) # Insert Snippet Text self.transcription_text.insert("0.0",pre_transcription[1:],('faded')) self.transcription_text.insert(END,transcription,('normal')) self.transcription_text.insert(END,post_transcription, ('faded')) # Display Textbox self.transcription_text.pack(anchor="nw", expand=Y, fill=BOTH) # If the Segment is an Image elif self.database[self.collection_index]['items'][self.item_index]['item_type'] == 'i': # Pull segmentation data self.top = int(self.database[self.collection_index]['items'][self.item_index]['segments'][self.segment_index]['top']) self.left = int(self.database[self.collection_index]['items'][self.item_index]['segments'][self.segment_index]['left']) self.bottom = int(self.database[self.collection_index]['items'][self.item_index]['segments'][self.segment_index]['bottom']) self.right = int(self.database[self.collection_index]['items'][self.item_index]['segments'][self.segment_index]['right']) # Create Image Canvas self.segment_imageCanvas = Canvas(self.pane_two_bottom_left) try: # Set image file self.filename = str(Path(self.raw_data_images_path) / self.database[self.collection_index]['items'][self.item_index]['image_file']) self.segment_image = PIL.Image.open(self.filename) except(FileNotFoundError): # Use stand in if file is not found self.filename = str(Path(self.raw_data_images_path) / 'sample.jpg') self.segment_image = PIL.Image.open(self.filename) # Find Image Size [self.segment_imageSizeWidth, self.segment_imageSizeHeight] = self.segment_image.size self.segment_image_original_ratio = self.segment_imageSizeHeight / self.segment_imageSizeWidth # Find Crop Coordinates self.segment_top_x_coordinate = int(self.left*self.segment_imageSizeWidth / 100) self.segment_top_y_coordinate = int(self.top*self.segment_imageSizeHeight / 100) self.segment_bottom_x_coordinate = int(self.right*self.segment_imageSizeWidth / 100) self.segment_bottom_y_coordinate = int(self.bottom*self.segment_imageSizeHeight / 100) # Crop Image self.segment_image = self.segment_image.crop((self.segment_top_x_coordinate, self.segment_top_y_coordinate, self.segment_bottom_x_coordinate, self.segment_bottom_y_coordinate)) # Compute Ratios [self.cropped_image_width, self.cropped_image_height] = self.segment_image.size self.cropped_image_ratio_h = self.cropped_image_height / self.cropped_image_width self.cropped_image_ratio_w = self.cropped_image_width /self.cropped_image_height # Implement Ratios for Portrait Images if self.cropped_image_width < self.cropped_image_height: self.segment_sizeRatio = 600 / self.cropped_image_height self.segment_newImageSizeHeight = int(self.cropped_image_height*self.segment_sizeRatio) self.segment_newImageSizeWidth = int(self.segment_newImageSizeHeight*self.cropped_image_ratio_w) # Implement Ratios for Landscape Images else: self.segment_sizeRatio = 600 / self.cropped_image_width self.segment_newImageSizeWidth = int(self.cropped_image_width*self.segment_sizeRatio) self.segment_newImageSizeHeight = int(self.segment_newImageSizeWidth*self.cropped_image_ratio_h) # Resize Image to Fit Canvas self.segment_image = self.segment_image.resize((self.segment_newImageSizeWidth, self.segment_newImageSizeHeight), PIL.Image.ANTIALIAS) # Prepare Image for Insertion self.segment_photoImg = PIL.ImageTk.PhotoImage(self.segment_image) # Display Image Canvas self.segment_imageCanvas.config(width=self.segment_newImageSizeWidth+10, height = self.segment_newImageSizeHeight+10, background="light gray") self.segment_imageCanvas.pack() # Add Image to Canvas self.segment_imageCanvas.create_image(self.segment_newImageSizeWidth/2+6, self.segment_newImageSizeHeight/2+6, image=self.segment_photoImg, anchor="center") # Display Notes self.note_displayer(selection_coordinates) def taxon_list_displayer(self,database,current_id): # Displays Taxon Editor Panel # Delete Any Existing Information try: self.pane_two.destroy() self.pane_two_bottom_left.destroy() self.pane_two_bottom_right.destroy() except (NameError, AttributeError): pass self.export_list = [] # Setup search Window Panels self.pane_two = ttk.Frame(self.search_window) self.pane_two.place(y=15, relx=.25, relwidth=.74, relheight=.4) self.pane_two_bottom_left = ttk.Frame(self.search_window) self.pane_two_bottom_left.place(relx=.25, rely = .45, relwidth=.32, relheight=.4) self.pane_two_bottom_right = ttk.Frame(self.search_window) self.pane_two_bottom_right.place(relx=.65, rely = .45, relwidth=.32, relheight=.4) # Set up segment list scrollbar self.scrollbar = Scrollbar(self.pane_two) self.scrollbar.pack(side=RIGHT,fill=Y) # Set Up segment listbox self.segments = Listbox(self.pane_two) self.segments.pack(anchor=W, fill=BOTH, expand=True) self.get_annotations_button = Button(self.pane_two, text="Search For Taxons", command=self.get_checked_annotations) self.get_annotations_button.pack() self.list_of_items = "" #Populate Segment List Box for collection_number,dictionary in self.database.items(): if collection_number != 'users': for item_number,item_dictionary in self.database[collection_number]['items'].items(): for segment_number,segment_dictionary in self.database[collection_number]['items'][item_number]['segments'].items(): self.relatedterms = [] if 'annotations' in segment_dictionary: for annotation in segment_dictionary['annotations']: self.relatedterms.append(annotation[0]) # If the selected term is in the item list if all(elem in self.relatedterms for elem in current_id): self.list_of_items = self.list_of_items + (collection_number + "/" + item_number+ "/" + segment_number + "; ") # If the segment is text if self.database[collection_number]['items'][item_number]['item_type'] == "t": if 'fabio:pageRange' in self.database[collection_number]['items'][item_number]: if 'dc:description' in self.database[collection_number]['items'][item_number]['segments'][segment_number]: display_item = "Text " + str(int(segment_number) +1) + ' of Page ' + self.database[collection_number]['items'][item_number]['fabio:pageRange'][0] + ' of ' + self.database[collection_number]['dc:title'][0] + ': ' + self.database[collection_number]['items'][item_number]['segments'][segment_number]['dc:description'][0] else: display_item = "Text " + str(int(segment_number) +1) + ' of Page ' + self.database[collection_number]['items'][item_number]['fabio:pageRange'][0] + ' of ' + self.database[collection_number]['dc:title'][0] else: if 'dc:description' in self.database[collection_number]['items'][item_number]['segments'][segment_number]: display_item = 'Text ' + str(int(item_number) + 1) + ":" + str(int(segment_number) +1) + ' of ' + self.database[collection_number]['dc:title'][0] + ': ' + self.database[collection_number]['items'][item_number]['segments'][segment_number]['dc:description'][0] else: display_item = 'Text ' + str(int(item_number) + 1) + ":" + str(int(segment_number) +1) + ' of ' + self.database[collection_number]['dc:title'][0] # If the segment is an image elif self.database[collection_number]['items'][item_number]['item_type'] == "i": display_item = 'Image ' + str(int(item_number) + 1) + ":" + str(int(segment_number) +1) + ' of ' + self.database[collection_number]['dc:title'][0] # Display the number and title segment = display_item self.segments.insert(END, segment) # Save to export list self.export_list.append([collection_number,item_number,segment_number]) # Bind scrollbar to listbox self.segments.config(yscrollcommand=self.scrollbar.set) self.scrollbar.config(command=self.segments.yview) # Bind command to double-click segment self.segments.bind('<Double-Button>', self.result_viewer) # Print list of items self.citationlist = ttk.Entry(self.pane_two) self.citationlist.insert(0,self.list_of_items[:-2]) self.citationlist.pack(expand=YES, fill=X) def taxon_tree_displayer(self): # Displays search Tree Panel window_width = self.search_window.winfo_screenwidth() window_height = self.search_window.winfo_screenheight() # Create Tree self.search_tree = CheckboxTreeview(self.pane_one,height=int(window_height),selectmode='browse',show='tree') # Create Tree Layout self.search_tree.column("#0", width=int(window_width/2), stretch=1) # Alphabetise search alpha_search = [] for item,dictionary in self.taxonomy.items(): alpha_search.append(dictionary['iid']) alpha_search = sorted(alpha_search) # Go through search alphabetically and build branches for taxon in alpha_search: self.iid_iterator(self.taxonomy,taxon,self.taxon_branch_builder) self.get_annotations_button = Button(self.pane_two, text="Search For Taxons", command=self.get_checked_annotations) # Display Tree self.search_tree.pack() self.get_annotations_button.pack(anchor="nw") self.search_tree.update() ######################## # Main # ######################## def search_viewer(self,window): # Displays the search Panels # Set Icon Assets # Menu Bar Icons made by Pixel Buddha (https://www.flaticon.com/authors/pixel-buddha) from http://www.flaticon.com CC-BY (http://creativecommons.org/licenses/by/3.0/) self.up_level_icon=PhotoImage(file=Path(self.assets_path) / 'uplevel.png') self.add_icon=PhotoImage(file=Path(self.assets_path) / 'add.png') self.delete_icon=PhotoImage(file=Path(self.assets_path) / 'delete.png') self.save_icon=PhotoImage(file=Path(self.assets_path) / 'save.png') self.refresh_icon=PhotoImage(file=Path(self.assets_path) / 'refresh.png') ################## # Window Cleanup # ################## # Delete Previous Panels and Menus or Create New Window try: self.pane_one.destroy() self.pane_two.destroy() self.pane_three.destroy() except (NameError, AttributeError): pass ################### # search Window # ################### # Setup search Window self.search_window = window # Setup search Window Panels self.pane_one = ttk.Frame(self.search_window) self.pane_two = ttk.Frame(self.search_window) self.pane_one.place(y=15, relwidth=.20, relheight=.85) self.pane_two.place(y=15, relx=.25, relwidth=.74, relheight=.4) #menubar.add_command(label="Add New Root", command=self.root_adder) # Set Up Annotation Selection (Tree) Panel self.annotation_list = [] self.taxon_tree_displayer()
class TreeviewConstructor(ttk.Frame): logger = CustomAdapter(logging.getLogger(str(__name__)), None) @debug(lvl=logging.DEBUG, prefix='') def __init__(self, master, *args, **kwargs): self.col_obj_dict = {} self.column_lst = [] self.col_disp_lst = [] self.item_obj_dict = {} self.master = master # noinspection PyArgumentList super().__init__(self.master, *args, **kwargs) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.treeview = CheckboxTreeview(self) TreeviewConstructor.logger.log(logging.DEBUG, "10") self.treeview.grid(row=0, column=0, sticky=tk.NSEW) TreeviewConstructor.logger.log(logging.DEBUG, "11") self.ysb = ttk.Scrollbar(self) TreeviewConstructor.logger.log(logging.DEBUG, "12") self.ysb.grid(row=0, column=1, sticky=tk.NS) TreeviewConstructor.logger.log(logging.DEBUG, "13") self.ysb.config(orient=tk.VERTICAL, command=self.treeview.yview) TreeviewConstructor.logger.log(logging.DEBUG, "14") self.xsb = ttk.Scrollbar(self) TreeviewConstructor.logger.log(logging.DEBUG, "15") self.xsb.grid(row=1, column=0, sticky=tk.EW) TreeviewConstructor.logger.log(logging.DEBUG, "16") self.xsb.config(orient=tk.HORIZONTAL, command=self.treeview.xview) TreeviewConstructor.logger.log(logging.DEBUG, "17") self.treeview['yscroll'] = self.ysb.set TreeviewConstructor.logger.log(logging.DEBUG, "18") self.treeview['xscroll'] = self.xsb.set TreeviewConstructor.logger.log(logging.DEBUG, "19") # self.manager = BusyManager(self.frame) @debug(lvl=logging.DEBUG, prefix='') def populate_cols(self, checkwidth): col_obj = TreeColumn(order=0, col_id='#0', hdr_txt="", anchor=tk.W, stretch=tk.NO, minwidth=0, width=checkwidth, display=False) TreeviewConstructor.logger.log( logging.DEBUG, "Column ID: {col_id} Header Text: {hdr_txt}".format( col_id=col_obj.col_id, hdr_txt=col_obj.hdr_txt)) self.col_obj_dict[col_obj.col_id] = col_obj for col_key, column in sorted(self.col_obj_dict.items(), key=lambda x: x[1].order): self.column_lst.append(column.col_id) if column.display: self.col_disp_lst.append(column.col_id) self.treeview.config(columns=self.column_lst, displaycolumns=self.col_disp_lst) self.treeview.tag_configure('red', foreground='red4', background='IndianRed1') self.treeview.tag_configure('parent_evenrow', background='gray85') self.treeview.tag_configure('child_evenrow', background="honeydew3") self.treeview.tag_configure('parent_oddrow', background='white') self.treeview.tag_configure('child_oddrow', background="honeydew2") for col in self.col_obj_dict.values(): TreeviewConstructor.logger.log( logging.DEBUG, "Column ID: {col_id} Header Text: {hdr_txt} Anchor: {anchor}". format(col_id=col.col_id, hdr_txt=col.hdr_txt, anchor=col.anchor)) if col.hdr_txt in (None, ""): header = col.col_id else: header = col.hdr_txt if col.col_id == '#0': self.treeview.heading(column=col.col_id, text="", anchor=col.anchor, command=lambda _col=col.col_id: self. treeview_sort_column(_col, False)) else: self.treeview.heading(column=col.col_id, text=header, anchor=col.anchor, command=lambda _col=col.col_id: self. treeview_sort_column(_col, False)) self.treeview.column(col.col_id, minwidth=col.minwidth, width=col.width, stretch=col.stretch) @debug(lvl=logging.DEBUG, prefix='') def populate_items(self): for item in self.item_obj_dict.values(): TreeviewConstructor.logger.log(logging.NOTSET, "Item Info: {0}".format(item.iid)) self.treeview.insert(item.parent, item.index, iid=item.iid, values=item.values_list) for tag in item.tags_list: self.treeview.tag_add(item.iid, tag) @debug(lvl=logging.DEBUG, prefix='') def stripe_rows(self): for item in self.item_obj_dict.values(): self.treeview.tag_del(item.iid, 'parent_evenrow') self.treeview.tag_del(item.iid, 'child_evenrow') self.treeview.tag_del(item.iid, 'parent_oddrow') self.treeview.tag_del(item.iid, 'child_oddrow') row_num = self.treeview.index(item.iid) if row_num % 2 == 0: if item.parent == "": self.treeview.tag_add(item.iid, 'child_evenrow') else: self.treeview.tag_add(item.iid, 'parent_evenrow') elif row_num % 2 != 0: if item.parent == "": self.treeview.tag_add(item.iid, 'child_oddrow') else: self.treeview.tag_add(item.iid, 'parent_oddrow') @debug(lvl=logging.DEBUG, prefix='') def treeview_sort_column(self, col, reverse): # self.manager.busy() item_list = [(self.treeview.set(k, col), k) for k in self.treeview.get_children('')] item_list.sort(reverse=reverse) # rearrange items in sorted positions for index, (val, k) in enumerate(item_list): self.treeview.move(k, '', index) self.stripe_rows() # reverse sort next time self.treeview.heading( col, command=lambda: self.treeview_sort_column(col, not reverse)) # self.manager.not_busy() @debug(lvl=logging.DEBUG, prefix='') def tv_refresh(self): # self.manager.busy() item_list = list(self.treeview.get_children('')) item_list.sort(key=lambda x: int(x)) for item_iid, item_obj in sorted(self.item_obj_dict.items()): TreeviewConstructor.logger.log(logging.DEBUG, "Item ID: {0}".format(item_iid)) # l = self.treeview.get_children('') for index, k in enumerate(item_list): TreeviewConstructor.logger.log(logging.DEBUG, "k: {0}".format(k)) if str(item_iid) == str(k): self.treeview.delete(k) item_obj.index = index self.treeview.insert(item_obj.parent, item_obj.index, iid=item_obj.iid, values=item_obj.values_list) item_list.remove(k) break self.stripe_rows() # self.manager.not_busy() @debug(lvl=logging.DEBUG, prefix='') def add_column(self, order=None, col_id=None, hdr_txt="", anchor=tk.W, stretch=tk.YES, minwidth=0, width=50, display=True, desc=None): col_obj = TreeColumn(order=order, col_id=col_id, hdr_txt=hdr_txt, anchor=anchor, stretch=stretch, minwidth=minwidth, width=width, display=display, desc=desc) self.col_obj_dict[col_obj.col_id] = col_obj @debug(lvl=logging.NOTSET, prefix='') def add_item(self, iid, parent="", index=tk.END, values_dict=None): item_obj = TreeRow(treeview_const=self, iid=iid, parent=parent, index=index, values_dict=values_dict) self.item_obj_dict[item_obj.iid] = item_obj @debug(lvl=logging.DEBUG, prefix='') def columns_from_query(self, query, hide_list=None, pref_order=None): if pref_order is None: pref_order = [] if hide_list is None: hide_list = [] col_order = 1 col_order += len(pref_order) TreeviewConstructor.logger.log( logging.DEBUG, "Column Order Starting Value: {0}".format(str(col_order))) for desc in query.column_descriptions: name = desc.get('name').replace("'", "").replace('"', "") TreeviewConstructor.logger.log(logging.DEBUG, "Column Name: {0}".format(name)) disp = True if name in hide_list: disp = False cust_order = col_order if name in pref_order: cust_order = pref_order.index(name) + 1 self.add_column(order=cust_order, col_id=name.replace(" ", "_"), hdr_txt=name, display=disp, desc=desc) if name not in pref_order: col_order += 1 @debug(lvl=logging.DEBUG, prefix='') def rows_from_query(self, query, id_col="line_number", limit=None, parent_col=None): counter = 1 for row in query.all(): temp_dict = {} for col_obj in self.col_obj_dict.values(): # noinspection PyProtectedMember value = row._asdict().get(col_obj.hdr_txt) if isinstance(value, str): value.replace("{", "").replace("}", "") temp_dict[str(col_obj.order)] = value counter += 1 if counter == limit: break parent = "" if parent_col is not None: # noinspection PyProtectedMember if str(row._asdict().get(id_col)) != str( row._asdict().get(parent_col)): # noinspection PyProtectedMember parent = str(row._asdict().get(parent_col)) # noinspection PyProtectedMember self.add_item(iid=str(row._asdict().get(id_col)), values_dict=temp_dict, parent=parent) @debug(lvl=logging.DEBUG, prefix='') def populate_query(self, query, hide_list=None, pref_order=None, id_col="line_number", limit=None, checkwidth=0, parent_col=None): the_query = query self.columns_from_query(the_query, hide_list, pref_order) self.populate_cols(checkwidth=checkwidth) self.rows_from_query(the_query, id_col, limit, parent_col) self.populate_items() self.stripe_rows()
import tkinter as tk import tkinter.ttk as ttk root = tk.Tk() root.geometry('600x600') root.title("Checkbox example") f1 = tk.Frame(root, width=595, height=595, background='blue', bd=1) f1.grid(row=0, column=0) checkingFrame = tk.Frame(f1, width=590, height=590, background='yellow', bd=1) checkingFrame.grid(row=0, column=0, padx=5, pady=5) canvas_tree = tk.Canvas(checkingFrame, bg='white') canvas_tree.grid(row=0, column=0) main_tree = CheckboxTreeview(canvas_tree, show='tree') main_tree.column("#0", width=500, minwidth=600, stretch=True) main_tree.configure(height=10) main_tree.insert("", "end", "1", text="1" + '2') main_tree.insert("1", "end", "11", text="11") main_tree.insert("1", "end", "12", text="Anantha" + "kumar" + 'Kondra' + 'Anantha Kumar Kondra') main_tree.insert("11", "end", "111", text="Anantha" + "kumar" + 'Kondra' + 'Anantha Kumar Kondra') main_tree.insert("", "end", text="Anantha" + "kumar" + 'Kondra' + 'Anantha Kumar Kondra')
from ttkwidgets import CheckboxTreeview import tkinter as tk import tkinter.ttk as ttk root = tk.Tk() root.geometry('500x500') root.title("Checkbox example") f1 = tk.Frame(root, width=490, height=490) f1.grid() can = tk.Canvas(f1, width=500) tree = CheckboxTreeview(can, show='tree') tree.column('#0', minwidth=350, stretch=True, width=300) tree.insert("", "end", "1", text="1" + '2') tree.insert("1", "end", "11", text="11") tree.insert("1", "end", "12", text="Anantha" + "kumar" + 'Kondra' + 'Anantha Kumar Kondra') tree.insert("11", "end", "111", text="Anantha" + "kumar" + 'Kondra' + 'Anantha Kumar Kondra') tree.insert("", "end", "2", text="Anantha" + "kumar" + 'Kondra' + 'Anantha Kumar Kondra') tree.grid() xscrol = ttk.Scrollbar(can, orient=tk.HORIZONTAL, command=tree.xview)
class ScriptManager: """ Open the scripts window manager """ folder_icon = None def __init__(self, parent): """ parent: the tkinter parent view to use for this window construction. """ self.parent = parent self.app = tk.Toplevel(parent) self.app.title("Scripts Manager") self.app.resizable(True, True) self.rvalue = None appFrame = ttk.Frame(self.app) #PANED PART self.paned = tk.PanedWindow(appFrame, height=300) #RIGHT PANE : TAble self.viewframe = ttk.Frame(self.paned) self.file_tree = CheckboxTreeview(self.viewframe) self.file_tree['columns'] = ('name', 'category') self.file_tree.heading('#0', text='Name') self.file_tree.column("#0", stretch=tk.YES, minwidth=300, width=300) self.file_tree.heading('#1', text='Category') self.file_tree.column("#1", stretch=tk.YES, minwidth=300, width=300) self.file_tree.pack(fill=tk.BOTH, expand=True) btn_pane = ttk.Frame(self.viewframe) self.execute_icone = tk.PhotoImage(file = Utils.getIcon("execute.png")) btn_execute = ttk.Button(btn_pane, text="Execute", image=self.execute_icone, command=self.executedSelectedScripts, tooltip="Execute all selected scripts", style="Toolbutton") btn_execute.pack(side=tk.RIGHT, padx=3, pady=5) self.open_folder_icone = tk.PhotoImage(file = Utils.getIcon("folder.png")) btn_openPathForUser = ttk.Button(btn_pane, text="Execute", image=self.open_folder_icone, command=self.openPathForUser, tooltip="Open scripts folder", style="Toolbutton") btn_openPathForUser.pack(side=tk.RIGHT, padx=3, pady=5) btn_pane.pack(fill=tk.X, side=tk.BOTTOM, anchor=tk.E) #LEFT PANE : Treeview self.frameTw = ttk.Frame(self.paned) self.treevw = ttk.Treeview(self.frameTw) self.treevw.pack() scbVSel = ttk.Scrollbar(self.frameTw, orient=tk.VERTICAL, command=self.treevw.yview) self.treevw.configure(yscrollcommand=scbVSel.set) self.treevw.grid(row=0, column=0, sticky=tk.NSEW) scbVSel.grid(row=0, column=1, sticky=tk.NS) self.treevw.grid(row=0, column=0, sticky=tk.NSEW) scbVSel.grid(row=0, column=1, sticky=tk.NS) self.paned.add(self.frameTw) self.paned.add(self.viewframe) self.paned.pack(fill=tk.BOTH, expand=1) self.frameTw.rowconfigure(0, weight=1) # Weight 1 sur un layout grid, sans ça le composant ne changera pas de taille en cas de resize self.frameTw.columnconfigure(0, weight=1) # Weight 1 sur un layout grid, sans ça le composant ne changera pas de taille en cas de resize appFrame.pack(fill=tk.BOTH, ipady=10, ipadx=10, expand=True) self.treevw.bind("<<TreeviewSelect>>", self.onTreeviewSelect) try: self.app.wait_visibility() self.app.focus_force() self.app.lift() except tk.TclError: pass self.refreshUI() def refreshUI(self): for widget in self.treevw.winfo_children(): widget.destroy() script_dir = self.getScriptsDir() if self.__class__.folder_icon is None: self.__class__.folder_icon = ImageTk.PhotoImage(Image.open(Utils.getIcon("folder.png"))) parent = self.treevw.insert("", "end", " ", text="Scripts", image=self.__class__.folder_icon, open=True) self.treevw.focus(parent) self.treevw.selection_set(parent) for root, subFolders, files in os.walk(script_dir): root_name = root.replace(script_dir, "") for folder in subFolders: if folder.startswith("__") or folder.endswith("__"): continue folder_iid = os.path.join(root_name, folder) parent_node = parent if root_name == "" else root_name self.treevw.insert(parent_node, "end", folder_iid, text=folder, image=self.__class__.folder_icon) self.openScriptFolderView() def getScriptsDir(self): return os.path.join(Utils.getMainDir(), "scripts/") def onTreeviewSelect(self, _event=None): selec = self.treevw.selection() if len(selec) == 0: return None item = selec[0] self.openScriptFolderView(str(item)) def openScriptFolderView(self, script_folder=""): full_script_path = os.path.join(self.getScriptsDir(), script_folder.strip()) script_shown = set() self.file_tree.delete(*self.file_tree.get_children()) for root, _, files in os.walk(full_script_path): for file in files: filepath = root + '/' + file if file.endswith(".py"): script_shown.add(filepath) scripts_list = sorted(script_shown) script_dir = self.getScriptsDir() for script in scripts_list: scriptName = os.path.basename(script) category_name = os.path.dirname(script.replace(script_dir, "")) self.file_tree.insert("", "end", script, text=scriptName, values=(category_name)) def executedSelectedScripts(self): for selected in self.file_tree.get_checked(): self.executeScript(selected) def executeScript(self, script_path): script_dir = self.getScriptsDir() category_name = os.path.dirname(script_path.replace(script_dir, "")) script_name = ".".join(os.path.splitext(os.path.basename(script_path))[:-1]) module = os.path.join("pollenisatorgui/scripts/",category_name, script_name).replace("/", '.') imported = importlib.import_module(module) success, res = imported.main(APIClient.getInstance()) if success: tk.messagebox.showinfo("Script finished", f"Script {script_name} finished.\n{res}") else: tk.messagebox.showwarning("Script failed", f"Script {script_name} failed.\n{res}") def openPathForUser(self): selection = self.treevw.selection() if selection: folder = os.path.join(self.getScriptsDir(), selection[0]) else: folder = self.getScriptsDir() Utils.openPathForUser(folder)