Python 2.7 Tkinter列表框、箭头键和鼠标点击中的行为差异

Python 2.7 Tkinter列表框、箭头键和鼠标点击中的行为差异,python-2.7,tkinter,callback,event-binding,Python 2.7,Tkinter,Callback,Event Binding,我的环境是运行在Windows7上的Python 2.7 我正在尝试获取一个Tkinter列表框来触发回调,以响应用户更改“活动”项(即具有焦点的项)。我正在使用对事件的绑定来实现这一点,它正在工作——有点像 回调本身应该检查新的活动项是什么,并相应地执行一些处理。当我通过向上/向下箭头键更改活动项时,此逻辑以我预期的方式运行。但是,当我点击一个新项目时,代码错误地将先前的活动项目识别为当前项目 下面是一个精简的代码示例,它演示了我得到的行为: import Tkinter as tk #Ro

我的环境是运行在Windows7上的Python 2.7

我正在尝试获取一个Tkinter列表框来触发回调,以响应用户更改“活动”项(即具有焦点的项)。我正在使用对
事件的绑定来实现这一点,它正在工作——有点像

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

下面是一个精简的代码示例,它演示了我得到的行为:

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()
将Tkinter作为tk导入
#根窗口
root=tk.tk()
#回调以显示焦点更改
def updateDisplay(*args):
focusIndex=str(磅指数(tk活跃))
ctrlFI.set('焦点位于索引'+focusIndex)
#控制变量
ctrlLB=tk.StringVar()
ctrlFI=tk.StringVar()
#小部件
lb=传统列表框(根,
宽度=20,高度=10,
浮雕=tk.平坦,高光厚度=0,
selectmode=tk.EXTENDED,
activestyle='dotbox',
listvariable=ctrlLB)
lbl=传统标签(根、,
对正=tk.LEFT,锚=tk.W,
textvariable=ctrlFI)
lb.grid(行=0,列=0,粘性=tk.NW,padx=(5,0),pady=5)
lbl.grid(行=1,列=0,列span=2,粘性=tk.NW,padx=5,pady=5)
#Listbox绑定到触发器回调
lb.bind(“”,updateDisplay)
#准备GUI的初始化
ctrlLB.set('Index0-entry Index1 entry Index2 entry Index3 entry Index4 entry')
ctrlFI.set('Ready')
#开始应用程序
tk.mainloop()
以下是使用箭头键时的结果:

但当你用鼠标点击时,你会得到以下结果:

信息“滞后”一个,显示先前的选择。(如果第二次单击同一项目,它会“赶上”。)

因此,我的问题是:

  • 是什么导致了这种差异
  • 我如何修复它,使鼠标点击得到正确的结果

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

    通过在当前未选中的项目上单击并按住鼠标按钮,您应该能够看到这一点。当您这样做时,您将看到如下内容:

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


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

    这是我要查找的活动项(选择对这项功能不重要)。但是你提供的信息让我走上了正确的轨道。我可以通过添加以下行获得所需的行为:
    root.bind(“”,updateDisplay)