隐藏和显示 ttk.Combobox 下拉列表

Hide and show ttk.Combobox dropdown list

情况: 当我使用鼠标按钮单击 ttk.Combobox 的 "down-arrow" 时,它的标准行为是显示下拉列表。第二次点击向下箭头时,组合框下拉列表将隐藏。

使用键盘。按一次 "down-arrow" 可以显示组合框下拉列表。进一步按下 "down-arrow" 将向下滚动下拉列表至末尾。重复按 "up-arrow" 会向上滚动下拉列表,直到 highlight/selection 到达下拉列表的顶部,但最终不会隐藏下拉列表。

问题:不使用鼠标或键盘,即使用计算机编程,如何隐藏一个ttk.Combobox的暴露下拉列表。我知道 w.event_generate("<Down>") 命令可用于编写 ttk.Combobox 以显示其下拉列表。但是我怎样才能达到相反的效果呢?也就是说,如何使用相同的 w.event_generate() 命令来隐藏下拉列表?或者我应该使用什么其他 tkinter 命令来实现我想要的?

我对这个问题进行了多次尝试,终于找到了一种通过编程隐藏组合框下拉列表的方法。我的代码如下所示。

观察:

  1. 使用"combobox_widget_object.event_generate('<Button-1>')"可以 使组合框下拉列表显示。事件 '<Button-1>' 似乎是 固有定义导致此行为。
  2. 运行 2条这条命令背靠背不导致显示 并隐藏组合框下拉列表。它仍然只显示下拉菜单 与单个命令一样列出。
  3. "combobox_widget_object.after(delay_ms, callback=None, *args)" 方法可用于指示组合框 运行 一个函数 经过一定的时间延迟。该函数应包含
    "combobox_widget_object.event_generate('<Button-1>')" 方法导致 隐藏下拉列表。

代码:

# tkinter modules
import tkinter as tk
import tkinter.ttk as ttk

"""
Aim:
Create a combobox widget and use w.event_generate(sequence, sequence,**kw) to
simulate external stimuli to cause combobox dropdown list to show and hide.

Author: Sun Bear
Date: 16/01/2017
"""

# Function to activate combobox's '<Button-1>' event
def _source_delayed_clicked():
    print ('\n def __source_delayed_clicked():')
    print('Delayed 2nd simulation of external stimuli')
    print('HIDE combobox Dropdown list. \n'
          'IT WORKED!')
    source.event_generate('<Button-1>')

root = tk.Tk()
source_var=tk.StringVar()
reference=['Peter', 'Scotty', 'Walter', 'Scott', 'Mary', 'Sarah']

# Create Main Frame in root
frame0 = ttk.Frame(root, borderwidth=10, relief=tk.RAISED)
frame0.grid(row=0, column=0, sticky='nsew') 

# Create Combobox
source = ttk.Combobox(frame0, textvariable=source_var, values=reference)
source.grid(row=0, column=0, sticky='nsew')

# Simulate external stimuli using w.event_generate(sequence,**kw)
print('\n', '1st simulation of external stimuli using: \n'
      '   source.event_generate('"<Button-1>"') \n'
      ' SHOW Combobox Dropdown List.')
source.event_generate('<Button-1>')
#source.event_generate('<Button-1>') # running another similar command
                                    # back to back didn't work
delay = 1000*6 # 6 seconds delay
source.after(delay, _source_delayed_clicked)

更新: 或者,要隐藏组合框下拉列表,命令 source.event_generate('<Escape>') 可以用来代替函数 def _source_delayed_clicked() 中定义的 source.event_generate('<Button-1>') 命令。这模拟按下键盘 "Esc" 键。