On 10/26/2016 11:00 AM, BartC wrote:
On 26/10/2016 13:33, Marko Rauhamaa wrote:

Say you want to implement a simple, character-based shooting game where
the two guns are operated by the [Shift] keys. Unfortunately, the Unix
terminal API doesn't make that possible. You need to get the keyboard
events from some other API. In practice, your only choice is X11/Wayland
(on Linux).

This is trivial with tkinter and practical if one uses a tk Text. See below for the problem with using tkinter and console.

That sort of thing is possible to build by directly calling OS-specific
functions in a similar manner to Steven D'Aprano's way of implementing
getch().

But it's something everyone would have to code themselves.

(I just tried it using my 'getchx' function where it ought to have
worked. Unfortunately MS' interface to key events doesn't seem to
distinguish between left and right shift keys. But it was doable with
left/right ctrl keys.

That's a blocking function it it means having to wait for input. But a
version that just tests for status shouldn't be hard.)

In my answer to Marko, I posted code which worked as far as I tested it. Here I add a line to make the tk window invisible. I also replace rshift with a function that gets input from the user.

import tkinter as tk
root = tk.Tk()
root.withdraw()  # make tk window invisible
def lshift(event): print('shift-l')
def rshift(event):
    s = input('type something: ')
    print('received', s)
root.bind('<Key-Shift_L>', lshift)
root.bind('<Key-Shift_R>', rshift)
root.mainloop()

For input, the problem is input focus. When the tk window is created, the OS gives it input focus. Leaving itself invisible does not negate that. But to respond to input in a different window, the user must, as least on Windows, click on the input window. I do not know of any way for tkinter to give focus back to a parent window that is either not a tk window or is not in the same process.

After input is received, or indeed after focus is moved by clicking on any other window, there is the problem of moving focus back to the tk window. If it is invisible, it cannot be clicked on. And without a binding to stop mainloop when the focus leaves, there is no way to stop it without killing the console, or with IDLE, restarting Shell.

I conclude that if one uses tkinter to captures and process some keyboard events, one should do so for all. Python's input should be replaced by a tkinter simulation. I can think of a couple of ways this might be implemented.

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to