Tkinter ListboxSelect回调始终处理列表中的最后一项



如果ListboxSelect回调是在没有选择条目的情况下执行的,即在相应列表框中的单击被放置在空白区域中的最后一个项目下方,则"curselection";方法总是返回列表框中最后一项的索引。更重要的是,如果试图使用默认的";浏览";选择列表框的方法,并在按住鼠标按钮的同时将鼠标光标移动到列表框上,任何移动都将执行回调。我试着找到一个关于如何修复它的提示…但没有运气。

from tkinter import *
class simple( Frame ):
def __init__( self, parent = None ):
Frame.__init__( self )
self.master.title( 'DEMO' )
self.master.bind( '<Control-q>', quit )
self.pack()
self.create_widgets()
def create_widgets( self ):
words = ['An','"empty"','selection','processes','the', 'last', 'item','in','this','list' ]
self.lb = Listbox ( self, width = 12, height = 25, selectmode = SINGLE, exportselection = False )
self.lb.pack ( side = LEFT )
self.lb.bind ( '<<ListboxSelect>>', self.process_item )
Label ( self, anchor = W, text = 'nnClick herenn<--nnin the emtpy space...' ).pack ( side = RIGHT )
for w in words:
self.lb.insert ( 0, w )

def process_item ( self, event ):
selection = self.lb.curselection ( )
self.do_stuff_with_item ( self.lb.get ( selection ) )
self.lb.delete ( selection )

def do_stuff_with_item ( self, item ):
print ( item )


def engage():
root = Tk()
sw = simple( root )
sw.pack()
root.mainloop()

if __name__ == '__main__':
engage()

我用python 2.7、3.6(在Linux上(和Win 上的python 3.8进行了尝试

实现您的要求确实很棘手
Listbox的默认行为是在获得焦点时选择最后一个项目。

为了愚弄它,你可以添加一个空单词作为你的words列表的最后一项。这将使其在Listbox中不可见。然后在您的process_item回调中,检查所选值是否为空(也可以选择是否为最后一个值(。如果是,请从Listbox中移除焦点,然后从您的回调中返回。这看起来好像什么都没发生。

这是修改后的代码:

from tkinter import *

class simple(Frame):
def __init__(self, parent=None):
Frame.__init__(self)
self.master.title('DEMO')
self.master.bind('<Control-q>', quit)
self.pack()
self.create_widgets()
def create_widgets(self):
# Words with dummy "" word in the end
words = ['An', '"empty"', 'selection', 'processes', 'the', 'last', 'item', 'in', 'this', 'list', ""]
self.lb = Listbox(self, width=12, height=25, selectmode=SINGLE, exportselection=False)
self.lb.pack(side=LEFT)
self.lb.bind('<<ListboxSelect>>', self.process_item)
Label(self, anchor=W, text='nnClick herenn<--nnin the emtpy space...').pack(side=RIGHT)
self.lb.insert(0, *words)
def process_item(self, event):
selection = self.lb.curselection()
item = self.lb.get(selection)
if item == "":
# It's last dummy item, remove focus and return
self.master.after(0, self.master.focus)
return
# Real item was clicked
self.do_stuff_with_item(item)
self.lb.delete(selection)
def do_stuff_with_item(self, item):
print(item)

def engage():
root = Tk()
sw = simple(root)
sw.pack()
root.mainloop()

if __name__ == '__main__':
engage()

最新更新