2017-06-13 2 views
4

Ich habe ein Problem mit der Bindung von Event-Handlern.Gestapelte Widgets lösen beide ihr eigenes Ereignis aus

Ich habe zwei gestapelte Frames auf einem Mainframe positioniert. Jeder Rahmen hat seinen eigenen Knopf. Wenn ich auf eine Schaltfläche klicke, wird der zugehörige Rahmen aufgehoben.

Auf jedem Rahmen habe ich eine Listbox. Diese Listenfelder befinden sich an derselben Position im mainFrame. Wenn ich ein Element in der ersten Listbox auswähle, füllt es die andere Listbox mit neuem Inhalt. Dann klicke ich auf die zweite Frame-Schaltfläche, um auf meine zweite Listbox zuzugreifen. Ich habe das Ereignis dupliziert (mit neuen Namen), um genau dasselbe mit meiner zweiten Listbox zu tun, um eine dritte Listbox zu füllen.

Wenn ich jedoch ein Element in meiner zweiten Listbox auswähle, scheint es, dass das Ereignis der ersten Listbox auch nur einmal ausgelöst wird (wenn ich meine Auswahl wiederhole, löst es nur das Ereignis der zweiten Listbox aus).

EDIT: Ich habe eine "kurze" Version meines Codes wie gewünscht.

Wenn ich db1 oder db2 als erste Listbox auswähle, wird der frame2 aufgehoben und test2 wird gedruckt. Dann wähle ich item1 oder item2 und beide test2/test1 anstelle von nur 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() 
+2

Bitte senden Sie eine [MCVE]. NICHT dein ganzer Code mit "zu viel Abhängigkeiten". Erstellen Sie ein neues _minimal_-Programm, das Ihr Problem veranschaulicht. Es klingt, als ob Sie nur zwei Frames, zwei Listboxen, zwei Buttons und ein weiteres Dutzend solcher Codezeilen benötigen, um alles miteinander zu verbinden. –

+0

Wenn Sie schreiben * "Ich poste hier keinen Code, weil sie zu viel Abhängigkeiten sind" * kann es interpretiert werden als * "Ich interessiere mich überhaupt nicht für meine Frage" *, nichts für ungut. Selbst ein langer Code ist besser, natürlich wirst du von Downvotes gestampft, aber wenn die Frage interessant ist - könnte jemand dein Problem krabbeln (verlasse dich nie darauf). Wie kann Ihre Frage keine Antworten liefern, sondern nur Annahmen, die nicht verifizierbar sind. Werfen Sie einen Blick auf [this] (https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users/261593) und versuchen Sie, alle Abhängigkeiten zu trennen . Viel Glück! – CommonSense

+0

@BryanOakley Ich hoffe, der Code, den ich hinzugefügt habe, wird nicht zu lang sein –

Antwort

3

Die <<ListboxSelect>> Ereignis ausgelöst wird, wenn sich die Auswahl ändert gedruckt. Das bedeutet sowohl, wenn eine neue Auswahl getroffen wird als auch die aktuelle Auswahl aufgehoben wird.

Standardmäßig wird das ausgewählte Element in einer Listbox in die X selection exportiert. Da es immer nur eine X-Auswahl geben kann, werden alle anderen Listenfelder deaktiviert, wenn Sie ein Element in einer Listbox auswählen. Wenn Sie also auf ein Element in der zweiten Listbox klicken, geht die Auswahl der ersten Listbox verloren, und das Ereignis <<ListboxSelect>> wird gesendet.

Eine einfache Lösung besteht darin, dieses Verhalten in Ihren Listboxen zu deaktivieren, damit Sie in jeder Listbox gleichzeitig etwas auswählen können. Sie tun dies, indem Sie das Flag exportselection in jeder Listbox auf False setzen.

Zum Beispiel:

self.databases = Listbox(..., exportselection=False) 
... 
self.collections = Listbox(..., exportselection=False) 
+0

Perfekt klar, danke, und es funktioniert. –

Verwandte Themen