PySimpleGUI中的return_keyboard_events意外行为

时间:2019-06-20 10:00:03

标签: python-3.x pysimplegui

import PySimpleGUI as sg

layout = [[sg.Button("OK1", key='1', bind_return_key=True)],
      [sg.Button("OK2", key='2', bind_return_key=True)],
      [sg.Button("OK3", key='3', bind_return_key=True)]]
window = sg.Window("Keyboard Test", return_keyboard_events=True).Layout(layout)
while True:
    event, values = window.Read()
    print(event)
    if event == None:
        break

运行上面的代码并执行鼠标单击操作时,得到的输出与预期的一样,

单击 OK1按钮在控制台中打印为: 1

单击 OK2按钮在控制台中打印为: 2

点击 OK3按钮在控制台中打印为: 3

但是,当我执行键盘事件手段时,我通过键盘的Tab键访问该按钮,然后通过键盘在该按钮上按 Enter ,这三个按钮都返回相同的键,

通过Tab键逐个访问这些按钮,然后在每个按钮上按Enter,我得到的结果为

OK1按钮上按Enter键,在控制台中打印为: 1

OK2按钮上的Enter键,在控制台中将打印为: 1

OK3按钮上的Enter键,在控制台中将其打印为: 1

这不是预期的输出。我想要的还应该打印与鼠标单击事件相同的键。

我的意图是什么

  1. 当用户在OK1上按Enter键时,应打印('Hello,已按下OK1。')

  2. 当用户在OK2上按Enter键时,应打印(“ Hello,OK2已按下。”)

  3. 当用户在OK3上按Enter键时,应打印(“ Hello,OK3已按下。”)

  4. 当用户单击OK1时,它应该打印('Hello,按下OK1。')

  5. 当用户单击OK2时,它应该打印('Hello,按下OK2。')

  6. 当用户单击OK3时,它应该打印('Hello,按下OK3。')

如何实现?

2 个答案:

答案 0 :(得分:1)

我不完全了解您的目标是什么。您想要什么行为?

当按钮具有焦点时,默认情况下按回车键似乎不会触发按钮。空格键会。

以下是一些代码,这些代码将根据用户的键盘输入来单击按钮。在我重新阅读了几次您的问题后,我想这就是您的描述。

import PySimpleGUI as sg

layout = [[sg.Button("OK1", key='_1_', )],
          [sg.Button("OK2", key='_2_', )],
          [sg.Button("OK3", key='_3_', )]]

window = sg.Window("Keyboard Test", layout, return_keyboard_events=True)

while True:
    event, values = window.Read()
    # window.Maximize()
    print('event: ', event)
    if event == None:
        break
    if event == '1':
        window.Element('_1_').Click()
    elif event == '2':
        window.Element('_2_').Click()
    elif event == '3':
        window.Element('_3_').Click()

window.Close()

如果要使用键盘控制按钮,则要做的就是收集键盘按键,然后将其转换为所需的任何行为。

当按钮具有焦点(突出显示)时,按ENTER不会产生按钮单击,而空格键会。您可以在tkinter程序中看到这一点:

import tkinter as tk


def write_slogan():
    print("Tkinter is easy to use!")


root = tk.Tk()
frame = tk.Frame(root)
frame.pack()

button = tk.Button(frame,
                   text="QUIT",
                   fg="red",
                   command=quit)
button.pack(side=tk.LEFT)
slogan = tk.Button(frame,
                   text="Hello",
                   command=write_slogan)
slogan.pack(side=tk.LEFT)

root.mainloop()

[编辑-抱歉,我正在尝试...]

答案 1 :(得分:1)

我终于理解了这个问题并将其写为解决方案。它已经变成了该项目的Demo Program,因为人们确实希望ENTER键可以单击一个按钮,但是tkinter和Qt都似乎无法通过这种方式工作。他们使用空格键选择按钮。

此源代码可用于PySimpleGUI和PySimpleGUIQt。只需在顶部使用正确的导入语句即可。

    import PySimpleGUI as sg
    # import PySimpleGUIQt as sg

    QT_ENTER_KEY1 =  'special 16777220'
    QT_ENTER_KEY2 =  'special 16777221'

    layout = [  [sg.T('Test of Enter Key use')],
                [sg.In(key='_IN_')],
                [sg.Button('Button 1', key='_1_')],
                [sg.Button('Button 2', key='_2_')],
                [sg.Button('Button 3', key='_3_')],  ]

    window = sg.Window('My new window', layout,
                       return_keyboard_events=True)
    while True:             # Event Loop
        event, values = window.Read()
        if event is None:
            break
        if event in ('\r', QT_ENTER_KEY1, QT_ENTER_KEY2):         # Check for ENTER key
            elem = window.FindElementWithFocus()                            # go find element with Focus
            if elem is not None and elem.Type == sg.ELEM_TYPE_BUTTON:       # if it's a button element, click it
                elem.Click()
            # check for buttons that have been clicked
        elif event == '_1_':
            print('Button 1 clicked')
        elif event == '_2_':
            print('Button 2 clicked')
        elif event == '_3_':
            print('Button 3 clicked')

在以上所有代码中,实现此功能的部分包含在这4行代码中。将这些代码行添加到您的事件循环,然后您的窗口将运行,以便ENTER键将单击一个按钮。代码的其余部分与单击有关,与布局有关。实际上是由这些语句实现的。

if event in ('\r', QT_ENTER_KEY1, QT_ENTER_KEY2):         # Check for ENTER key
    elem = window.FindElementWithFocus()                            # go find element with Focus
    if elem is not None and elem.Type == sg.ELEM_TYPE_BUTTON:       # if it's a button element, click it
        elem.Click()