2017-06-13 55 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

完美清晰,谢谢,并且,它的工作原理。 –