Reputation: 1266
I have a problem using binding on event handlers.
I have two stacked frames positionned on a mainFrame. Each frame has its own button. When I click on one button, the associated frame is lifted.
On each frame, I have one listbox. These listboxes are at the same position on the mainFrame. When I select one item in the first listbox, it fills the other listbox with new content. Then I click the second frame button to access my second listbox. I duplicated (with new names) the event to do the exact same thing with my second listbox to fill a third listbox.
However, when I select one item in my second listbox, it appears that the first listbox's event is also triggered but only one time (if I redo my selection it only triggers the second listbox's event).
EDIT : I put a "short" version of my code as requested.
When I select db1 or db2 it the first listbox, the frame2 is lifted and test2 is printed. Then I select item1 or item2 and both test2/test1 are printed instead of only test1
from tkinter import *
class Page(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def dbCheckCommand(self, event, page2):
page2.collections.delete(0, END)
print("test2")
page2.collections.insert(END, "item1")
page2.collections.insert(END, "item2")
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.grid_columnconfigure(0, weight=1)
self.databases = Listbox(self, height=2)
self.grid_rowconfigure(1, weight=1)
self.databases.insert(END, "db1")
self.databases.insert(END, "db2")
self.databases.grid(row=1, sticky="nsew")
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.grid_columnconfigure(0, weight=1)
self.colls = []
self.collections = Listbox(self, height=2)
self.grid_rowconfigure(1, weight=1)
self.collections.grid(row=1, sticky="nsew")
class MainView(Frame):
def on_p1_listbox_selection(self, event, page1, page2):
page1.dbCheckCommand(event, page2)
page2.lift()
def on_p2_listbox_selection(self, event):
print("test1")
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=5)
buttonframe = Frame(self)
container = Frame(self)
buttonframe.grid(column=0, row=0, sticky="nsew")
container.grid(column=1, row=0, sticky="nsew")
container.grid_columnconfigure(0, weight=1)
container.grid_rowconfigure(0, weight=1)
p1 = Page1(container)
p2 = Page2(container)
p1.grid(column=0, row=0, sticky="nsew")
p2.grid(column=0, row=0, sticky="nsew")
b1 = Button(buttonframe, text="1 - Server & Database", command=p1.lift)
b2 = Button(buttonframe, text="2 - Collection", command=p2.lift)
b1.pack(fill="both", expand=1)
b2.pack(fill="both", expand=1)
p1.databases.bind("<<ListboxSelect>>", lambda event: self.on_p1_listbox_selection(event, p1, p2))
p2.collections.bind("<<ListboxSelect>>", lambda event: self.on_p2_listbox_selection(event))
p1.show()
if __name__ == "__main__":
root = Tk()
main = MainView(root)
main.pack(fill="both", expand=1)
root.wm_geometry("1100x500")
root.wm_title("MongoDB Timed Sample Generator")
root.mainloop()
Upvotes: 4
Views: 85
Reputation: 386342
The <<ListboxSelect>>
event fires whenever the selection changes. That means both when a new selection is made, or the current selection is de-selected.
By default the selected item in a listbox will be exported to the X selection. Since there can always only be one X selection, when you select an item in one listbox, any other listboxes will be deselected. Thus, when you click on an item in the second listbox, the selection of the first listbox will be lost, and causing the <<ListboxSelect>>
event to be sent.
A simple solution is to turn off this behavior in your listboxes, so that you can have something selected in each listbox simultaneously. You do this by setting the exportselection
flag to False
in each listbox.
For example:
self.databases = Listbox(..., exportselection=False)
...
self.collections = Listbox(..., exportselection=False)
Upvotes: 3