当前位置: 首页 > 面试题库 >

Tkinter和绑定到ListboxSelect事件的两个列表框的意外行为

戚弘和
2023-03-14
问题内容

我正在处理的脚本中遇到一个异常问题。该程序是用Python3 /
Tkinter编写的。它初始化两个列表框,包装在两个单独的框架中,并根据用户的命令显示一个或另一个。当用户在第一个列表框中选择一个项目,然后决定更改屏幕并在第二个框架中选择一个项目时,就会出现异常。

我创建了一个示例代码(如下),以复制该问题。使用此代码,在运行时,单击第一个列表框(白色背景)中的一个项目将使第二个列表框出现(橙色背景)。同样,第一个对象是“未包装的”,因此用户将不再能够与其进行交互。最后,单击第二个列表框中的项目,会从第一个对象的“
on_select_1”方法中引发IndexError。为什么在该事件之后执行该方法?我很清楚自己作为程序员的局限性,但是我很确定这不是应该发生的事情。

import tkinter as tk


class Listbox1(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.lb1 = tk.Listbox(self)
        for i in ["item 1.1", "item 1.2", "item 1.3", "item 1.4"]:
            self.lb1.insert(tk.END, i)
        self.lb1.bind("<<ListboxSelect>>", self.on_select_1)
        self.lb1.pack()

    def on_select_1(self, *args):
        try:
            print("item {} selected in listbox 1".format(self.lb1.curselection()[0]))
        except IndexError:
            print("IndexError raised in method 'on_select_1'")

        self.master.switch()


class Listbox2(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.lb2 = tk.Listbox(self, bg='orange')
        for i in ["item 2.1", "item 2.2", "item 2.3", "item 2.4"]:
            self.lb2.insert(tk.END, i)
        self.lb2.bind("<<ListboxSelect>>", self.on_select_2)
        self.lb2.pack()

    def on_select_2(self, *args):
        print("item {} selected in listbox 2".format(self.lb2.curselection()[0]))


class App(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.pack()
        self.lb1_frame = Listbox1(self)
        self.lb2_frame = Listbox2(self)
        self.lb1_frame.pack()

    def switch(self):
        self.lb1_frame.pack_forget()
        self.lb2_frame.pack()


def main():
    root = tk.Tk()
    app = App(root)
    app.mainloop()


if __name__ == '__main__':
    main()

问题答案:

默认情况下,tkinter一次只允许一个窗口小部件保留选择。因此,当您在第二个列表框中选择某项时,将取消选择在第一个列表框中选择的项目。这将导致您的函数被调用。发生这种情况时,self.lb1.curselection()[0])由于选择为空,将引发错误。

一个简单的解决方案是,当您在第二个列表框中选择某些内容时,使选择在第一个列表框中保持不变,这是将两个列表框的exportselection选项False都设置为。

self.lb1 = tk.Listbox(self, exportselection=False)
...
self.lb2 = tk.Listbox(self, bg='orange', exportselection=False)


 类似资料:
  • 问题内容: 如何停止事件的处理或切换事件的功能? 修改后的代码: 问题答案: 您只需使用事件的新功能再次调用即可。既然你没有利用第三个参数,在此只是简单地覆盖任何已经存在。默认情况下,此参数为,但它也接受,它将在该事件已触发的回调中添加回调。 但是,如果您开始使用该可选参数,则需要使用该函数删除单个回调。当你调用一个返回。您可以将此作为第二个参数传递给。 例:

  • 主要内容:Listbox控件,Combobox控件列表框(Listbox)和复选框(Combobox)是 Tkinter 中两个控件,由于其非常相似,本节将它们放在一起进行介绍。 Listbox控件 首先介绍一下列表框,即 Listbox。在使用 Tkinter 进行 GUI 编程的过程中,如果需要用户自己进行选择时就可以使用列表框控件。列表框中的选项可以是多个条目,也可以是单个唯一条目,但常用于多个条目。 下面对列表框控件(Listbox)的常

  • 问题内容: 我想撤消一个列表,但是我设法做到了,但是在工作的中间我发现了一些奇怪的事情。下面的程序按预期工作,但list_reversed [i] = list [len(list)-1-i] 和 print(list [i]) (顺理成章地注释了 最后一行 )这 行 引起了 list 的更改。我没看到什么?我的Python版本是3.3.3。先感谢您。 问题答案: 以下: 使两个变量引用相同的列表

  • 本文向大家介绍js绑定事件和解绑事件,包括了js绑定事件和解绑事件的使用技巧和注意事项,需要的朋友参考一下 在js中绑定多个事件用到的是两个方法:attachEvent和addEventListener,但是这两个方法又存在差异性 attachEvent方法  只支持IE678,不兼容其他浏览器 addEventListener方法   兼容火狐谷歌,不兼容IE8及以下 addEventListe

  • 问题内容: 我只是想知道在Tkinter中是否可以将click事件绑定到画布。 我希望能够在画布上单击任意位置,然后将一个对象移到画布上。我能够提出议案,但是我还没有找到在画布上绑定click事件的方法。 问题答案: 直接取自Effbot关于事件的教程中的示例。 在此示例中,我们使用框架小部件的bind方法将回调函数绑定到名为的事件。运行该程序,然后在出现的窗口中单击。每次单击,都会在控制台窗口中

  • 本文向大家介绍Python tkinter之Bind(绑定事件)的使用示例,包括了Python tkinter之Bind(绑定事件)的使用示例的使用技巧和注意事项,需要的朋友参考一下 1、绑定鼠标事件并获取事件属性 2、绑定键盘事件并获取事件属性 以上就是Python tkinter之Bind(绑定事件)的使用示例的详细内容,更多关于python tkinter Bind(绑定事件)的资料请关注呐