Addition of tkinter events, catching up with the generated version

This commit is contained in:
PySimpleGUI 2021-01-30 15:10:08 -05:00
parent 108d5308dc
commit 0a6b64dc11
4 changed files with 141 additions and 59 deletions

View file

@ -4991,14 +4991,13 @@ Watch this space in the future for the more standardized variable name for this
## Binding tkiner "events"
If you wish to receive events directly from tkinter, but do it in a PySimpleGUI way, then you can do that and get those events returned to you via your standard `Window.read()` call.
If you wish to receive events directly from tkinter, but do it in a PySimpleGUI way, then you can do that and get those events returned to you via your standard `Window.read()` call.
Both the Elements and Window objects have a method called `bind`. You specify 2 parameters to this function. One is the string that is used to tell tkinter what events to bind. The other is a "key modifier" for Elements and a "key" for Windows.
Both the Elements and Window objects have a method called `bind`. You specify 2 parameters to this function. One is the string that is used to tell tkinter what events to bind. The other is a "key modifier" for Elements and a "key" for Windows.
The `key_modifier` in the `Element.bind` call is something that is added to your key. If your key is a string, then this modifier will be appended to your key and the event will be a single string.
If your element's key is not a string, then a tuple will be returned as the event
(your_key, key_modifier)
If your element's key is not a string, then a tuple will be returned as the event (your_key, key_modifier)
This will enable you to continue to use your weird, non-string keys. Just be aware that you'll be getting back a tuple instead of your key in these situations.
@ -5006,16 +5005,66 @@ The best example of when this can happen is in a Minesweeper game where each but
It'll be tricky for the user to parse these events, but it's assumed you're an advanced user if you're using this capability and are also using non-string keys.
There are 2 member variables that have also been added as shown in the documentation for the bind methods. This added variable contains the tkinter specific event information. In other words, the 'event' that tkinter normally sends back when a callback happens.
An Element member variable `user_bind_event` will contain information that tkinter passed back along with the event. It's not required for most operations and none of the demos currently use this variable, but it's there just in case. The contents of the variable are tkinter specific and set by tkinter so you'll be digging into the tkinter docs if you're using an obscure binding of some kind.
Here is sample code that shows how to make these calls.
tkinter events must be in between angle brackets
Three events are being bound.
```python
window['-KEY-'].bind('<TKINTER EVENT>', 'STRING TO APPEND')
```
Events can also be binded to the window
```python
window.bind('<TKINTER EVENT>', 'STRING TO APPEND')
```
List of tkinter events:
| Event | Description |
| :------------------------------- | ------------------------------------------------------------ |
| Button-1 / ButtonPress-1 / 1 | Left button is pressed over an element. 1 corresponds to the left button, 2 to the middle button, 3 to the right button. <br>Buttons can go up to 5 |
| ButtonRelease-1 | Left button is released over an element. |
| Double-Button-1 | An element was double clicked. The 'Double' modifier was used. See below for more modifiers. |
| B1-Motion | Left button is held and moved around over an element. |
| Motion | Mouse pointer is moved over an element |
| Enter | Mouse pointer entered the element |
| Leave | Mouse pointer left the element |
| Key / KeyPress<br>Keypress-a / a | A key was pressed. [Keysyms](https://www.tcl.tk/man/tcl8.6/TkCmd/keysyms.htm) can be used to bind specific key/s. <br>When using keysyms, 'Key' or 'KeyPress' can be omitted. <br> |
| KeyReleased | A key was released. |
| FocusIn | Keyboard has focused on element. |
| FocusOut | Keyboard switched focus from element. |
| Visibility | Some part of the element is seen on screen |
Modifier keys can be put in front of events.
| Windows | MacOS |
| ------- | ------- |
| Control | Command |
| Alt | Option |
| Shift |<==|
| Double | <== |
| Triple | <== |
| Quadruple | <== |
The following will bind Ctrl+z to the window:
```python
window.bind('<Control-z>', 'STRING TO APPEND')
```
To unbind an event from an element, use the `unbind` method.
```python
window['-KEY-'].unbind('TKINTER EVENT')
```
Here is sample code that shows these bindings in action.
Four main things are occurring.
1. Any button clicks in the window will return an event "Window Click" from window.read()
2. Right clicking the "Go" buttons will return an event "Go+RIGHT CLICK+" from window.read()
3. When the Input Element receives focus, an event "-IN-+FOCUS+" will be returned from window.read()
2. Right clicking the "Go" buttons will return an event "Go +RIGHT CLICK+" from window.read()
3. When the second Input Element receives focus, an event "-IN2- +FOCUS+" will be returned from window.read()
4. If the "Unbind " button is pressed, the right click binding of the "Go" button will be unbinded.
```python
import PySimpleGUI as sg
@ -5023,27 +5072,29 @@ import PySimpleGUI as sg
sg.theme('Dark Green 2')
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-'), sg.Text(size=(15,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')]
[sg.Input(key='-IN1-')],
[sg.Input(key='-IN2-')],
[sg.Button('Go'), sg.Button('Unbind'),sg.Button('Exit')]
]
window = sg.Window('Window Title', layout, finalize=True)
window['-IN-'].bind("<FocusIn>", '+FOCUS+')
window.bind("<Button-1>", 'Window Click')
window['Go'].bind("<Button-3>", '+RIGHT CLICK+')
window['Go'].bind("<Button-3>", ' +RIGHT CLICK+')
window['-IN2-'].bind("<FocusIn>", ' +FOCUS+')
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (sg.WIN_CLOSED, 'Exit'):
break
if event == 'Unbind':
window['Go'].unbind('<Button-3>')
window.close(); del window
window.close()
```
There is no way to "unbind" and event at this time. (sorry, didn't think of it before releasing)
---
[Tkinter bindings documentation](https://tcl.tk/man/tcl8.6/TkCmd/bind.htm#M18)
------------------