0
votes
from tkinter import *
from tkinter.ttk import *

root = Tk()
listbox = None
listboxMultiple = None
listboxStr = None
listboxMultipleStr = None

def main():
    global root
    global listboxStr
    global listboxMultipleStr
    global listbox
    global listboxMultiple

    root.protocol("WM_DELETE_WINDOW", exitApplication)
    root.title("Title Name")
    root.option_add('*tearOff', False)  # don't allow tear-off menus
    root.geometry('1600x300')

    listboxStr = StringVar()
    listboxStr.set("ABCD")
    listbox = Listbox(root, name="lb1", listvariable=listboxStr, width=120)
    listbox.pack(side=LEFT)
    listbox.bind("<<ListboxSelect>>", selectListItemCallback)

    listboxMultipleStr = StringVar()
    listboxMultipleStr.set("")
    listboxMultiple = Listbox(root, name="lb2", listvariable=listboxMultipleStr, width=120)
    listboxMultiple.pack(side=LEFT)
    root.mainloop()


def selectListItemCallback(event):
    global listboxMultipleStr
    global listbox
    global listboxMultiple

    print("event.widget is {} and listbox is {} and listboxMultiple is {}\n".format(event.widget, listbox, listboxMultiple))
    selection = event.widget.curselection()
    listboxMultipleStr.set("")
    if selection:
        index = selection[0]
        data = event.widget.get(index)
        newvalue = "{}\n{}".format(data,"SOMETHING")
        print("selected \"{}\"\n".format( data ))
        print("newvalue is \"{}\"\n".format( newvalue ))
        listboxMultiple.insert(END, "{}".format(data))
        listboxMultiple.insert(END, "SOMETHING")
        #listboxMultipleStr.set( newvalue )
    else:
        pass

def exitApplication():
    global root
    root.destroy()

if __name__ == "__main__":
    main()

Using python3 on Windows 7. I've setup a callback "selectListItemCallback" for one of my two listbox widgets. And yet, when I click on the text in "lb1" it works as expected, I update "lb2" with the same selected text plus I add another line to "lb2".

The issue is, when I then select the item in "lb2", it still calls the callback and the event.widget is "lb1" and not "lb2".

My intent is to have a list of items in 'lb1' and when I select any of them, then 'lb2' gets filled with info related to the selected 'lb1' item. And, I don't want a selection callback invoked in my 'lb2' widget.

Can you see what I'm doing wrong that could be causing this strange behavior?

Thank you.

I've posted the code; and this does run on my Windows 7 machine using python3. Python 3.8.6 to be exact.

1

1 Answers

1
votes

It is because the event fires when the first list box loses the selection when you click on the other list box. The event fires whenever the selection changes, not just when it is set.

If you don't want the first listbox to lose its selection when you click in the second listbox, set exportselection to False for the listboxes. Otherwise, tkinter will only allow one to have a selection at a time.