The problem with this code is I have two autocomplete entry boxes one in Win1 and the other in Win3. It works in Win1 though but problem is when I click on Win3 the new entry box appears in win1. self.entername_e is used to receive the entry on Win3 and self.name_e is used to receive entries on Win1
import tkinter as tk
from tkinter import *
import sqlite3
import tkinter.messagebox
import datetime
import math
import os
import random
import re
The AutocompleteEntry is the class that is used by both the windows Win1 and Win3
#This is the Autocomplete class both the entries will use
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 = 8
# 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("<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) ]
This is where the code starts
class Win1:
def __init__(self, master):
self.master = master
self.master = master
autocompleteList = [ 'Milo tin', 'Shito small', 'Deodorant', 'Spray']
def matches(fieldValue, acListEntry):
pattern = re.compile(re.escape(fieldValue) + '.*', re.IGNORECASE)
return re.match(pattern, acListEntry)
self.master.geometry("400x300")
self.show_widgets()
Here is the AutocompleteEntry on Win1
#Autocomplete Entry
self.name_e = AutocompleteEntry(autocompleteList, listboxLength=10, width=25, font=('arial 18 bold'), bg='lightblue', matchesFunction=matches)
self.name_e.place(x=260, y=150)
def show_widgets(self):
self.frame = tk.Frame(self.master)
self.master.title("Window n.1")
self.create_button("Click to open Window 2", Win2)
self.create_button("Click to open Window 3", Win3)
self.frame.pack()
def create_button(self, text, _class):
"Button that creates a new window"
tk.Button(self.frame, text=text,command=lambda: self.new_window(_class)).pack()
def new_window(self, _class):
self.win = tk.Toplevel(self.master)
_class(self.win)
class Win2(Win1):
def __init__(self, master):
self.master = master
self.master.title("Window n.2")
self.master.geometry("400x100+200+200")
self.show_widgets()
def show_widgets(self):
"A frame with a button to quit the window"
self.frame = tk.Frame(self.master, bg="red")
self.quit_button = tk.Button(self.frame, text=f"Quit this window n. 2",command=self.close_window)
self.quit_button.pack()
self.create_button("Open window 3 from window 2", Win3)
self.frame.pack()
def close_window(self):
self.master.destroy()
class Win3(Win1):
def __init__(self, master):
self.master = master
self.master = master
#This is the list of the autocomplete entry
autocompleteList = [ 'Milo tin', 'Shito small', 'Deodorant', 'Spray' ]
def matches(fieldValue, acListEntry):
pattern = re.compile(re.escape(fieldValue) + '.*', re.IGNORECASE)
return re.match(pattern, acListEntry)
self.master.title("Window n.3")
self.master.geometry("400x200+200+200")
self.show_widgets()
Here's also the AutocompleteEntry on Win3
#Autocomplete Entry
self.entername_e = AutocompleteEntry(autocompleteList, listboxLength=10, width=25, font=('arial 18 bold'), bg='white', matchesFunction=matches)
self.entername_e.place(x=260, y=150)
def show_widgets(self):
self.frame = tk.Frame(self.master, bg="green")
self.quit = tk.Button(self.frame, text=f"Quit this window n. 3",command=self.close_window)
self.quit.pack()
self.label = tk.Label(self.frame, text="THIS IS ONLY IN THE THIRD WINDOW")
self.label.pack()
self.frame.pack()
def close_window(self):
self.master.destroy()
root = tk.Tk()
app = Win1(root)
root.mainloop()