2
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

When I run the above code and perform mouse click operation, I get the output as following that is as expected,

clicking on OK1 Button print in the console as: 1

clicking on OK2 Button print in the console as: 2

clicking on OK3 Button print in the console as: 3

But, when I perform keyboard event means, I visit on the button through tab key of keyboard and press Enter on that Button via keyboard it return the same key on all these three button,

Visit on these button one by one via tab key and then press Enter on each I get the result as,

Press Enter on OK1 Button print in the console as: 1

Press Enter on OK2 Button print in the console as: 1

Press Enter on OK3 Button print in the console as: 1

That is not expected output. What I want it should also print their own key same as mouse click event.

What is my intention:

  1. When user press Enter button over OK1, It should print('Hello, OK1 pressed.')

  2. When user press Enter button over OK2, It should print('Hello, OK2 pressed.')

  3. When user press Enter button over OK3, It should print('Hello, OK3 pressed.')

  4. When user click on OK1, It should print('Hello, OK1 pressed.')

  5. When user click on OK2, It should print('Hello, OK2 pressed.')

  6. When user click on OK3, It should print('Hello, OK3 pressed.')

How to achieve this?

2017kamb
  • 192
  • 3
  • 8
  • 27
  • Glad you asked this problem. I'm still checking to see if Pyside2 (Qt) doesn't select buttons when you press enter with them focused. I saw that behavior, but want to verify it. Regardless the code provided as an answer works on both Qt and tkinter. – Mike from PSG Jun 23 '19 at 17:12

2 Answers2

2

I finally understood the question and wrote this as a solution. It's been turned into a Demo Program for the project because people do expect the ENTER key to click a button and yet tkinter and Qt both seem to not work this way. They select buttons using the spacebar.

This source code works for both PySimpleGUI and PySimpleGUIQt. Just use the correct import statement at the top.

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

Out of all of the code above, the part that implements this feature is contained in these 4 lines of code. Add these lines of code to your event loop and then your window will behave such that the ENTER key will click a button. The rest of the code does things with the clicks, is the layout, etc. It's really these statements that implement it.

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()
Mike from PSG
  • 5,312
  • 21
  • 39
  • in my case on Ubuntu 19.04, when enter button pressed it's returning event is - Return:36 When I add ('\r', QT_ENTER_KEY1, QT_ENTER_KEY2, 'Return:36 ') in the event check condition it's working for me but without included 'Return:36 ' it's not working. – 2017kamb Jun 24 '19 at 02:48
  • I run the above program in Raspberry Pi it's not working in RaspberryPi while working in Ubuntu. In Raspberry Pi I am getting the error as: AttributeError: 'Button' object has no attribute 'Click'! – 2017kamb Jun 24 '19 at 03:04
  • Responded to these on GitHub. The Pi problem must be an install problem. You've got an old pip install, and old PySimpleGUI.py file. Regardless, instructions were posted to help you determine your version. When in doubt, always check to make sure you're running the right stuff. Saves time for everyone – Mike from PSG Jun 24 '19 at 14:59
1

I don't fully understand what your goal is. What behavior do you want?

When a button has the focus, pressing the return key doesn't seem to trigger buttons by default. The space bar will though.

Here is some code that will click a button based on a user's keyboard input. I THINK that was what you described after I re-read your question a few times.

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

If you want to control the buttons using the keyboard, then what you'll have to do is collect the keyboard key presses and then convert those into whatever behavior you want.

Pressing ENTER when a button has focus (is highlighted) does NOT generate a button click, a SPACE BAR does. You can see this demonstrated in this tkinter program:

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

[EDIT - sorry about the edits but I'm experimenting... ]

Mike from PSG
  • 5,312
  • 21
  • 39
  • It also appears that tkinter buttons are activated using the SPACE BAR on the keyboard rather than return key. PySimpleGUI is only able to bind the return key to one of the buttons, not all of them. Finally, it may be worth opening an Issue on the project GitHub to get more ideas – Mike from PSG Jun 20 '19 at 19:33
  • MikeyB, Please check my updated question I hope you will understand what is my Goal. What example you give is working perfectly for Mouse click event and returning as expected: event: _1_, event: _2_ and event: _3_ respectively. But the same thing I want to do with Keyboard not just only with Mouse. I want when user go over the OK3 via Tab key and then Press Enter key I expect in return key as 3 but right now when I Press Enter over all these three buttons I get the same in the result. How to achieve this? Thanks MikeyB for your help. – 2017kamb Jun 21 '19 at 02:34