wxPython: Catching key events globally
Asked Answered
G

4

8

There's something I'm trying to do with wxPython and I can't figure out how. (I'm on Windows 7 and I'm okay with a Windows-only solution.)

I want to catch key events globally. This means key-up, key-down and char events. (I'm trying to build something like AHK in Python.)

Now, I know wxPython allows global hotkeys, but that's not satisfactory, because I want to get all the events, including key up, key down and char. How can I do that?

I tried using pyHook, which almost worked except char events aren't implemented. Char events seem to be tricky and I want to know how to capture them globally. (i.e. in all apps.) I'm also okay with solutions that use other tools except wxPython. (Except not a separate GUI framework, I'm happy with using wxPython for the GUI, just tools for capturing the char events.)

Gorlovka answered 26/7, 2015 at 19:15 Comment(0)
M
5

Sorry, but you can't catch WM_CHAR events directly from a Python executable. You will need to write a native Windows DLL to hook WH_GETMESSAGE and then separately notify your Python process that a key was pressed.

As you can see here the way to catch WM_CHAR is to catch the events read by GetMessage() using the WH_GETMESSAGE hook. Sadly, any global hook for that message must be able to run in the context of any process and so has to be implemented as a DLL (as mandated by the API docs). That means you cannot do this inside your Python process. This is also covered in the Python win32 archives here.

That means you need to write a native DLL to hook the messages and then use your favourite form of IPC (e.g. Post a message to another window) to pass any interesting events to your Python process.

If you really just want Python bindings for AutoHotKey, you could use pyahk to do this for you.

Magnolia answered 31/7, 2015 at 23:24 Comment(3)
Will it work if I create a DLL and then use ctypes to load that DLL from my Python process?Gorlovka
@RamRachum yeah - that should work. The key thing is that you need to build the standalone native DLL to implement your hook. The DLL could then also have other interfaces that you can use from your Python application.Magnolia
+1 for bringing AHK to attention: because its DLL is already the DLL you need to inject in other processes.Canteen
A
0

The free and open source screen reader for Windows, NVDA, implements this functionality. Perhaps take a look at how they accomplish it?

Source: winInputHook.py

Affiliation answered 28/7, 2015 at 21:44 Comment(1)
Looks like they only listen for key-up and key-down events, not seeing char events there.Gorlovka
T
0

PyWin32 has SetWindowsHook which might work according to this thread. You might be able to use ctypes, although I haven't found any good examples as of yet.

I also found this project which looks promising:

Triggerfish answered 29/7, 2015 at 14:29 Comment(1)
Thanks Mike. I explored these two links but couldn't figure out a solution to my problem from them.Gorlovka
M
0

This may not be an ideal solution, but have tried including some pygame code?

Pygame is a module used to build games (as the name suggests), but it has some nice functions for getting keypresses.

This tutorial shows how to get keyboard input, it also has pygame do some grpahical stuff, but you don't need to have any of that to get key presses.

http://www.nerdparadise.com/tech/python/pygame/basics/part6/

And here is a list of the key codes pygame uses.

https://www.pygame.org/docs/ref/key.html

Malign answered 4/8, 2015 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.