【问题标题】:Stacked Widgets trigger both their own eventStacked Widgets 触发它们自己的事件
【发布时间】:2017-06-13 14:03:12
【问题描述】:

我在使用事件处理程序上的绑定时遇到问题。

我在 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()

【问题讨论】:

  • 请发帖minimal reproducible example。不是您的整个代码具有“太多依赖项”。创建一个新的最小程序来说明您的问题。听起来您只需要两个框架、两个列表框、两个按钮和另外十几行这样的代码就可以将它们联系在一起。
  • 当你写“我不在这里发布任何代码,因为它们的依赖太多”它可以解释为“我对我的不感兴趣完全没有问题”,没有冒犯。即使是长代码也更好,当然你会被否决票踩到,但如果问题很有趣 - 有人可以抓取你的问题(永远不要依赖它)。你的问题不能提供任何答案,只能提供无法验证的假设。查看this 并尝试删除所有依赖项。祝你好运!
  • @BryanOakley 我希望我添加的代码不会太长
  • @Clément 对于您添加的代码,这是一个更好的问题。乍一看,它确实是一个 MCVE 示例 :)

标签: python python-3.x tkinter


【解决方案1】:

&lt;&lt;ListboxSelect&gt;&gt;事件在选择更改时触发。这意味着在进行新选择或取消选择当前选择时。

默认情况下,列表框中的选定项目将导出到X selection。由于总是只能有一个X 选择,因此当您在一个列表框中选择一项时,将取消选择任何其他列表框。因此,当您单击第二个列表框中的某个项目时,第一个列表框的选择将丢失,并导致发送&lt;&lt;ListboxSelect&gt;&gt; 事件。

一个简单的解决方案是在列表框中关闭此行为,以便您可以同时在每个列表框中选择某些内容。为此,您可以在每个列表框中将 exportselection 标志设置为 False

例如:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 2021-07-23
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多