class Window(object):
    def __init__(self, master):

        self.master = master
        self.master.wm_title('PEP8 checker')
        self.master.resizable(False, True)

        self.frame = Frame(master)
        self.frame.pack(fill=BOTH, expand=1)

        home_dir = expanduser("~")
        self.directory = StringVar(value=home_dir)

        directory_frame = Frame(self.frame)
        directory_frame.grid()
        self.frame.grid_rowconfigure(2, weight=1)

        self.entry_directory = Entry(directory_frame, textvariable=self.directory)
        self.entry_directory.pack(anchor=W, side=LEFT)

        self.select_directory = Button(directory_frame, text="Select directory to scan", command=self.select_directory)
        self.select_directory.pack(anchor=E, side=RIGHT)

        self.run_button = Button(self.frame, text='Run PEP8!', command=self.run_pep)
        self.run_button.grid(sticky=W + E)

        self.errors_list = Listbox(self.frame)
        self.errors_list.grid(sticky=W + E)

        self.status_label = Label(self.frame)

    def select_directory(self):
        directory = askdirectory(initialdir=self.directory.get())
        if directory:
            self.directory.set(directory)

    def run_pep(self):
        self.errors_list.delete(0, END)
        process = Popen('$(which pep8) {}'.format(self.directory.get()), shell=True, stderr=PIPE, stdout=PIPE)
        output = process.communicate()[0]
        selected_dir = ''.join((self.directory.get(), '/'))
        if output:
            self.errors_list.configure(background='red')
            for i, error in enumerate(output.split('\n')):
                self.errors_list.insert(i, error.replace(selected_dir, ''))
        else:
            self.errors_list.configure(background='green')
            self.errors_list.insert(0, 'Directory is OK!')
Esempio n. 2
0
class Combobox_Autocomplete(Entry, object):
    def __init__(self,
                 master,
                 list_of_items=None,
                 autocomplete_function=None,
                 listbox_width=None,
                 listbox_height=7,
                 ignorecase_match=False,
                 startswith_match=True,
                 vscrollbar=True,
                 hscrollbar=True,
                 **kwargs):
        if hasattr(self, "autocomplete_function"):
            if autocomplete_function is not None:
                raise ValueError(
                    "Combobox_Autocomplete subclass has 'autocomplete_function' implemented"
                )
        else:
            if autocomplete_function is not None:
                self.autocomplete_function = autocomplete_function
            else:
                if list_of_items is None:
                    raise ValueError(
                        "If not guiven complete function, list_of_items can't be 'None'"
                    )

                if ignorecase_match:
                    if startswith_match:

                        def matches_function(entry_data, item):
                            return item.startswith(entry_data)
                    else:

                        def matches_function(entry_data, item):
                            return item in entry_data

                    self.autocomplete_function = lambda entry_data: [
                        item for item in self.list_of_items
                        if matches_function(entry_data, item)
                    ]
                else:
                    if startswith_match:

                        def matches_function(escaped_entry_data, item):
                            if re.match(escaped_entry_data, item,
                                        re.IGNORECASE):
                                return True
                            else:
                                return False
                    else:

                        def matches_function(escaped_entry_data, item):
                            if re.search(escaped_entry_data, item,
                                         re.IGNORECASE):
                                return True
                            else:
                                return False

                    def autocomplete_function(entry_data):
                        escaped_entry_data = re.escape(entry_data)
                        return [
                            item for item in self.list_of_items
                            if matches_function(escaped_entry_data, item)
                        ]

                    self.autocomplete_function = autocomplete_function

        self._listbox_height = int(listbox_height)
        self._listbox_width = listbox_width

        self.list_of_items = list_of_items

        self._use_vscrollbar = vscrollbar
        self._use_hscrollbar = hscrollbar

        kwargs.setdefault("background", "white")

        if "textvariable" in kwargs:
            self._entry_var = kwargs["textvariable"]
        else:
            self._entry_var = kwargs["textvariable"] = StringVar()

        Entry.__init__(self, master, **kwargs)

        self._trace_id = self._entry_var.trace('w', self._on_change_entry_var)

        self._listbox = None

        self.bind("<Tab>", self._on_tab)
        self.bind("<Up>", self._previous)
        self.bind("<Down>", self._next)
        self.bind('<Control-n>', self._next)
        self.bind('<Control-p>', self._previous)

        self.bind("<Return>", self._update_entry_from_listbox)
        self.bind("<Escape>", lambda event: self.unpost_listbox())

    def _on_tab(self, event):
        self.post_listbox()
        return "break"

    def _on_change_entry_var(self, name, index, mode):

        entry_data = self._entry_var.get()

        if entry_data == '':
            self.unpost_listbox()
            self.focus()
        else:
            values = self.autocomplete_function(entry_data)
            if values:
                if self._listbox is None:
                    self._build_listbox(values)
                else:
                    self._listbox.delete(0, END)

                    height = min(self._listbox_height, len(values))
                    self._listbox.configure(height=height)

                    for item in values:
                        self._listbox.insert(END, item)

            else:
                self.unpost_listbox()
                self.focus()

    def _build_listbox(self, values):
        listbox_frame = Frame()

        self._listbox = Listbox(listbox_frame,
                                background="white",
                                selectmode=SINGLE,
                                activestyle="none",
                                exportselection=False)
        self._listbox.grid(row=0, column=0, sticky=N + E + W + S)

        self._listbox.bind("<ButtonRelease-1>",
                           self._update_entry_from_listbox)
        self._listbox.bind("<Return>", self._update_entry_from_listbox)
        self._listbox.bind("<Escape>", lambda event: self.unpost_listbox())

        self._listbox.bind('<Control-n>', self._next)
        self._listbox.bind('<Control-p>', self._previous)

        if self._use_vscrollbar:
            vbar = Scrollbar(listbox_frame,
                             orient=VERTICAL,
                             command=self._listbox.yview)
            vbar.grid(row=0, column=1, sticky=N + S)

            self._listbox.configure(
                yscrollcommand=lambda f, l: autoscroll(vbar, f, l))

        if self._use_hscrollbar:
            hbar = Scrollbar(listbox_frame,
                             orient=HORIZONTAL,
                             command=self._listbox.xview)
            hbar.grid(row=1, column=0, sticky=E + W)

            self._listbox.configure(
                xscrollcommand=lambda f, l: autoscroll(hbar, f, l))

        listbox_frame.grid_columnconfigure(0, weight=1)
        listbox_frame.grid_rowconfigure(0, weight=1)

        x = -self.cget("borderwidth") - self.cget("highlightthickness")
        y = self.winfo_height() - self.cget("borderwidth") - self.cget(
            "highlightthickness")

        if self._listbox_width:
            width = self._listbox_width
        else:
            width = self.winfo_width()

        listbox_frame.place(in_=self, x=x, y=y, width=width)

        height = min(self._listbox_height, len(values))
        self._listbox.configure(height=height)

        for item in values:
            self._listbox.insert(END, item)

    def post_listbox(self):
        if self._listbox is not None: return

        entry_data = self._entry_var.get()
        if entry_data == '': return

        values = self.autocomplete_function(entry_data)
        if values:
            self._build_listbox(values)

    def unpost_listbox(self):
        if self._listbox is not None:
            self._listbox.master.destroy()
            self._listbox = None

    def get_value(self):
        return self._entry_var.get()

    def set_value(self, text, close_dialog=False):
        self._set_var(text)

        if close_dialog:
            self.unpost_listbox()

        self.icursor(END)
        self.xview_moveto(1.0)

    def _set_var(self, text):
        self._entry_var.trace_vdelete("w", self._trace_id)
        self._entry_var.set(text)
        self._trace_id = self._entry_var.trace('w', self._on_change_entry_var)

    def _update_entry_from_listbox(self, event):
        if self._listbox is not None:
            current_selection = self._listbox.curselection()

            if current_selection:
                text = self._listbox.get(current_selection)
                self._set_var(text)

            self._listbox.master.destroy()
            self._listbox = None

            self.focus()
            self.icursor(END)
            self.xview_moveto(1.0)

        return "break"

    def _previous(self, event):
        if self._listbox is not None:
            current_selection = self._listbox.curselection()

            if len(current_selection) == 0:
                self._listbox.selection_set(0)
                self._listbox.activate(0)
            else:
                index = int(current_selection[0])
                self._listbox.selection_clear(index)

                if index == 0:
                    index = END
                else:
                    index -= 1

                self._listbox.see(index)
                self._listbox.selection_set(first=index)
                self._listbox.activate(index)

        return "break"

    def _next(self, event):
        if self._listbox is not None:

            current_selection = self._listbox.curselection()
            if len(current_selection) == 0:
                self._listbox.selection_set(0)
                self._listbox.activate(0)
            else:
                index = int(current_selection[0])
                self._listbox.selection_clear(index)

                if index == self._listbox.size() - 1:
                    index = 0
                else:
                    index += 1

                self._listbox.see(index)
                self._listbox.selection_set(index)
                self._listbox.activate(index)
        return "break"
Esempio n. 3
0
class GUI:
    def _run(self):
        self.saveBtn.config(state=DISABLED)
        self.progressTxt.config(state=NORMAL)
        self.progressTxt.delete('1.0', END)
        self.progressTxt.update()
        self.progressTxt.config(state=DISABLED)
        inputId = self.txEntry.get()
        item = map(int, self.dbLbox.curselection())
        db = self.dbids[item[0]]
        self.runBtn.config(state=DISABLED)
        self.inputId, self.inputName, self.hprobes = main(inputId,
                                                          db,
                                                          debug=self.debug,
                                                          txt=self.progressTxt)
        self.runBtn.config(state=NORMAL)
        if self.hprobes is not None:
            self.saveBtn.config(state=NORMAL)

    def _quitGUI(self):
        #rpath = self.progressTxt.get('8.0','end-1c')
        #if rpath.startswith('Your results'):
        #  tkMessageBox.showinfo("Quit", self.progressTxt.get('8.0','end-1c'))
        self.master.destroy()

    def _save(self):
        hps = filter_probes(self.hprobes, self.spec.get(), self.mingc.get(),
                            self.multiexon.get(), self.mintm.get(),
                            self.maxtm.get(), self.mindimer.get(),
                            self.minfold.get(), self.maxduplex.get())
        result_csv = write_probesCSV(self.inputId, self.inputName, hps,
                                     self.progressTxt)
        result_fna = write_probesFNA(self.inputId, self.inputName, hps,
                                     self.progressTxt)
        tkMessageBox.showinfo('Result file',
                              'Details on ' + str(len(hps)) + \
                              ' hybridization probe(s) were exported to ' + \
                              result_csv + "\n\n" + \
                              'Sequences of '+ str(len(hps)) + \
                              ' hybridization probe(s) were exported to ' + \
                              result_fna)

    def __init__(self, master, dbnames, dbids, debug, version):
        self.dbids = dbids
        self.debug = debug

        self.master = master
        master.title('Plish Probe Designer')

        self.logoImg = PhotoImage(file=get_script_path() +
                                  '/img/plishLogo.gif')
        self.logoLbl = Label(master, image=self.logoImg)
        self.logoLbl.grid(row=0, columnspan=3)
        self.logoLbl.img = self.logoImg

        self.dbLbl = Label(master, text='Database')
        self.dbLbl.grid(row=1, sticky=W + N)
        self.dbLbox = Listbox(master, width=63, height=4)
        self.dbLbox.configure(exportselection=False)

        for i in range(len(dbnames)):
            self.dbLbox.insert(i, dbnames[i])
        self.dbLbox.select_set(0)
        self.dbLbox.grid(row=1, column=1, columnspan=2, sticky=N)

        self.txLbl = Label(master, text='Transcript ID')
        self.txLbl.grid(row=2, sticky=W + N)
        self.txEntry = Entry(master, width=39)
        self.txEntry.grid(row=2, column=1, sticky=W + N)

        self.runBtn = Button(master, text='Run', command=self._run, width=15)
        self.runBtn.grid(row=2, column=2)

        self.progressLbl = Label(master, text='Progress')
        self.progressLbl.grid(row=4, sticky=W + N)
        self.progressTxt = Text(bg="#263238",
                                fg="#ffffff",
                                state=DISABLED,
                                width=51,
                                height=16)
        self.progressTxt.grid(row=4, column=1)

        self.saveBtn = Button(master,
                              text='Save',
                              command=self._save,
                              state=DISABLED,
                              width=15)
        self.saveBtn.grid(row=5, column=2, sticky=N)

        self.quitBtn = Button(master,
                              text='Quit',
                              command=self._quitGUI,
                              width=15)
        self.quitBtn.grid(row=6, column=2, sticky=N)

        self.aboutLF = LabelFrame(master, text='About', width=300)
        self.aboutLF.grid(row=5,
                          column=0,
                          rowspan=2,
                          columnspan=2,
                          sticky=N + W)
        self.versionLbl = Label(self.aboutLF, text='PLISH Probe Designer, Version ' + version + '\n' + \
                          '(c) Heller lab, Stanford University School of Medicine\n' + \
                          '     Daniel C. Ellwanger <*****@*****.**>                       ',
                          justify=LEFT)
        self.versionLbl.grid(row=0, column=0, sticky=N)

        # Filter
        self.filterLF = LabelFrame(master, text='Filter')
        self.filterLF.grid(row=4, column=2, rowspan=2, sticky=N + W)

        self.mingc = DoubleVar()
        self.mingc.set(_defaultGC)
        self.mingcLbl = Label(self.filterLF, text='Min. GC')
        self.mingcLbl.grid(row=0, column=0, sticky=N + W)
        self.mingcEntry = Entry(self.filterLF, width=5, text=self.mingc)
        self.mingcEntry.grid(row=0, column=1, sticky=N + W)
        self.mingcLbl2 = Label(self.filterLF, text='%')
        self.mingcLbl2.grid(row=0, column=2, sticky=N + W)

        self.spec = StringVar(master)
        self.spec.set("isoform")
        self.specLbl = Label(self.filterLF, text='Specificity')
        self.specLbl.grid(row=1, column=0, sticky=N + W)
        self.specOm = OptionMenu(self.filterLF, self.spec, "isoform", "gene",
                                 "none")
        self.specOm.grid(row=1, column=1, sticky=N + W, columnspan=2)

        self.mintm = DoubleVar()
        self.mintm.set(_defaultMinTm)
        self.mintmLbl = Label(self.filterLF, text='Min. Tm')
        self.mintmLbl.grid(row=2, column=0, sticky=N + W)
        self.mintmEntry = Entry(self.filterLF, width=5, text=self.mintm)
        self.mintmEntry.grid(row=2, column=1, sticky=N + W)
        self.mintmLbl2 = Label(self.filterLF, text=u'\N{DEGREE SIGN}' + 'C')
        self.mintmLbl2.grid(row=2, column=2, sticky=N + W)

        self.maxtm = DoubleVar()
        self.maxtm.set(_defaultMaxTm)
        self.maxtmLbl = Label(self.filterLF, text='Max. Tm')
        self.maxtmLbl.grid(row=3, column=0, sticky=N + W)
        self.maxtmEntry = Entry(self.filterLF, width=5, text=self.maxtm)
        self.maxtmEntry.grid(row=3, column=1, sticky=N + W)
        self.maxtmLbl2 = Label(self.filterLF, text=u'\N{DEGREE SIGN}' + 'C')
        self.maxtmLbl2.grid(row=3, column=2, sticky=N + W)

        self.minfold = DoubleVar()
        self.minfold.set(_defaultMinFold)
        self.minfoldLbl = Label(self.filterLF, text='Min. Fold')
        self.minfoldLbl.grid(row=4, column=0, sticky=N + W)
        self.minfoldEntry = Entry(self.filterLF, width=5, text=self.minfold)
        self.minfoldEntry.grid(row=4, column=1, sticky=N + W)
        self.minfoldLbl2 = Label(self.filterLF, text='kcal/mol')
        self.minfoldLbl2.grid(row=4, column=2, sticky=N + W)

        self.mindimer = DoubleVar()
        self.mindimer.set(_defaultMinDimer)
        self.mindimerLbl = Label(self.filterLF, text='Min. Dimer')
        self.mindimerLbl.grid(row=5, column=0, sticky=N + W)
        self.mindimerEntry = Entry(self.filterLF, width=5, text=self.mindimer)
        self.mindimerEntry.grid(row=5, column=1, sticky=N + W)
        self.mindimerLbl2 = Label(self.filterLF, text='kcal/mol')
        self.mindimerLbl2.grid(row=5, column=2, sticky=N + W)

        self.maxduplex = DoubleVar()
        self.maxduplex.set(_defaultMaxDuplex)
        self.maxduplexLbl = Label(self.filterLF, text='Max. Duplex')
        self.maxduplexLbl.grid(row=6, column=0, sticky=N + W)
        self.maxduplexEntry = Entry(self.filterLF,
                                    width=5,
                                    text=self.maxduplex)
        self.maxduplexEntry.grid(row=6, column=1, sticky=N + W)
        self.maxduplexLbl2 = Label(self.filterLF, text='kcal/mol')
        self.maxduplexLbl2.grid(row=6, column=2, sticky=N + W)

        self.multiexon = BooleanVar()
        self.multiexon.set(_defaultMultiExon)
        self.multiexonCb = Checkbutton(self.filterLF,
                                       text='Multi-exon',
                                       variable=self.multiexon,
                                       onvalue=True,
                                       offvalue=False)
        self.multiexonCb.grid(row=7, column=0, sticky=N + W)
Esempio n. 4
0
class Combobox_Autocomplete(Entry, object):
    def __init__(self, master, list_of_items=None, autocomplete_function=None, listbox_width=None, listbox_height=7, ignorecase_match=False, startswith_match=True, vscrollbar=True, hscrollbar=True, **kwargs):
        if hasattr(self, "autocomplete_function"):
            if autocomplete_function is not None:
                raise ValueError("Combobox_Autocomplete subclass has 'autocomplete_function' implemented")
        else:
            if autocomplete_function is not None:
                self.autocomplete_function = autocomplete_function
            else:
                if list_of_items is None:
                    raise ValueError("If not guiven complete function, list_of_items can't be 'None'")

                if ignorecase_match:
                    if startswith_match:
                        def matches_function(entry_data, item):
                            return item.startswith(entry_data)
                    else:
                        def matches_function(entry_data, item):
                            return item in entry_data

                    self.autocomplete_function = lambda entry_data: [item for item in self.list_of_items if matches_function(entry_data, item)]
                else:
                    if startswith_match:
                        def matches_function(escaped_entry_data, item):
                            if re.match(escaped_entry_data, item, re.IGNORECASE):
                                return True
                            else:
                                return False
                    else:
                        def matches_function(escaped_entry_data, item):
                            if re.search(escaped_entry_data, item, re.IGNORECASE):
                                return True
                            else:
                                return False
                    
                    def autocomplete_function(entry_data):
                        escaped_entry_data = re.escape(entry_data)
                        return [item for item in self.list_of_items if matches_function(escaped_entry_data, item)]

                    self.autocomplete_function = autocomplete_function

        self._listbox_height = int(listbox_height)
        self._listbox_width = listbox_width

        self.list_of_items = list_of_items
        
        self._use_vscrollbar = vscrollbar
        self._use_hscrollbar = hscrollbar

        kwargs.setdefault("background", "white")

        if "textvariable" in kwargs:
            self._entry_var = kwargs["textvariable"]
        else:
            self._entry_var = kwargs["textvariable"] = StringVar()

        Entry.__init__(self, master, **kwargs)

        self._trace_id = self._entry_var.trace('w', self._on_change_entry_var)
        
        self._listbox = None

        self.bind("<Tab>", self._on_tab)
        self.bind("<Up>", self._previous)
        self.bind("<Down>", self._next)
        self.bind('<Control-n>', self._next)
        self.bind('<Control-p>', self._previous)

        self.bind("<Return>", self._update_entry_from_listbox)
        self.bind("<Escape>", lambda event: self.unpost_listbox())
        
    def _on_tab(self, event):
        self.post_listbox()
        return "break"

    def _on_change_entry_var(self, name, index, mode):
        
        entry_data = self._entry_var.get()

        if entry_data == '':
            self.unpost_listbox()
            self.focus()
        else:
            values = self.autocomplete_function(entry_data)
            if values:
                if self._listbox is None:
                    self._build_listbox(values)
                else:
                    self._listbox.delete(0, END)

                    height = min(self._listbox_height, len(values))
                    self._listbox.configure(height=height)

                    for item in values:
                        self._listbox.insert(END, item)
                
            else:
                self.unpost_listbox()
                self.focus()

    def _build_listbox(self, values):
        listbox_frame = Frame()

        self._listbox = Listbox(listbox_frame, background="white", selectmode=SINGLE, activestyle="none", exportselection=False)
        self._listbox.grid(row=0, column=0,sticky = N+E+W+S)

        self._listbox.bind("<ButtonRelease-1>", self._update_entry_from_listbox)
        self._listbox.bind("<Return>", self._update_entry_from_listbox)
        self._listbox.bind("<Escape>", lambda event: self.unpost_listbox())
        
        self._listbox.bind('<Control-n>', self._next)
        self._listbox.bind('<Control-p>', self._previous)

        if self._use_vscrollbar:
            vbar = Scrollbar(listbox_frame, orient=VERTICAL, command= self._listbox.yview)
            vbar.grid(row=0, column=1, sticky=N+S)
            
            self._listbox.configure(yscrollcommand= lambda f, l: autoscroll(vbar, f, l))
            
        if self._use_hscrollbar:
            hbar = Scrollbar(listbox_frame, orient=HORIZONTAL, command= self._listbox.xview)
            hbar.grid(row=1, column=0, sticky=E+W)
            
            self._listbox.configure(xscrollcommand= lambda f, l: autoscroll(hbar, f, l))

        listbox_frame.grid_columnconfigure(0, weight= 1)
        listbox_frame.grid_rowconfigure(0, weight= 1)

        x = -self.cget("borderwidth") - self.cget("highlightthickness") 
        y = self.winfo_height()-self.cget("borderwidth") - self.cget("highlightthickness")

        if self._listbox_width:
            width = self._listbox_width
        else:
            width=self.winfo_width()

        listbox_frame.place(in_=self, x=x, y=y, width=width)
        
        height = min(self._listbox_height, len(values))
        self._listbox.configure(height=height)

        for item in values:
            self._listbox.insert(END, item)

    def post_listbox(self):
        if self._listbox is not None: return

        entry_data = self._entry_var.get()
        if entry_data == '': return

        values = self.autocomplete_function(entry_data)
        if values:
            self._build_listbox(values)

    def unpost_listbox(self):
        if self._listbox is not None:
            self._listbox.master.destroy()
            self._listbox = None

    def get_value(self):
        return self._entry_var.get()

    def set_value(self, text, close_dialog=False):
        self._set_var(text)

        if close_dialog:
            self.unpost_listbox()

        self.icursor(END)
        self.xview_moveto(1.0)
        
    def _set_var(self, text):
        self._entry_var.trace_vdelete("w", self._trace_id)
        self._entry_var.set(text)
        self._trace_id = self._entry_var.trace('w', self._on_change_entry_var)

    def _update_entry_from_listbox(self, event):
        if self._listbox is not None:
            current_selection = self._listbox.curselection()
            
            if current_selection:
                text = self._listbox.get(current_selection)
                self._set_var(text)

            self._listbox.master.destroy()
            self._listbox = None

            self.focus()
            self.icursor(END)
            self.xview_moveto(1.0)
            
        return "break"

    def _previous(self, event):
        if self._listbox is not None:
            current_selection = self._listbox.curselection()

            if len(current_selection)==0:
                self._listbox.selection_set(0)
                self._listbox.activate(0)
            else:
                index = int(current_selection[0])
                self._listbox.selection_clear(index)

                if index == 0:
                    index = END
                else:
                    index -= 1

                self._listbox.see(index)
                self._listbox.selection_set(first=index)
                self._listbox.activate(index)

        return "break"

    def _next(self, event):
        if self._listbox is not None:

            current_selection = self._listbox.curselection()
            if len(current_selection)==0:
                self._listbox.selection_set(0)
                self._listbox.activate(0)
            else:
                index = int(current_selection[0])
                self._listbox.selection_clear(index)
                
                if index == self._listbox.size() - 1:
                    index = 0
                else:
                    index +=1
                    
                self._listbox.see(index)
                self._listbox.selection_set(index)
                self._listbox.activate(index)
        return "break"
Esempio n. 5
0
class Combobox_Autocomplete(Entry, object):
    def __init__(self, master, list_of_items=None, autocomplete_function=None, listbox_width=None, listbox_height=7, ignorecase_match=False, startswith_match=True, vscrollbar=True, hscrollbar=True, **kwargs):
        if hasattr(self, "autocomplete_function"):
            if autocomplete_function is not None:
                raise ValueError("Combobox_Autocomplete subclass has 'autocomplete_function' implemented")
        else:
            if autocomplete_function is not None:
                self.autocomplete_function = autocomplete_function
            else:
                if list_of_items is None:
                    raise ValueError("If not guiven complete function, list_of_items can't be 'None'")

                if ignorecase_match:
                    if startswith_match:
                        def matches_function(entry_data, item):
                            return item.startswith(entry_data)
                    else:
                        def matches_function(entry_data, item):
                            return item in entry_data

                    self.autocomplete_function = lambda entry_data: [item for item in self.list_of_items if matches_function(entry_data, item)]
                else:
                    if startswith_match:
                        def matches_function(escaped_entry_data, item):
                            if re.match(escaped_entry_data, item, re.IGNORECASE):
                                return True
                            else:
                                return False
                    else:
                        def matches_function(escaped_entry_data, item):
                            if re.search(escaped_entry_data, item, re.IGNORECASE):
                                return True
                            else:
                                return False
                    
                    def autocomplete_function(entry_data):
                        escaped_entry_data = re.escape(entry_data)
                        return [item for item in self.list_of_items if matches_function(escaped_entry_data, item)]

                    self.autocomplete_function = autocomplete_function

        self._listbox_height = int(listbox_height)
        self._listbox_width = listbox_width

        self.list_of_items = list_of_items
        
        self._use_vscrollbar = vscrollbar
        self._use_hscrollbar = hscrollbar

        kwargs.setdefault("background", "white")

        if "textvariable" in kwargs:
            self._entry_var = kwargs["textvariable"]
        else:
            self._entry_var = kwargs["textvariable"] = StringVar()

        Entry.__init__(self, master, **kwargs)

        self._trace_id = self._entry_var.trace('w', self._on_change_entry_var)
        
        self._listbox = None

        self.bind("<Tab>", self._on_tab)
        self.bind("<Up>", self._previous)
        self.bind("<Down>", self._next)
        self.bind('<Control-n>', self._next)
        self.bind('<Control-p>', self._previous)

        self.bind("<Return>", self._update_entry_from_listbox)
        self.bind("<Escape>", lambda event: self.unpost_listbox())
        #self.bind("<FocusOut>", lambda event: self.unpost_listbox())
        
    def _on_tab(self, event):
        #self.post_listbox()
        self.unpost_listbox()        
        #frmbill.cbouom.focus() 
             

        #self._update_entry_from_listbox()        
        #self.unpost_listbox()
        # if self._listbox is not None:
        #     self._listbox.master.destroy()
        #     self._listbox = None
        return "break"
   
    def _on_change_entry_var(self, name, index, mode):
        
        entry_data = self._entry_var.get()

        if entry_data == '':
            #print('test111')
            self.unpost_listbox()
            self.focus()
        else:
            if len(entry_data) < 3:
                return True
            values = finditem(entry_data)
            #kk
            #self.autocomplete_function(entry_data)
            if values:
                if self._listbox is None:
                    self._build_listbox(values)
                else:
                    self._listbox.delete(0, END)

                    height = min(self._listbox_height, len(values))
                    self._listbox.configure(height=height)

                    for item in values:
                        self._listbox.insert(END, item)
                
            else:
                self.unpost_listbox()
                self.focus()

    def _build_listbox(self, values):
        listbox_frame = Frame()

        self._listbox = Listbox(listbox_frame, background="white", selectmode=SINGLE, activestyle="none", exportselection=False)
        self._listbox.grid(row=0, column=0,sticky = N+E+W+S)

        self._listbox.bind("<ButtonRelease-1>", self._update_entry_from_listbox)
        self._listbox.bind("<Return>", self._update_entry_from_listbox)
        self._listbox.bind("<Escape>", lambda event: self.unpost_listbox())
        
        self._listbox.bind('<Control-n>', self._next)
        self._listbox.bind('<Control-p>', self._previous)

        if self._use_vscrollbar:
            vbar = Scrollbar(listbox_frame, orient=VERTICAL, command= self._listbox.yview)
            vbar.grid(row=0, column=1, sticky=N+S)
            
            self._listbox.configure(yscrollcommand= lambda f, l: autoscroll(vbar, f, l))
            
        if self._use_hscrollbar:
            hbar = Scrollbar(listbox_frame, orient=HORIZONTAL, command= self._listbox.xview)
            hbar.grid(row=1, column=0, sticky=E+W)
            
            self._listbox.configure(xscrollcommand= lambda f, l: autoscroll(hbar, f, l))

        listbox_frame.grid_columnconfigure(0, weight= 1)
        listbox_frame.grid_rowconfigure(0, weight= 1)

        x = -self.cget("borderwidth") - self.cget("highlightthickness") 
        y = self.winfo_height()-self.cget("borderwidth") - self.cget("highlightthickness")

        if self._listbox_width:
            width = self._listbox_width
        else:
            width=self.winfo_width()

        listbox_frame.place(in_=self, x=x, y=y, width=width)
        
        height = min(self._listbox_height, len(values))
        self._listbox.configure(height=height)

        for item in values:
            self._listbox.insert(END, item)

    def post_listbox(self):
        if self._listbox is not None: return

        entry_data = self._entry_var.get()
        if entry_data == '': return

        values = self.autocomplete_function(entry_data)
        if values:
            self._build_listbox(values)

    def unpost_listbox(self):
        if self._listbox is not None:
            self._listbox.master.destroy()
            self._listbox = None

    def get_value(self):
        return self._entry_var.get()

    def set_value(self, text, close_dialog=False):
        self._set_var(text)

        if close_dialog:
            self.unpost_listbox()

        self.icursor(END)
        self.xview_moveto(1.0)
        
    def _set_var(self, text):
        self._entry_var.trace_vdelete("w", self._trace_id)
        self._entry_var.set(text)
        self._trace_id = self._entry_var.trace('w', self._on_change_entry_var)
        if len(text) > 0:
            find_price(text)
        #kk

    def _update_entry_from_listbox(self, event):
        if self._listbox is not None:
            current_selection = self._listbox.curselection()
            
            if current_selection:
                text = self._listbox.get(current_selection)
                self._set_var(text)

            self._listbox.master.destroy()
            self._listbox = None

            self.focus()
            self.icursor(END)
            self.xview_moveto(1.0)
            
        return "break"

    def _previous(self, event):
        if self._listbox is not None:
            current_selection = self._listbox.curselection()

            if len(current_selection)==0:
                self._listbox.selection_set(0)
                self._listbox.activate(0)
            else:
                index = int(current_selection[0])
                self._listbox.selection_clear(index)

                if index == 0:
                    index = END
                else:
                    index -= 1

                self._listbox.see(index)
                self._listbox.selection_set(first=index)
                self._listbox.activate(index)

        return "break"

    def _next(self, event):
        if self._listbox is not None:

            current_selection = self._listbox.curselection()
            if len(current_selection)==0:
                self._listbox.selection_set(0)
                self._listbox.activate(0)
            else:
                index = int(current_selection[0])
                self._listbox.selection_clear(index)
                
                if index == self._listbox.size() - 1:
                    index = 0
                else:
                    index +=1
                    
                self._listbox.see(index)
                self._listbox.selection_set(index)
                self._listbox.activate(index)
        return "break"

# if __name__ == '__main__':
#     try:
#         from Tkinter import Tk
#     except ImportError:
#         from tkinter import Tk

#     list_of_items = ["Cordell Cannata", "Lacey Naples", "Zachery Manigault", "Regan Brunt", "Mario Hilgefort", "Austin Phong", "Moises Saum", "Willy Neill", "Rosendo Sokoloff", "Salley Christenberry", "Toby Schneller", "Angel Buchwald", "Nestor Criger", "Arie Jozwiak", "Nita Montelongo", "Clemencia Okane", "Alison Scaggs", "Von Petrella", "Glennie Gurley", "Jamar Callender", "Titus Wenrich", "Chadwick Liedtke", "Sharlene Yochum", "Leonida Mutchler", "Duane Pickett", "Morton Brackins", "Ervin Trundy", "Antony Orwig", "Audrea Yutzy", "Michal Hepp", "Annelle Hoadley", "Hank Wyman", "Mika Fernandez", "Elisa Legendre", "Sade Nicolson", "Jessie Yi", "Forrest Mooneyhan", "Alvin Widell", "Lizette Ruppe", "Marguerita Pilarski", "Merna Argento", "Jess Daquila", "Breann Bevans", "Melvin Guidry", "Jacelyn Vanleer", "Jerome Riendeau", "Iraida Nyquist", "Micah Glantz", "Dorene Waldrip", "Fidel Garey", "Vertie Deady", "Rosalinda Odegaard", "Chong Hayner", "Candida Palazzolo", "Bennie Faison", "Nova Bunkley", "Francis Buckwalter", "Georgianne Espinal", "Karleen Dockins", "Hertha Lucus", "Ike Alberty", "Deangelo Revelle", "Juli Gallup", "Wendie Eisner", "Khalilah Travers", "Rex Outman", "Anabel King", "Lorelei Tardiff", "Pablo Berkey", "Mariel Tutino", "Leigh Marciano", "Ok Nadeau", "Zachary Antrim", "Chun Matthew", "Golden Keniston", "Anthony Johson", "Rossana Ahlstrom", "Amado Schluter", "Delila Lovelady", "Josef Belle", "Leif Negrete", "Alec Doss", "Darryl Stryker", "Michael Cagley", "Sabina Alejo", "Delana Mewborn", "Aurelio Crouch", "Ashlie Shulman", "Danielle Conlan", "Randal Donnell", "Rheba Anzalone", "Lilian Truax", "Weston Quarterman", "Britt Brunt", "Leonie Corbett", "Monika Gamet", "Ingeborg Bello", "Angelique Zhang", "Santiago Thibeau", "Eliseo Helmuth"]

#     root = Tk()
#     root.geometry("300x200")

#     combobox_autocomplete = Combobox_Autocomplete(root, list_of_items, highlightthickness=1)
#     combobox_autocomplete.pack()
    
#     combobox_autocomplete.focus()
    
#     root.mainloop()
class App(tk.Frame):
    def __init__(self, master, *args, **kw):
        super().__init__(master, *args, **kw)
        self.root = master
        self.master.title('Rebuild List')
        # Width, Height of application
        self.master.geometry("775x700")
        self.store = Combobox_Autocomplete
        self.alldicts = {}
        self.create_widgets()
        self.create_widgets1()
        self.refresh_button()

    def create_widgets(self, *args):
        # Calculate button
        self.imgtitle = ImageTk.PhotoImage(
            Image.open(
                'C:\\Users\\Chris\\PycharmProjects\\untitled\\snapsrebuild.png'
            ))
        self.lab = tk.Label(image=self.imgtitle)
        self.lab.grid(row=0, column=3, padx=20, pady=20)
        # Heading Labels
        # Consumable Label
        self.consume_label = tk.Label(self.root,
                                      text='Items:',
                                      font=('Arial', 12, 'bold'))
        self.consume_label.grid(row=1, column=0, columnspan=3, padx=50)
        # Rebuild List Center Text
        self.consume_label = tk.Label(self.root,
                                      text='Rebuild List',
                                      font=('Arial', 12, 'bold'))
        self.consume_label.grid(row=1, column=3, padx=50)
        # Armour Text
        self.consume_label = tk.Label(self.root,
                                      text='items:',
                                      font=('Arial', 12, 'bold'))
        self.consume_label.grid(row=1, column=5, columnspan=3, padx=50)
        #######################################################################################################################
        #                                               Left Side buttons and input
        #######################################################################################################################
        # 111111
        # Check Button Number One
        self.is_checked = IntVar()
        self.option_yes = tk.Checkbutton(self.root,
                                         text="",
                                         onvalue=1,
                                         offvalue=0,
                                         variable=self.is_checked,
                                         command=self.callback)
        self.option_yes.grid(row=2, column=0, padx=15)
        # Entry Label To the right of the checkbox
        self.entry_0 = tk.StringVar()
        self.combobox_autocomplete = Combobox_Autocomplete(
            self.root,
            list_of_items,
            textvariable=self.entry_0,
            highlightthickness=1)
        self.combobox_autocomplete.grid(row=2, column=1)
        # Insert button
        self.insert_butt = tk.Button(self.root,
                                     text='Insert',
                                     command=lambda: self.commando())
        self.insert_butt.grid(row=2, column=2, padx=10)
        ########################################################################################################################
        # Check Button Number Two                                                                                22222
        self.is_checked1 = IntVar()
        self.option_yes1 = tk.Checkbutton(self.root,
                                          text="",
                                          onvalue=1,
                                          offvalue=0,
                                          variable=self.is_checked1,
                                          command=self.callback1)
        self.option_yes1.grid(row=3, column=0, padx=15)
        # Entry Label To the right of the checkbox
        self.entry_1 = tk.StringVar()
        self.combobox_autocomplete1 = Combobox_Autocomplete(
            self.root,
            list_of_items,
            textvariable=self.entry_1,
            highlightthickness=1)
        self.combobox_autocomplete1.grid(row=3, column=1)
        # Insert button
        self.insert_butt1 = tk.Button(self.root,
                                      text='Insert',
                                      command=lambda: self.commando1())
        self.insert_butt1.grid(row=3, column=2, padx=10)
        ########################################################################################################################
        # Check Button Number Three                                                                             3333333
        self.is_checked2 = IntVar()
        self.option_yes2 = tk.Checkbutton(self.root,
                                          text="",
                                          onvalue=1,
                                          offvalue=0,
                                          variable=self.is_checked2,
                                          command=self.callback2)
        self.option_yes2.grid(row=4, column=0, padx=15)
        # Entry Label To the right of the checkbox
        self.entry_2 = tk.StringVar()
        self.combobox_autocomplete2 = Combobox_Autocomplete(
            self.root,
            list_of_items,
            textvariable=self.entry_2,
            highlightthickness=1)
        self.combobox_autocomplete2.grid(row=4, column=1)
        # Insert button
        self.insert_butt2 = tk.Button(self.root,
                                      text='Insert',
                                      command=lambda: self.commando2())
        self.insert_butt2.grid(row=4, column=2, padx=10)
        ########################################################################################################################
        # Check Button Number Four                                                                              4444444
        self.is_checked3 = IntVar()
        self.option_yes3 = tk.Checkbutton(self.root,
                                          text="",
                                          onvalue=1,
                                          offvalue=0,
                                          variable=self.is_checked3,
                                          command=self.callback3)
        self.option_yes3.grid(row=5, column=0, padx=15)
        # Entry Label To the right of the checkbox
        self.entry_3 = tk.StringVar()
        self.combobox_autocomplete3 = Combobox_Autocomplete(
            self.root,
            list_of_items,
            textvariable=self.entry_3,
            highlightthickness=1)
        self.combobox_autocomplete3.grid(row=5, column=1)
        # Insert button
        self.insert_butt3 = tk.Button(self.root,
                                      text='Insert',
                                      command=lambda: self.commando3())
        self.insert_butt3.grid(row=5, column=2, padx=10)
        ########################################################################################################################
        # Parts list (listbox)                                                                                 LISTBOX:
        self.list_box = Listbox(self.root,
                                border=0,
                                width=40,
                                height=20,
                                justify='center')
        self.list_box.grid(row=2, rowspan=5, column=3, pady=5)
        # Create scrollbar
        self.scrollbar = tk.Scrollbar(self.root)
        self.scrollbar.grid(row=3, column=4)
        # Set scrollbar to parts
        self.list_box.configure(yscrollcommand=self.scrollbar.set)
        self.scrollbar.configure(command=self.list_box.yview)

    ########################################################################################################################
    # LEFT SIDE FUNCTIONS
    ########################################################################################################################
    # Insert Button On the left right
    def commando(self):
        x = 'Consumables'
        self.alldicts.update({x: (self.entry_0.get())})
        self.list_box.delete(0)
        self.list_box.insert(0, self.entry_0.get())
        for (key, value) in self.alldicts.items():
            print(key, "::", value)
        return ()

    def commando1(self):
        x = 'Consumables1'
        self.alldicts.update({x: (self.entry_1.get())})
        self.list_box.delete(1)
        self.list_box.insert(1, self.entry_1.get())
        for (key, value) in self.alldicts.items():
            print(key, "::", value)
        return ()
        # Insert Button On the left right

    def commando2(self):
        x = 'Consumables2'
        self.alldicts.update({x: (self.entry_2.get())})
        self.list_box.delete(2)
        self.list_box.insert(2, self.entry_2.get())
        for (key, value) in self.alldicts.items():
            print(key, "::", value)
        return ()
        # Insert Button On the left right

    def commando3(self):
        x = 'Consumables3'
        self.alldicts.update({x: (self.entry_3.get())})
        self.list_box.delete(3)
        self.list_box.insert(3, self.entry_3.get())
        for (key, value) in self.alldicts.items():
            print(key, "::", value)
        return ()

    #######################################################################################################################
    def callback(self):
        if self.is_checked.get():
            self.list_box.itemconfig(0, {'bg': 'green'})
        else:
            self.list_box.itemconfig(0, {'bg': '#ffffff'})

    def callback1(self):
        if self.is_checked1.get():
            self.list_box.itemconfig(1, {'bg': 'green'})
        else:
            self.list_box.itemconfig(1, {'bg': '#ffffff'})

    def callback2(self):
        if self.is_checked2.get():
            self.list_box.itemconfig(2, {'bg': 'green'})
        else:
            self.list_box.itemconfig(2, {'bg': '#ffffff'})

    def callback3(self):
        if self.is_checked3.get():
            self.list_box.itemconfig(3, {'bg': 'green'})
        else:
            self.list_box.itemconfig(3, {'bg': '#ffffff'})

    ########################################################################################################################
    # RIGHT SIDE BUTTONS AND LABELS
    ########################################################################################################################
    # 5555555
    def create_widgets1(self, *args):
        # Check Button Number One
        self.is_checked4 = IntVar()
        self.option_yes4 = tk.Checkbutton(self.root,
                                          text="",
                                          onvalue=1,
                                          offvalue=0,
                                          variable=self.is_checked4,
                                          command=self.callback4)
        self.option_yes4.grid(row=2, column=7, padx=15)
        # Entry Label To the right of the checkbox
        self.entry_4 = tk.StringVar()
        self.combobox_autocomplete4 = Combobox_Autocomplete(
            self.root,
            list_of_items,
            textvariable=self.entry_4,
            highlightthickness=1)
        self.combobox_autocomplete4.grid(row=2, column=6)
        # Insert button
        self.insert_butt4 = tk.Button(self.root,
                                      text='Insert',
                                      command=lambda: self.commando4())
        self.insert_butt4.grid(row=2, column=5, padx=10)
        ########################################################################################################################
        # Check Button Number Two                                                                               666666
        self.is_checked5 = IntVar()
        self.option_yes5 = tk.Checkbutton(self.root,
                                          text="",
                                          onvalue=1,
                                          offvalue=0,
                                          variable=self.is_checked5,
                                          command=self.callback5)
        self.option_yes5.grid(row=3, column=7, padx=15)
        # Entry Label To the right of the checkbox
        self.entry_5 = tk.StringVar()
        self.combobox_autocomplete5 = Combobox_Autocomplete(
            self.root,
            list_of_items,
            textvariable=self.entry_5,
            highlightthickness=1)
        self.combobox_autocomplete5.grid(row=3, column=6)
        # Insert button
        self.insert_butt5 = tk.Button(self.root,
                                      text='Insert',
                                      command=lambda: self.commando5())
        self.insert_butt5.grid(row=3, column=5, padx=10)
        ########################################################################################################################
        # Check Button Number Three                                                                             777777
        self.is_checked6 = IntVar()
        self.option_yes6 = tk.Checkbutton(self.root,
                                          text="",
                                          onvalue=1,
                                          offvalue=0,
                                          variable=self.is_checked6,
                                          command=self.callback6)

        self.option_yes6.grid(row=4, column=7, padx=15)
        # Entry Label To the right of the checkbox
        self.entry_6 = tk.StringVar()
        self.combobox_autocomplete6 = Combobox_Autocomplete(
            self.root,
            list_of_items,
            textvariable=self.entry_6,
            highlightthickness=1)
        self.combobox_autocomplete6.grid(row=4, column=6)
        # Insert button
        self.insert_butt6 = tk.Button(self.root,
                                      text='Insert',
                                      command=lambda: self.commando6())
        self.insert_butt6.grid(row=4, column=5, padx=10)
        ########################################################################################################################
        # Check Button Number Four                                                                             888888
        self.is_checked7 = IntVar()
        self.option_yes7 = tk.Checkbutton(self.root,
                                          text="",
                                          onvalue=1,
                                          offvalue=0,
                                          variable=self.is_checked7,
                                          command=self.callback7)

        self.option_yes7.grid(row=5, column=7, padx=15)
        # Entry Label To the right of the checkbox
        self.entry_7 = tk.StringVar()
        self.combobox_autocomplete7 = Combobox_Autocomplete(
            self.root,
            list_of_items,
            textvariable=self.entry_7,
            highlightthickness=1)
        self.combobox_autocomplete7.grid(row=5, column=6)
        # Insert button
        self.insert_butt7 = tk.Button(self.root,
                                      text='Insert',
                                      command=lambda: self.commando7())
        self.insert_butt7.grid(row=5, column=5, padx=10)

    ########################################################################################################################
    #        FUNCTIONS FOR THE RIGHT SIDE
    ########################################################################################################################
    # Insert Buttons on the right side
    def commando4(self):
        x = 'Consumables'
        self.alldicts.update({x: (self.entry_4.get())})
        self.list_box.delete(4)
        self.list_box.insert(4, self.entry_4.get())
        for (key, value) in self.alldicts.items():
            print(key, "::", value)
        return ()

    def commando5(self):
        x = 'Consumables1'
        self.alldicts.update({x: (self.entry_5.get())})
        self.list_box.delete(5)
        self.list_box.insert(5, self.entry_5.get())
        for (key, value) in self.alldicts.items():
            print(key, "::", value)
        return ()

    def commando6(self):
        x = 'Consumables1'
        self.alldicts.update({x: (self.entry_6.get())})
        self.list_box.delete(6)
        self.list_box.insert(6, self.entry_6.get())
        for (key, value) in self.alldicts.items():
            print(key, "::", value)
        return ()

    def commando7(self):
        x = 'Consumables1'
        self.alldicts.update({x: (self.entry_7.get())})
        self.list_box.delete(7)
        self.list_box.insert(7, self.entry_7.get())
        for (key, value) in self.alldicts.items():
            print(key, "::", value)
        return ()

    ########################################################################################################################
    def callback4(self):
        if self.is_checked4.get():
            self.list_box.itemconfig(4, {'bg': 'green'})
        else:
            self.list_box.itemconfig(4, {'bg': '#ffffff'})

    def callback5(self):
        if self.is_checked5.get():
            self.list_box.itemconfig(5, {'bg': 'green'})
        else:
            self.list_box.itemconfig(5, {'bg': '#ffffff'})

    def callback6(self):
        if self.is_checked6.get():
            self.list_box.itemconfig(6, {'bg': 'green'})
        else:
            self.list_box.itemconfig(6, {'bg': '#ffffff'})

    def callback7(self):
        if self.is_checked7.get():
            self.list_box.itemconfig(7, {'bg': 'green'})
        else:
            self.list_box.itemconfig(7, {'bg': '#ffffff'})

    #########################################################################################################################
    # Refresh button
    def refresh_button(self, *args):
        self.refresher = tk.Button(self.root,
                                   text='Refresh',
                                   command=lambda: self.refresh())
        self.refresher.grid(row=7, column=3, pady=10)

    # Need to refresh the colours that have been checked already, must clear the list box.
    def refresh(self, *args):
        self.list_box.delete(0, END)
        self.combobox_autocomplete.delete(0, "end")
        self.combobox_autocomplete1.delete(0, "end")
        self.combobox_autocomplete2.delete(0, "end")
        self.combobox_autocomplete3.delete(0, "end")
        self.combobox_autocomplete4.delete(0, "end")
        self.combobox_autocomplete5.delete(0, "end")
        self.combobox_autocomplete6.delete(0, "end")
        self.combobox_autocomplete7.delete(0, "end")