Jul-16-2018, 12:35 PM
The autocomplete class below works as expected when the lines 9-19 (=notebook tabs) are missing, meaning that the list of the entry box (line 130), appears below the box.
Adding the pages/tabs of the notebook widget, everything works fine but the drop down list "covers" the entry box (so, if a string is written in the field, isn't visible). I don't know if the addition of the tabs alters the alignment of the rows etc
Adding the pages/tabs of the notebook widget, everything works fine but the drop down list "covers" the entry box (so, if a string is written in the field, isn't visible). I don't know if the addition of the tabs alters the alignment of the rows etc
from tkinter import * import re from tkinter import ttk w1=Tk() w1.title('GUI Special Solutions') w1.geometry('1500x800+0+0') # Defines and places the notebook widget nb = ttk.Notebook(w1) nb.grid(row=1, column=0,columnspan=100, rowspan=99,sticky='NESW') # Adds tab 1 of the notebook page1 = ttk.Frame(nb) nb.add(page1, text='Home') # Adds tab 2 of the notebook page2 = ttk.Frame(nb) nb.add(page2, text='Search') class AutocompleteEntry(Entry): def __init__(self, autocompleteList, *args, **kwargs): # Listbox length if 'listboxLength' in kwargs: self.listboxLength = kwargs['listboxLength'] del kwargs['listboxLength'] else: self.listboxLength = 6 # 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("<Right>", self.selection) self.bind("<Up>", self.moveUp) self.bind("<Down>", self.moveDown) self.listboxUp = False def changed(self, name, index, mode): if self.var.get() == '': if self.listboxUp: 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) self.listbox.bind("<Button-1>", self.selection) self.listbox.bind("<Double-Button-1>", self.selection) self.listbox.bind("<Right>", 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) else: if self.listboxUp: self.listbox.destroy() self.listboxUp = False def selection(self, event): if self.listboxUp: self.var.set(self.listbox.get(ACTIVE)) self.listbox.destroy() self.listboxUp = False self.icursor(END) 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) 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) # Scroll! self.listbox.selection_set(first=index) self.listbox.activate(index) def comparison(self): return [ w for w in self.autocompleteList if self.matchesFunction(self.var.get(), w) ] if __name__ == '__main__': autocompleteList = [ 'Dora Lyons (7714)', 'Hannah Golden (6010)', 'Walker Burns (9390)', 'Dieter Pearson (6347)', 'Allen Sullivan (9781)', 'Warren Sullivan (3094)', 'Genevieve Mayo (8427)', 'Igor Conner (4740)', 'Ulysses Shepherd (8116)', 'Imogene Bullock (6736)', 'Dominique Sanchez (949)', 'Sean Robinson (3784)', 'Diana Greer (2385)', 'Arsenio Conrad (2891)', 'Sophia Rowland' ] def matches(fieldValue, acListEntry): pattern = re.compile(re.escape(fieldValue) + '.*', re.IGNORECASE) return re.match(pattern, acListEntry) entry = AutocompleteEntry(autocompleteList, page2, listboxLength=6, matchesFunction=matches) entry.grid(row=1, column=1) e1=Label (page2, font=('arial',9,'bold'),text='''afm :''') e1.grid(row=1, column=0,sticky=E) e3=Entry(page2, state='readonly', readonlybackground='mintcream') e3.grid(row=2, column=1) w1.mainloop()