Tkinter列表框中的行为差异,箭头键与鼠标单击

时间:2018-06-08 15:24:44

标签: python-2.7 tkinter callback event-binding

我的环境是Python 2.7,在Windows 7上运行。

我正在尝试获取一个Tkinter列表框来触发回调以响应用户更改“活动”项目(即具有焦点的项目)。我正在使用绑定到<<ListboxSelect>>事件来实现这一点,并且它正在运行 - 有点像。

回调本身应该检查新的活动项目是什么,并相应地执行一些处理。当我通过上/下箭头键更改活动项目时,此逻辑以我期望的方式运行。但是,当我指出&amp;点击一个新项目代码,代码错误地将先前的活动项目标识为当前活动项目。

这是一个精简的代码示例,说明了我得到的行为:

import Tkinter as tk

#Root window
root = tk.Tk()

#Callback to show focus change
def updateDisplay(*args):
    focusIndex = str(lb.index(tk.ACTIVE))
    ctrlFI.set('Focus is at index '+focusIndex)

#Control variables
ctrlLB = tk.StringVar()
ctrlFI = tk.StringVar()

#Widgets
lb  = tk.Listbox(root,
                 width=20, height=10,
                 relief=tk.FLAT,highlightthickness=0,
                 selectmode=tk.EXTENDED,
                 activestyle='dotbox',
                 listvariable=ctrlLB)
lbl = tk.Label(root,
               justify=tk.LEFT, anchor=tk.W,
               textvariable=ctrlFI)
lb.grid(row=0,column=0,sticky=tk.NW,padx=(5,0),pady=5)
lbl.grid(row=1,column=0,columnspan=2,sticky=tk.NW,padx=5,pady=5)

#Listbox binding to trigger callback
lb.bind('<<ListboxSelect>>',updateDisplay)

#Initializations to prep GUI
ctrlLB.set('Index0-entry Index1-entry Index2-entry Index3-entry Index4-entry')
ctrlFI.set('Ready')

#Begin app
tk.mainloop()

使用箭头键时的结果如下:

ArrowKeys

但是这是用鼠标点击时得到的结果:

MouseClick

信息'滞后'落后,显示先前的选择。 (如果你第二次点击同一个项目,它就会赶上来。')

所以我的问题是:

  1. 造成这种差异的原因是什么?
  2. 如何修复它,以便鼠标点击可以得到正确的结果?

1 个答案:

答案 0 :(得分:2)

活动项目不一定与所选项目相同。当您按下鼠标时,它会更改所选值,但不会更改活动项。只有释放鼠标按钮后,活动项才会更改。

您应该可以通过在当前未选中的项目上单击并按住鼠标按钮来查看此内容。当你这样做时,你会看到这样的事情:

enter image description here

在上图中,活动项目是由虚线轮廓包围的项目。所选项目为蓝色。当您的代码显示“焦点”时,它会显示活动元素而不是所选元素。

如果您想要所选项目,则需要使用curselection来获取所选项目的索引。它返回一个元组,因此在扩展模式下,您需要获取返回的第一个元素(例如:lb.curselection()[0])。请务必处理curselection返回空字符串的情况。