Brandon
Brandon

Reputation: 361

Tkinter Listbox not deleting items correctly

I have a method that is suppose to take a search parameter and remove everything from the list that does not meet the parameter. But when it runs it removes list items at almost random. I've debugged it and it correctly determines if an item needs to be removed but it doesn't remove the right one. I think it has something to do with when I remove one item it messes up the indexes of the rest of the list, which doesn't with with my method of tracking the index. I posted the whole class but the relevant code is towards the bottom

class StudentFinderWindow(Tkinter.Toplevel):

    def __init__(self):
        Tkinter.Toplevel.__init__(self) # Create Window

        ##### window attributes
        self.title('Edit Students') #sets window title

        ##### puts stuff into the window

        # text
        editStudentInfoLabel = Tkinter.Label(self,text='Select the student from the list below or search for one in the search box provided')
        editStudentInfoLabel.grid(row=0, column=0)

        # entry box
        self.searchRepositoryEntry = Tkinter.Entry(self)
        self.searchRepositoryEntry.grid(row=1, column=0)

        # list box
        self.searchResults = Tkinter.Listbox(self)
        self.searchResults.grid(row=2, column=0)


        # search results initial updater
        self.getStudentList()
        for student in self.studentList:
            self.searchResults.insert(Tkinter.END, student)

        ##### event handler 

        self.searchRepositoryEntry.bind('<KeyRelease>', self.updateSearch)

This is the relevant code

    def updateSearch(self, event):
        parameters = self.searchRepositoryEntry.get()
        int = 0 
        currentList = self.searchResults.get(0, Tkinter.END)
        length = len(parameters)
        print(parameters)
        print(length)
        for i in currentList:
            if not i[0:length] == parameters:
                self.searchResults.delete(int)
            print(i[0:length] == parameters)
            print(i[0:length])
            print(int)
            int += 1


    def getStudentList(self):
        global fileDirectory # gets the directory that all the files are in
        fileList = listdir(fileDirectory) # makes a list of files from the directory
        self.studentList = [] #  makes a new list
        for file in fileList: # for loop that adds each item from the file list to the student list
            self.studentList.append(file[:-4])

Upvotes: 1

Views: 3170

Answers (2)

Bryan Oakley
Bryan Oakley

Reputation: 385890

When you delete an item, everything below it moves up causing the index of all following items to change. The simplest solution to this sort of a problem (it's also common when deleting words from a text widget) is to delete backwards, starting at the end.

Upvotes: 3

unutbu
unutbu

Reputation: 879251

I think you already know the problem. When you delete an item, the index for the rest of the items change. For example, if you delete the 4th item, then the 5th item becomes the "new" 4th item. So you don't want to increment int whenever you delete an item. You can implement that with continue:

for i in currentList:
    if not i[0:length] == parameters:
        self.searchResults.delete(int)
        continue # <--  Use continue so `int` does not increment.
    int += 1

PS. It's not good coding style to use int as a variable name -- in Python it masks the built-in function of the same name.

Upvotes: 2

Related Questions