2017-06-13 17 views
4

我在使用綁定事件處理程序時遇到問題。Stacked Widget觸發他們自己的事件

我有兩個堆疊的框架定位在一個mainFrame上。每個框架都有自己的按鈕。當我點擊一個按鈕時,關聯的框架被擡起。

在每一幀上,我有一個列表框。這些列表框位於mainFrame上的相同位置。當我在第一個列表框中選擇一個項目時,它會用新的內容填充另一個列表框。然後我點擊第二個框架按鈕來訪問我的第二個列表框。我複製(使用新名字)事件來完成與第二​​個列表框完全相同的操作,以填充第三個列表框。但是,當我在第二個列表框中選擇一個項目時,似乎第一個列表框的事件也被觸發但只有一次(如果我重做我的選擇它只觸發第二個列表框的事件)。

編輯:我把我的代碼的「短」版本按要求。

當我選擇db1或db2它的第一個列表框,frame2被解除,test2被打印出來。然後我選擇ITEM1或ITEM2和二者TEST2/TEST1被印刷的僅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

請張貼[MCVE]。不是你的整個代碼「太多依賴」。創建一個說明你的問題的新的_minimal_程序。這聽起來像你只需要兩個框架,兩個列表框,兩個按鈕,以及另外十幾行這樣的代碼將它們聯繫在一起。 –

+0

當你寫*「我不在這裏發佈任何代碼,因爲它們太依賴了」*它可以被解釋爲*「我根本不關心我的問題」*,沒有冒犯性。即使是長碼也更好,當然你會被downvotes壓制,但如果問題很有趣 - 有人可以抓住你的問題(永遠不要依賴這個問題)。至於你的問題可以提供沒有答案,但只有假設,這是不可證實的。看看[這](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users/261593),並試圖削減所有的依賴。祝你好運! – CommonSense

+0

@BryanOakley我希望我添加的代碼不會太長 –

回答

3

<<ListboxSelect>>事件觸發每當選擇更改來代替。這意味着無論何時進行新的選擇,或者當前的選擇都被取消選擇。

默認情況下,列表框中的選定項目將被導出到X selection。由於總是隻能有一個X選擇,當您在一個列表框中選擇一個項目時,將取消選擇任何其他列表框。因此,當您單擊第二個列表框中的項目時,第一個列表框的選擇將丟失,並導致發送<<ListboxSelect>>事件。

一個簡單的解決方案是關閉你的列表框中的這種行爲,這樣你可以同時在每個列表框中選擇一些東西。您可以通過在每個列表框中將exportselection標誌設置爲False來完成此操作。

例如:

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

完美清晰,謝謝,並且,它的工作原理。 –