class CenterFrame(BasePAFrame): """ фрейм со списком файлов """ def __init__(self, *args, **kwargs): self.w_frame_child = kwargs.pop('child_frame') BasePAFrame.__init__(self, *args, **kwargs) self.w_listbox_files = Listbox(self) self.w_scrollbar_files = Scrollbar(self) self.catalog = None self.catalog_files = [] def _pa_configure(self): BasePAFrame._pa_configure(self) self.w_listbox_files.config(yscrollcommand=self.w_scrollbar_files.set) self.w_scrollbar_files.config(command=self.w_listbox_files.yview) self.w_listbox_files.bind( '<<ListboxSelect>>', self.select_listbox_file) def _pa_layout(self): BasePAFrame._pa_layout(self) w_listbox_files_width = 0.95 self.w_listbox_files.place( relx=0, rely=0, relwidth=w_listbox_files_width, relheight=1) self.w_scrollbar_files.place( relx=w_listbox_files_width, rely=0, relwidth=1-w_listbox_files_width, relheight=1) def set_catalog(self, catalog=None): """ задаем новый каталог для отображения :param catalog: словарь { 'path': путь к каталогу } :return: """ try: current_index = self.w_listbox_files.curselection()[0] except IndexError: current_index = 0 if 0 < current_index < len(self.catalog_files): set_index = current_index + 1 else: set_index = current_index self.catalog = catalog self.catalog_files = [] self.w_listbox_files.delete(0, END) self.w_frame_child.set_file(None) if self.catalog is not None: catalog_path = self.catalog for file_name in os.listdir(catalog_path): file_path = os.path.join(catalog_path, file_name) if os.path.isfile(file_path): self.catalog_files.append({ 'name': file_name, 'path': file_path}) self.catalog_files.sort(key=lambda x: x['name']) catalog_files = [catalog['name'] for catalog in self.catalog_files] self.w_listbox_files.insert(END, *catalog_files) self.w_listbox_files.selection_set(set_index) self.w_listbox_files.see(set_index) self.w_listbox_files.event_generate("<<ListboxSelect>>") def update_catalog(self): self.set_catalog(self.catalog) def select_listbox_file(self, event): """ обработчик выбора файла в списке файлов :param event: :return: """ try: index = self.w_listbox_files.curselection()[0] file_ = self.catalog_files[index] except IndexError: return else: self.w_frame_child.set_file(file_)
class AutocompleteEntry(Entry): def __init__(self, autocompleteList, *args, **kwargs): # Listbox length self.listboxLength = kwargs.pop('listboxLength', 12) self.listboxFontSize = tkFont.Font(size=18) # Custom matches function if 'matchesFunction' in kwargs: self.matchesFunction = kwargs['matchesFunction'] del kwargs['matchesFunction'] else: def matches(fieldValue, acListEntry): pattern = re.compile('.*' + re.escape(fieldValue) + '.*', re.IGNORECASE) return re.match(pattern, acListEntry) self.matchesFunction = matches Entry.__init__(self, *args, **kwargs) self.focus() self.autocompleteList = autocompleteList self.var = self["textvariable"] if self.var == '': self.var = self["textvariable"] = StringVar() self.var.trace('w', self.changed) self.bind("<Return>", self.selection) self.bind("<Up>", self.moveUp) self.bind("<Down>", self.moveDown) self.listboxUp = False def update_content_text(self, event): w = event.widget try: index = int(w.curselection()[0]) except IndexError: return value = w.get(index) clipboard_content = autocompleteList.get(value)[0] content['text'] = clipboard_content def changed(self, name, index, mode): if self.var.get() == '': if self.listboxUp: content['text'] = '' self.listbox.destroy() self.listboxUp = False else: words = self.comparison() if words: if not self.listboxUp: self.listbox = Listbox(width=self["width"], height=self.listboxLength, font=self.listboxFontSize) self.listbox.bind('<<ListboxSelect>>', self.update_content_text) self.listbox.bind("<Return>", self.selection) self.listbox.place(x=self.winfo_x(), y=self.winfo_y() + self.winfo_height()) self.listboxUp = True self.listbox.delete(0, END) for w in words: self.listbox.insert(END, w) self.listbox.see(0) # Scroll! self.listbox.selection_set(first=0) value = self.listbox.get(ACTIVE) clipboard_content = autocompleteList.get(value)[0] content['text'] = clipboard_content else: if self.listboxUp: content['text'] = '' self.listbox.destroy() self.listboxUp = False def selection(self, event): if self.listboxUp: self.var.set(self.listbox.get(ACTIVE)) value = self.listbox.get(ACTIVE) data = autocompleteList.get(value) content = data[0] is_command = data[1] is_website = data[2] if is_command == '1': self.execute(content) elif is_website == '1': self.open_website(content) self.listbox.destroy() self.listboxUp = False self.icursor(END) self.copy_value(content) self.quit() def open_website(self, url): webbrowser.open(url) def execute(self, command): p = subprocess.Popen(command, bufsize=2048, shell=True, stdin=subprocess.PIPE) (output, err) = p.communicate() p_status = p.wait() def copy_value(self, value): clipboard.copy(value) def moveUp(self, event): if self.listboxUp: if self.listbox.curselection() == (): index = '0' else: index = self.listbox.curselection()[0] if index != '0': self.listbox.selection_clear(first=index) index = str(int(index) - 1) self.listbox.see(index) # Scroll! self.listbox.selection_set(first=index) self.listbox.activate(index) self.listbox.event_generate("<<ListboxSelect>>", when="tail") def moveDown(self, event): if self.listboxUp: if self.listbox.curselection() == (): index = '0' else: index = self.listbox.curselection()[0] if index != END: self.listbox.selection_clear(first=index) index = str(int(index) + 1) self.listbox.see(index) self.listbox.selection_set(first=index) self.listbox.activate(index) self.listbox.event_generate("<<ListboxSelect>>", when="tail") def quit(self): root.quit() def comparison(self): return [ w for w in self.autocompleteList if self.matchesFunction(self.var.get(), w) ]