关于python:如何禁用Tkinter Listbox小部件的自由部分的选择?

How to disable selction of the free part of Tkinter Listbox widget as an item?

我正在创建一个基于Tkinter的应用程序。 它具有一个"列表框"窗口小部件,我希望双击该项目。 如果我双击一个项目,那么一切都会很好,但是如果我双击列表框的自由部分,则最后一个项目被选中,并且curselection返回一个元组(而不是一个空的元组)。

这是代码:

1
2
3
4
5
6
7
8
9
10
from tkinter import *


root = Tk()
listbox = Listbox(root)
for item in ("foo","bar"):
    listbox.insert(END, item)
listbox.bind("<Double-1>", lambda event: print(listbox.curselection()))
listbox.pack()
root.mainloop()

我也尝试按照@stovfl的建议使用listbox.get(ACTIVE)listbox.nearest(event.y),但是不幸的是,它也没有帮助。 在第一种情况下,它返回列表框中显示的最后一个字符串,而不是带有最后一个索引的元组。 在第二种情况下,它只是返回了最后一个索引,而不是带有它的元组。

illustration to my problem

PS:我来过这里。 但是我没有将事件绑定到根窗口,而是将其绑定到列表框,但是它也无法正常工作。


我认为有两种方法可以实现:

  • 当用户单击空白处时,取消选择active元素。(我不知道该怎么做)
  • 或判断鼠标的位置。
  • 对于第二种解决方案(您可以使用函数Listbox.bbox()):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import tkinter as tk


    class Custom(tk.Frame):
        def __init__(self, master):
            super(Custom, self).__init__()

            self.master = master
            self.listbox = tk.Listbox(master=self)
            self.pos_list = []
            for item in ("foo","bar"):
                self.listbox.insert(tk.END, item)
            self.listbox.bind("<Double-1>", self.double_click)

            self.listbox.pack()

        def double_click(self, event): # judge the event.y and the position of the first offsetY and the last offsetY
            if (event.y < self.listbox.bbox(0)[1]) or (event.y > self.listbox.bbox(tk.END)[1]+self.listbox.bbox(tk.END)[3]): # if not between it
                print(None)
            else:
                print(self.listbox.nearest(event.y))


    root = tk.Tk()
    customFrame = Custom(root)
    customFrame.pack()
    root.mainloop()

    请参阅:Listbox.bbox