Python 3.x PySimpleGUI中返回事件的意外行为

Python 3.x PySimpleGUI中返回事件的意外行为,python-3.x,pysimplegui,Python 3.x,Pysimplegui,当我运行上面的代码并执行鼠标点击操作时,我得到了如下预期的输出: 单击OK1按钮在控制台中打印为:1 单击控制台中的OK2按钮打印为:2 点击OK3按钮在控制台中打印为:3 但是,当我执行“键盘事件”时,我通过键盘的tab键访问该按钮,并通过键盘在该按钮上按Enter,它会在所有这三个按钮上返回相同的键 通过tab键逐个访问这些按钮,然后在每个按钮上按Enter键,结果如下: 在控制台中按Enter onOK1按钮打印为:1 在控制台中按Enter onOK2按钮打印为:1 在控制台中按Ente

当我运行上面的代码并执行鼠标点击操作时,我得到了如下预期的输出:

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

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

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

但是,当我执行“键盘事件”时,我通过键盘的tab键访问该按钮,并通过键盘在该按钮上按Enter,它会在所有这三个按钮上返回相同的键

通过tab键逐个访问这些按钮,然后在每个按钮上按Enter键,结果如下:

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

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

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

这不是预期的产出。我想它也应该打印自己的按键一样的鼠标点击事件

我的意图是:

  • 当用户在OK1上按Enter按钮时,它应该打印('您好,OK1已按下')

  • 当用户在OK2上按Enter按钮时,它应该打印('您好,OK2已按下')

  • 当用户在OK3上按Enter按钮时,它应该打印('您好,OK3已按下')

  • 当用户单击OK1时,它应该打印('您好,OK1已按下')

  • 当用户单击OK2时,它应该打印('您好,OK2已按下')

  • 当用户单击OK3时,它应该打印('您好,OK3已按下')


  • 如何做到这一点?

    我不完全理解你的目标是什么。你想要什么样的行为

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

    下面是一些根据用户键盘输入单击按钮的代码。我想这就是你在我再读了几遍你的问题后所描述的

    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
    
    如果你想用键盘控制按钮,那么你需要做的就是收集键盘按键,然后将它们转换成你想要的任何行为

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

    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()
    

    [编辑-抱歉编辑,但我正在尝试…][/p>我终于理解了这个问题,并将此作为解决方案写了下来。它已经变成了这个项目的一个例子,因为人们确实希望ENTER键点击一个按钮,但是tkinter和Qt似乎都不是这样工作的。它们使用空格键选择按钮

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

    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()
    
    在上面的所有代码中,实现此功能的部分包含在这4行代码中。将这些代码行添加到事件循环中,然后窗口的行为将使ENTER键单击按钮。代码的其余部分是通过点击、布局等来完成的。真正实现它的是这些语句

        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')
    

    tkinter按钮似乎是使用键盘上的空格键而不是返回键激活的。PySimpleGUI只能将返回键绑定到其中一个按钮,而不是所有按钮。最后,也许值得在GitHub项目上发表一篇文章,以获得更多的想法。请检查我更新的问题,我希望你能理解我的目标是什么。您给出的示例非常适用于鼠标单击事件,并按预期返回:事件:1、事件:2和事件:3。但我想用键盘做同样的事情,而不仅仅是用鼠标。我想当用户通过Tab键查看OK3,然后按Enter键时,我希望返回键为3,但现在当我在所有这三个按钮上按Enter键时,我得到的结果是相同的。如何做到这一点?谢谢你的帮助。很高兴你问这个问题。我仍在检查Pyside2(Qt)是否在按enter键时没有选择按钮,而这些按钮处于焦点状态。我看到了这种行为,但我想验证一下。无论如何,作为答案提供的代码在Qt和tkinter上都有效。在我的例子中,在Ubuntu 19.04上,当按下enter按钮时,返回事件是-Return:36,当我添加('\r',Qt\u enter\u KEY1,Qt\u enter\u KEY2,'Return:36')在事件检查条件下,它对我有效,但没有包含“Return:36”,它不起作用。我在Raspberry Pi中运行上述程序,在Ubuntu中运行时,它在RaspberryPi中不起作用。在Raspberry Pi中,我得到的错误是:AttributeError:“Button”对象没有属性“Click”!在GitHub上回应了这些。Pi问题必须是安装问题。您有一个旧的pip安装和旧的PySimpleGUI.py文件。不管怎样,发布说明是为了帮助您确定您的版本。当有疑问时,总是检查以确保你运行的是正确的东西。为每个人节省时间
    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()