wxPython: Catching key events globally - python

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

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.

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

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:
https://pypi.python.org/pypi/PyUserInput

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

Related

how to use TCL packages/code in python pytest program

I have been using TCL code, but i want use my all TCL packages/code in python pytest. Is it possible? If yes please let me know the process to accomplish this task.
Thanks
Malli
If you have python and need to run Tcl code, the easy way is to use Python's tkinter module, which is a wrapper around Tcl/Tk.
See the basic examples at https://wiki.python.org/moin/How%20Tkinter%20can%20exploit%20Tcl/Tk%20extensions
import Tkinter
root = Tkinter.Tk()
root.tk.eval('source {foo.tcl}')
root.tk.eval('foo_bar')
there are some parts that can be a little tricky, like moving data between those two, but if you mostly just call a few procedures, it works quite well.
Depending on how flow control works in your python scripts, you might not be able to use event loop related code (fileevent, after, etc.) without some changes like calling tkinters mainloop.
You can find some more exotic options in the answers to Know any creative ways to interface Python with Tcl?

Python. Get flashing/blinking windows of a chat

I want to focus a windows when it is blinking/flashing. The more common case is when someone sends some text by a chat software (for example MSN). In this case the windows bar is going to start blink in the start bar. I don't know if i am explaining myself. I want to get the HWND of the blinking windows. If more info is necesary to understand it, I will try to explain me better.
I have already searched info about this case but I find nothing. Maybe it can be resolver using "win32gui" library.
Thank you for your help!!!
First, most programs flash their windows by calling FlashWindowEx (or some higher-level function that wraps it). But there are a few apps—mostly from Microsoft—that do some custom stuff instead that looks like window-flashing to the end user, but may not look the same under the covers. Hopefully, you don't care about any such custom apps.
Anyway, the easiest way to capture that information is to install a shell hook with SetWindowsHookEx or RegisterShellHookWindow. (You could instead explicitly inject code in front of user32.dll… but you don't want to try that from Python.) When you do this, Windows will treat your window as if it were part of Explorer (the "shell") and send it special messages about what other programs are doing—in particular, WM_SHELLHOOKMESSAGE.
As forivall pointed out, this might be easier to do from AutoHotkey—this answer in the forums shows how to do it. It might also be easier to do from VB, or even C++. Yes, those languages are generally more difficult than Python, but the actual logic in your code is pretty trivial, and the only hard part is getting the shell hook messages, and that part will be easier in those languages. Another alternative is to use IronPython and do it via .NET.
But you asked if it's possible to do it from Python, and… yes, it is. I believe the relevant functions are not wrapped up by win32gui, so you'll have to use ctypes to do it from Python. See this SO question for a possible example, and look at some of the Related questions on the side and the ctypes docs for other examples of using ctypes to call different functions out of user.dll.
If you want to set a windows hook, the key function will look something like this (see ShellProc for details):
HSHELL_REDRAW=6
WM_SHELL=10
def my_callback(nCode, wParam, lParam):
if nCode == HSHELL_REDRAW and lParam:
got_flashing_window_with_hwnd(wParam)
hook = user32.SetWindowsHookEx(WM_SHELL, my_callback, None, 0)
But you need to set the types and push the callback through ctypes.
If you already have a window that you're managing from Python, it's probably easier to set yourself up as a shell hook window instead:
user32.RegisterShellHookWindow(my_hwnd)
Then, in your window proc:
WM_SHELLHOOKMESSAGE = None
def wndproc(hWnd, uMsg, lParam, wParam):
if WM_SHELLHOOKMESSAGE is None:
WM_SHELLHOOKMESSAGE = user32.RegisterWindowMessage('SHELLHOOK')
if uMsg == WM_SHELLHOOKMESSAGE and wParam == HSHELL_FLASH:
got_flashing_window_with_hwnd(lParam)
I'm not sure whether you need elevated privileges for either of these, but I would suspect you do.

How to globally overload assert so I don't have to change lib code in my PyQT app?

My app use QT for the gui layer, and many other lib I made.
One of this other lib is quite complex (it's a type system) and full of asserts to make it as solid as possible.
But when an assert is triggered in this lib, the Qt mainloop simply continue.
I have a qt_debug() that works well (with pyqtRemoveInputHook) for the Qt part but nothing for the rest of python libraries.
And, obviously I would avoid to change code in the library as it should useable without Qt.
The best solution would be an assert hook, but despite googling around I didn't any obvious way to do it. Any idea ?
Using assert is the wrong way. For one thing, if Python is run with -O (or -OO) asserts are turned off; for another, the error message is not very helpful. That library needs to be redesigned to properly use exceptions.
As far as using the library as it stands: what do you want to have happen? Should your app quit? If so, you could create your own AssertionError class, replace the one in __builtins__ with yours, and have it do whatever you want in its __init__. Note that you are completely on your own if you do this.

What are the parameters for .GetWindow function in python?

I'm kinda new to programming, and I wanna write a simple program that needs to OCR a particular window. Currently, I'm using (w.GetForegroundWindow()), but that gets me the current window which would always be the Python shell, since that is the one that is active when I run it, even if it is for a split second only.
After searching around for a bit, I found the .Getwindows function, but not much of it on Python. What does it do, and what are the parameters? Will i be able to target a particular process (=window) with it? If not, what can I use then?
This is using the pywin32 module on Python 2.7 in Windows
I'm in Windows, Python 2.7 . The GetWindows function comes with the module pywin32, if im not wrong
The usual way is to call EnumWindows with a callback and then get information about each hwnd - for example name, title or window class. Check that against what you are looking for and save the matched hwnd. After EnumWindows returns, check that you found a valid hwnd and use that for your program.
It's not pleasant - there's not much support for this kind of thing in windows. I've heard that using accessibility features is better but I have no experience using that.

X11 - How to raise another application's window using Python

I'd like to be able to raise another application's Window using Python.
I did see this, which I suppose I could try:
X11: raise an existing window via command line?
However, I'd prefer to do it in Python if at all possible.
To activate another window, the right thing to do on the Xlib protocol layer is to send a _NET_ACTIVE_WINDOW message as described in the EWMH spec
http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html
This could be done with python-xlib (presumably) or with gdk_window_focus() on a foreign GdkWindow using GDK through pygtk
_NET_ACTIVE_WINDOW is superior to XRaiseWindow() and has been in all the important WMs for many many years.
You should avoid XSetInputFocus() which will cause problems (especially if you get the timestamp wrong). The issue is that the WM can't intercept the SetInputFocus() so it causes weird race conditions and UI inconsistencies.
Really only _NET_ACTIVE_WINDOW works properly, which is why it was invented, because the previous hacks were bad.
There is a library called libwnck that will let you activate windows (among other things) but unfortunately it adds quite a lot of overhead because it always tracks all open windows from any app, even if you don't need to do that. However if you want to track windows from other apps anyway, then libwnck has a function to activate those windows that does the right thing and would be a good choice.
The strictly correct approach is to check for EWMH _NET_ACTIVE_WINDOW support (EWMH documents how to do this) and fall back to XRaiseWindow if the WM doesn't have _NET_ACTIVE_WINDOW. However, since any WM that's been actively worked on in the last many years has EWMH, lots of people are lazy about the fallback for legacy WMs.
You need to use python-xlib and call .circulate(Xlib.X.RaiseLowest) on the window object (which can be identified in many, many different ways -- can't guess which one is appropriate for you from the zero amount of info about it in your Q;-). For a great example of using python-xlib, check out the tinywm window manager -- after the C version, the author gives a Python version that takes about 30 non-blank, non-comment lines (for a usable, if tiny, window manager...!-).
You can have a look at the python ewmh package. Documentation contains examples, but here is how you can achieve what you want:
from ewmh import EWMH
import random
ewmh = EWMH()
# get every displayed windows
wins = ewmh.getClientList()
# let's active one window randomly
ewmh.setActiveWindow(random.choice(wins))
# flush requests - that's actually do the real job
ewmh.display.flush()

Categories