I need to write a virtual keyboard for typing texts, I'm planning to use Python and Qt (PyQt) library for this task. problem is I don't know how to simulate KeyPress not as internal Qt event, but as simulation of a real keyboard so I could work with this keyboard as like with real one - interacting with application on my computer. I can't find anything in Qt documentation about this. So is there any way to do it through PyQt/Qt, or I need to use some Python library, and which exactly?
I understand that this is a PyQt question, but at the request of the OP will give a c++ example in case it helps in finding the Python solution.
On the c++ side simulating the keyboard is done by posting keypress events to the application's event loop. These may be considered 'internal Qt events', but are the exact same interface as would be received for a physical key press. They are accomplished as follows:
QKeyEvent *event = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Enter);
QCoreApplication::postEvent (receiver, event);
Looking through the PyQt QCoreApplcation API, the postEvent function also exists, so it should be possible to do something analagous (unfortunately I can't offer an example as I'm unfamiliar with writting python scripts).
I had the same problem.
Pyautogui is very good for this and it is stupid simple.
import pyautogui
pyautogui.typewrite("the stuff")
Or if you want to actually simulate pressing a literal keypress use:
import pyautogui
pyautogui.keypressDown("the stuff")
pyautogui.keypressUp("the stuff")
Here's the documentation: https://pyautogui.readthedocs.org/en/latest/
Hope this helps.
Related
Basically I would like to write small script that would allow me to have some sort of programmable keyboard emulation. Something similar to how autohotkey on Windows is able to work.
Lets say I would like to rebind arrow keys to 'wsad' or 'hjkl' but only when CapsLook is active. I was able to detect keyboard key press with pyinput(https://pypi.python.org/pypi/pynput ) I also can send easily various keyboard events to focused window with pyautogui (https://pyautogui.readthedocs.io) But I can't figure out a way to consume events before they are received by currently focused window.
Any hints?
THIS module is one of the available tools for capturing keyboard events:
https://pypi.python.org/pypi/keyboard/
but it is still in the development and doesn't (yet) provide a global hook capable of capturing keyboard events at their very origin and forwarding them (or not) to the target application.
Another tool worth to look into is:
myboard.py at code.google.com downloads
The above script is using Python ctypes and Xlib modules which makes it possible to work directly with the system libraries written in C. It catches the keyboard events quite deep and system wide to a degree that it had crashed my OS while testing it a bit, so be warned ...
Consider also using XGrabKey and XGrabKeyboard from the X11 libX11.so system library:
import ctypes
libX11 = ctypes.CDLL('libX11.so')
XGrabKey = libX11.XGrabKey
XGrabKeyboard = libX11.XGrabKeyboard
print("XGrabKey: " , dir(XGrabKey))
print("XGrabKeyboard: ", dir(XGrabKeyboard))
I am writing long running program with simple GUI, the 99% of time I would like the program to work only as process, however sometimes I want to check the status, so is it possible to capture the keypress event in python?
For example I want to show the program window when I press Ctrl+Shift+Alt+Q, I expect to use app on Windows
Thank you
There are tutorials on how to create a key-logger with Python. They should help. But I do not know if that is the right way to go.
Also you could register shortcuts under a key combination on Windows.
You should be aware that Ctrl+Shift+Alt are handled independent of the keyboard layout and Q changes with the language.
With pywin32 you should be able to do that using Ctrl+Shift+Alt+F1 for example.
I am thinking of writing a python program that runs in the background and can inspect user's GUI events.
My requirements is very simple:
1) When user right click the mouse, it can show an option; and when this option is chosen, my program should know this event.
2) When user select a file and click some predefined key combination, my program should know this event.
What should I do? Is this a GUI program? I am also thinking that, this program maybe a daemon on the machine and can inspect the user's GUI event, but I am not sure how can I do this.
Thanks.
If you're talking about doing this stuff inside of a wxPython program, then it's all pretty simple. There's a PopupMenu widget for the first one and an AcceratorTable for the second one. If you're wanting to catch mouse and keyboard events outside of a wxPython program, then you have to go very low-level and hook into the OS itself, which means that there really isn't any good way to do it cross-platform. You'll probably want to look at ctypes and similar libraries for that sort of thing.
I've been researching this problem a bit and while I don't have a definite answer, I thought it would be good to share what I found.
First, according to the answers for this question, wxPython cannot track nor control the mouse position outside of the area controlled by the wxPython app. However, as we can see in the answers to this question, under certain circumstances it may be possible to create system-wide hot keys that wxPython can see (although we can also see that this is probably not the optimal solution).
So what will work for the OP? Well, build a cross platform application that does what the OP wants seems almost impossible so I will assume the OP is developing for MS Windows. Following the suggestions in those previous two questions, I looked into the PyWin32 API. It's a little hard to find documentation for it but this question offers some helpful links. A little more digging and I found this tutorial for system-wide hotkeys as well as the win32event.WaitForMultipleObjects and win32event.WaitForSingleObject methods which, if the OP can figure out the proper event, may be what the OP needs to catch menu clicks.
I know it's far from a complete answer but hopefully this can serve as a good jumping-off point for further research.
When you tkSimpleDialog.askinteger, the program stalls and waits for user input. What are the basics of writing my own method that would have the same effect? I want to make the same kind of dialog box, I just want to be able to request more information.
The problem that I'm having is that when I open the new window using Tk.Toplevel, the program does not wait for user input the way tkSimpleDialog.askinteger does.
First off, if you can use some other widget system like PyGtk or PyQt, you should seriously consider it. Tkinter is ancient, and the newer libraries have a lot more functionality (read: more things you don't have to reinvent). I've used PyGtk and like it a lot more than Tkinter, which I used in the old Python 1.x days.
That said, in Tkinter, you need to do this:
widget.wait_window(window)
This ties up the event loop waiting for the user to dismiss the dialog.
Reference: http://www.pythonware.com/library/tkinter/introduction/dialog-windows.htm
How can I detect, or be notified, when windows is logging out in python?
Edit:
Martin v. Löwis' answer is good, and works for a full logout but it does not work for a 'fast user switching' event like pressing win+L which is what I really need it for.
Edit: im not using a gui this is running as a service
You can detect fast user switching events using the Terminal Services API, which you can access from Python using the win32ts module from pywin32. In a GUI application, call WTSRegisterSessionNotification to receive notification messages, WTSUnRegisterSessionNotification to stop receiving notifications, and handle the WM_WTSSESSION_CHANGE message in your window procedure.
If you're writing a Windows service in Python, use the RegisterServiceCtrlHandlerEx function to detect fast user switching events. This is available in the pywin32 library as the RegisterServiceCtrlHandler function in the servicemanager module. In your handler function, look for the SERVICE_CONTROL_SESSIONCHANGE notification. See also the WM_WTSSESSION_CHANGE documentation for details of the specific notification codes.
There's some more detail in this thread from the python-win32 mailing list, which may be useful.
I hope this helps!
In a console application, you can use win32api.SetConsoleCtrlHandler and look for CTRL_LOGOFF_EVENT. In a GUI application, you need a window open and wait for the WM_QUERYENDSESSION message. How precisely that works (and if it works at all) depends on your GUI library.