Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from tkinter import *
- class AutoComplete():
- def __init__(self, root):
- self.root = root
- self.root.bind("<Button-1>", self.mouseClick)
- self.root.geometry("1000x600")
- self.active_window = None
- self.button = [None]*1000
- self.input = None
- def set_entry(self, event, text, stringvar):
- stringvar.set(text)
- self.close_overlay(Event())
- self.input.icursor(len(text))
- def set_button_colour(self, event, button, state):
- if state:
- button.configure(bg="#BBBBBB")
- else:
- button.configure(bg="#DDDDDD")
- def mouseClick(self, event):
- mous_over_button = False
- if self.input != None:
- for i in range(len(self.button)):
- if self.button[i] != None:
- if event.widget == self.button[i]:
- mous_over_button = True
- if mous_over_button:
- pass
- elif event.widget == self.input or event.widget == self.active_window:
- self.autocomplete(event, self.sv, self.options)
- else:
- self.close_overlay(event)
- def autocomplete(self, event, sv, options):
- intxt = sv.get()
- valid = []
- if len(intxt) >2 :
- for opt in options:
- if(opt[0:len(intxt)].lower() == intxt.lower()):
- valid.append(opt)
- if len(valid) > 0:
- xpos = self.input.winfo_rootx() - self.root.winfo_rootx()
- ypos = self.input.winfo_rooty() - self.root.winfo_rooty() + self.input.winfo_height()
- activeoverlay = self.overlay(self.root, width=self.input.winfo_width(), x=xpos, y=ypos)
- button_height = 2
- buttonFrame = Frame(activeoverlay, padx=2, pady=2, borderwidth=2, highlightbackground="black", relief="ridge")
- buttonFrame.pack(side=TOP, fill=BOTH, expand=1)
- for i in range(len(valid)):
- self.button[i] = Button(buttonFrame, text=valid[i], height=1, command=lambda e=Event(), t=valid[i], tv=sv: self.set_entry(e, t, sv), width=100, bg="#DDDDDD", fg="black", borderwidth=0, relief=None)
- self.button[i].pack(fill=X)
- self.button[i].bind("<Enter>", lambda e=Event(), b=self.button[i], s=True: self.set_button_colour(e, b, s))
- self.button[i].bind("<Leave>", lambda e=Event(), b=self.button[i], s=False: self.set_button_colour(e, b, s))
- main_height=self.button[i].winfo_height()
- for but in self.button:
- if but != None:
- but.update()
- lastbut = but
- self.active_window.configure(height=lastbut.winfo_height()*len(valid))
- self.active_window.update()
- else:
- self.close_overlay(Event())
- else:
- self.close_overlay(Event())
- def close_overlay(self, event):
- if self.active_window != None:
- self.button = [None]*1000
- self.active_window.pack_forget()
- self.active_window.destroy()
- self.active_window = None
- def overlay(self, over, width=100, x=0, y=0): ##the overlay to hold the selection options
- if self.active_window != None:
- self.close_overlay(Event())
- self.active_window = Canvas(over, width=width, bg="white", borderwidth=2, relief="raised")
- self.active_window.pack_propagate(False)
- self.active_window.place(x=x, y=y)
- self.root.update_idletasks()
- self.root.update()
- return self.active_window
- def autocomplete_Entry(self, holder, vals): ##the modified Widget
- self.sv = StringVar()
- self.options = vals
- self.sv.trace("w", lambda name, index, mode, sv=self.sv, opt=self.options, e=Event(): self.autocomplete(e, sv, opt))
- self.input=Entry(holder, textvariable=self.sv)
- self.input.pack()
- #self.input.bind("<FocusOut>", lambda e=Event(): self.close_overlay(e))
- return self.input, self.sv
- ##Just for texting
- def run(self):
- self.window = Frame(self.root)
- self.window.pack(fill=BOTH, expand=1) #
- options = ["apple", "apple1", "apple2", "apple3", "apple4", "apple5", "apple6", "apple7", "banana", "pare", "peach", "strawberry", "melon"]
- entry = self.autocomplete_Entry(self.window, options)
- self.root.mainloop()
- if __name__ == "__main__":
- root = Tk()
- AutoComplete(root).run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement