PySimpleGUI 中 return_keyboard_events 的意外行为

unexpected behaviour of return_keyboard_events in 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 它 return 相同按下所有这三个按钮,

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

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

OK2 按钮上按 Enter 在控制台中打印为:1

OK3 按钮上按 Enter 在控制台中打印为:1

这不是预期的输出。我想要的也应该像鼠标单击事件一样打印自己的键。

我的意图是什么:

  1. 当用户在 OK1 上按 Enter 按钮时,它应该打印('Hello, OK1 pressed.')

  2. 当用户在 OK2 上按下 Enter 按钮时,它应该打印('Hello, OK2 pressed.')

  3. 当用户在 OK3 上按 Enter 按钮时,它应该打印('Hello, OK3 pressed.')

  4. 当用户点击OK1时,它应该打印('Hello, OK1 pressed.')

  5. 当用户点击OK2时,它应该打印('Hello, OK2 pressed.')

  6. 当用户点击OK3时,它应该打印('Hello, OK3 pressed.')

如何实现?

我不完全明白你的目标是什么。你想要什么行为?

当按钮获得焦点时,默认情况下按下 return 键似乎不会触发按钮。 space 栏会。

下面是一些代码,可以根据用户的键盘输入单击按钮。我想那是你在我 re-read 几次你的问题后所描述的。

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 键不会产生按钮点击,SPACE BAR 会。你可以在这个 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()

[编辑 - 对编辑感到抱歉,但我正在试验...]

我终于理解了这个问题并写下这个作为解决方案。它已变成项目的 Demo Program,因为人们确实希望 ENTER 键单击按钮,但 tkinter 和 Qt 似乎都不能以这种方式工作。他们 select 使用空格键的按钮。

此源代码适用于 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 行代码中。将这些代码行添加到您的事件循环中,然后您的 window 将表现出 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()