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 = '\n\nClick here\n\n<--\n\nin 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 上)和 python 3.8 在 Win 上尝试过
If the ListboxSelect callback is executed without having an entry selected, i.e the click in the respective listbox has been placed below the last item in the empty space, the "curselection" method always returns the index of the last item in the listbox. Even more, if one tries to use the default "browse" selection method for the listbox and moves the mouse cursor over the listbox while holding mouse button pressed, any move will execute the callback. I tried to find a hint on how to fix it... no luck though.
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 = '\n\nClick here\n\n<--\n\nin 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()
I tried it with python 2.7, 3.6 ( on Linux ) and with python 3.8 on Win
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实现您所要求的目标确实很棘手。
Listbox
的默认行为是在获得焦点时选择最后一项。为了欺骗它,您可以添加一个空单词作为您的
单词
列表的最后一项。这将使其在
Listbox
中不可见。然后在您的
process_item
回调中,检查所选值是否为空(也可以选择是否为最后一个值)。如果是这样,请从Listbox
中移除焦点并从您的回调中返回。这看起来就像什么都没发生一样。这是修改后的代码:
It was indeed tricky to achieve what You've asked for.
Default behavior of
Listbox
is to select last item when it gains focus.To fool it, You can add an empty word as a last item of Your
words
list.This will make it invisible in a
Listbox
.Then in Your
process_item
callback, check if selected value is empty (optionally if it's last value as well). If so, remove focus fromListbox
and return from Your callback. This will look as if nothing happened.Here is modified code: