我想做一个功能:当单击 tkinter 中的组合框并打开下拉菜单时,当您按任意键(例如“s”)时,它会选择组合框中的第一个元素,以“s”字母开头。 但我不知道如何将它直接绑定到由组合框创建的列表框。如果我将 keyPress 事件绑定到组合框,则当下拉菜单打开时,它不会接收事件。
所以,我尝试了这样的事情:
self.combobox.bind("<KeyPress>", self.keyPressed)
但没有成功。
您能告诉我如何做到这一点吗?或者如果可能的话?
更新:小代码示例
import tkinter as tk
from tkinter import ttk
def pressed(evt):
print ("key pressed")
f = tk.Frame();
f.grid()
c = ttk.Combobox(f,values = ["alfa","betta","gamma"])
c.grid(column = 0, row = 0)
c.bind("<KeyRelease>",pressed)
f.mainloop()
据我了解,目前Python中没有办法获取弹出菜单。而你必须通过 TCL 来做到这一点。弱点是引用的“.f.l”部分,因为它取决于内部小部件的实现。有一个组合框的示例,当您按下键盘按钮时,它将首先按字母选择项目。
from tkinter import ttk
import itertools as it
class mycombobox(ttk.Combobox):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
pd = self.tk.call('ttk::combobox::PopdownWindow', self) #get popdownWindow reference
lb = pd + '.f.l' #get popdown listbox
self._bind(('bind', lb),"<KeyPress>",self.popup_key_pressed,None)
def popup_key_pressed(self,evt):
values = self.cget("values")
for i in it.chain(range(self.current() + 1,len(values)),range(0,self.current())):
if evt.char.lower() == values[i][0].lower():
self.current(i)
self.icursor(i)
self.tk.eval(evt.widget + ' selection clear 0 end') #clear current selection
self.tk.eval(evt.widget + ' selection set ' + str(i)) #select new element
self.tk.eval(evt.widget + ' see ' + str(i)) #spin combobox popdown for selected element will be visible
return
根据您的代码,当键入键/字符(如“s”)时,将选择组合框中以字母开头的第一个项目(如果存在),如果选择相同的键,则选择下一个项目:
def pressed(event):
widget = event.widget
matching_values = [item for item in widget['values'] if item.lower().startswith(event.char.lower())]
# Select the first matching item if available
if matching_values:
current_value = widget.get()
for i, val in enumerate(matching_values):
if current_value == val:
break
i = 0 if i >= len(matching_values)-1 else i+1
widget.set(matching_values[i]) # Set the combobox to the first match