A module for cross-platform control of the mouse and keyboard in python that is simple to install and use.

Related tags

Hardware PyUserInput
Overview

PyUserInput

PyUserInput is a group project so we've moved the project over to a group organization: https://github.com/PyUserInput/PyUserInput . That is now the active development repository and I'll be phasing this one out, so please go there for the latest code and to post new issues. This should be corrected on PyPI in the next version update of PyUserInput.

A module for cross-platform control of the mouse and keyboard in python that is simple to use.

Mouse control should work on Windows, Mac, and X11 (most Linux systems). Scrolling is implemented, but users should be aware that variations may exist between platforms and applications.

Keyboard control works on X11(linux) and Windows systems. Mac control is a work in progress.

Dependencies

Depending on your platform, you will need the following python modules for PyUserInput to function:

  • Linux - Xlib
  • Mac - Quartz, AppKit
  • Windows - pywin32, pyHook

How to get started

After installing PyUserInput, you should have pymouse and pykeyboard modules in your python path. Let's make a mouse and keyboard object:

from pymouse import PyMouse
from pykeyboard import PyKeyboard

m = PyMouse()
k = PyKeyboard()

Here's an example of clicking the center of the screen and typing "Hello, World!":

x_dim, y_dim = m.screen_size()
m.click(x_dim/2, y_dim/2, 1)
k.type_string('Hello, World!')

PyKeyboard allows for a range of ways for sending keystrokes:

# pressing a key
k.press_key('H')
# which you then follow with a release of the key
k.release_key('H')
# or you can 'tap' a key which does both
k.tap_key('e')
# note that that tap_key does support a way of repeating keystrokes with a interval time between each
k.tap_key('l',n=2,interval=5) 
# and you can send a string if needed too
k.type_string('o World!')

and it supports a wide range of special keys:

#Create an Alt+Tab combo
k.press_key(k.alt_key)
k.tap_key(k.tab_key)
k.release_key(k.alt_key)

k.tap_key(k.function_keys[5])  # Tap F5
k.tap_key(k.numpad_keys['Home'])  # Tap 'Home' on the numpad
k.tap_key(k.numpad_keys[5], n=3)  # Tap 5 on the numpad, thrice

Note you can also send multiple keystrokes together (e.g. when accessing a keyboard shortcut) using the press_keys method:

# Mac example
k.press_keys(['Command','shift','3'])
# Windows example
k.press_keys([k.windows_l_key,'d'])

Consistency between platforms is a big challenge; Please look at the source for the operating system that you are using to help understand the format of the keys that you would need to send. For example:

# Windows
k.tap_key(k.alt_key)
# Mac
k.tap_key('Alternate')

I'd like to make a special note about using PyMouseEvent and PyKeyboardEvent. These objects are a framework for listening for mouse and keyboard input; they don't do anything besides listen until you subclass them. I'm still formalizing PyKeyboardEvent, so here's an example of subclassing PyMouseEvent:

from pymouse import PyMouseEvent

def fibo():
    a = 0
    yield a
    b = 1
    yield b
    while True:
        a, b = b, a+b
        yield b

class Clickonacci(PyMouseEvent):
    def __init__(self):
        PyMouseEvent.__init__(self)
        self.fibo = fibo()

    def click(self, x, y, button, press):
        '''Print Fibonacci numbers when the left click is pressed.'''
        if button == 1:
            if press:
                print(self.fibo.next())
        else:  # Exit if any other mouse button used
            self.stop()

C = Clickonacci()
C.run()

Intended Functionality of Capturing in PyUserInput

For PyMouseEvent classes, the variables "capture" and "capture_move" may be passed during instantiation. If capture=True is passed, the intended result is that all mouse button input will go to your program and nowhere else. The same is true for capture_move=True except it deals with mouse pointer motion instead of the buttons. Both may be set simultaneously, and serve to prevent events from propagating further. If you notice any bugs with this behavior, please bring it to our attention.

A Short Todo List

These are a few things I am considering for future development in PyUserInput:

  • Ensuring that PyMouse capturing works for all platforms
  • Implement PyKeyboard capturing (add PyKeyboardEvent for Mac as well)
  • PyMouse dynamic delta scrolling (available in Mac and Windows, hard to standardize)
  • Make friends with more Mac developers, testing help is needed...

Many thanks to

Pepijn de Vos - For making PyMouse and allowing me to modify and distribute it along with PyKeyboard.

Jack Grigg - For contributions to cross-platform scrolling in PyMouse.

Comments
  • Using type_string, less than sign is replaced by greater than sign

    Using type_string, less than sign is replaced by greater than sign

    k = PyKeyboard()

    k.type_string('<')

    Expected output: < Actual output: >

    I noticed this first because I was trying to scan in an xml file and use PyKeyboard to put it into a form online. Unfortunately it turned every single < into >

    Is there already a fix for this?

    opened by reparadocs 10
  • ImportError: No module named Quartz - Mac OSX

    ImportError: No module named Quartz - Mac OSX

    I must be a moron but by quartz does that mean http://xquartz.macosforge.org/landing/ Because I installed it and still end up with this error: ImportError: No module named Quartz There is no pip module named quartz, so if you guys could help me figure this out it would be much appreciated.

    opened by Joebob12 10
  • Fix for extremely slow pyobjc import

    Fix for extremely slow pyobjc import

    I've been seeing the very long import time bug on Mac documented in Issue #5.

    Specifically,

    import pymouse
    

    hangs for in excess of 15 seconds on Mac OS X 10.9.3/Python 2.7.5 with pyobjc v2.5.1.

    I've traced the issue back to the pyobjc project, which has a bug discussion containing this message:

    If you are only using framework wrappers: make sure you do not use "from Foundation import ", use "import Foundation" or "from Foundation import NSObject" instead. Someone recently noticed that the "from ... import " form is currently much slower than it used to be, due to the way the PyObjC lazy loader is implemented. I'm working on a fix for that, but even with the fix explicit imports will be better because they perform less form (because explicit imports don't have to resolve the symbols you don't use).

    https://bitbucket.org/ronaldoussoren/pyobjc/issue/2/faster-metadata-support#comment-5204985

    The pymouse/mac.py and pykeyboard/mac.py modules use exactly this from Quartz import * import style.

    Changing this to import Quartz and fixing the references to Quartz objects solves the import time issues.

    I've also added a unit test that checks the import times for pymouse and pykeyboard. Since this is an import bug, only the first of these tests can ever fail (since subsequent from Quartz import * calls won't reimport Quartz). Even so, the test does catch the bug described above.

    Reproducing the bug

    Environment

    • Mac OS X 10.9.3 Mavericks
    • 1.6 GHz Core 2 Duo, 8 GB RAM, SSD
    • Python 2.7.5
    • pyobjc-core 2.5.1
    • PyUserInput 0.1.9 (both from PyPi and git bbf8c41)

    Steps

    1. import the pymouse module.

    You should observe at least a 15 second hang with no output or other response. For example:

    print "About to import pymouse"
    import pymouse
    print "This will print at least 15 seconds later"
    

    Results

    Before the patch, at version 0.1.9/bbf8c41:

    $ time python -m pymouse
    ...
    
    real        0m14.961s
    user        0m14.275s
    sys 0m0.164s
    

    After changing to import Quartz:

    $ time python -m pymouse
    ...
    
    real        0m0.495s
    user        0m0.381s
    sys 0m0.092s
    

    Caveats/risks

    Three unit tests fail for me when I run nosetests both before and after this PR's commits, so I don't have a clean baseline to evaluate whether I've broken anything, for example by missing adding the Quartz.* reference to any Quartz package objects in pymouse/mac.py or pykeyboard/mac.py.

    I can successfully run the examples/filetranscriber.py demo and the tests/basic.py program.

    opened by casebeer 9
  • Corrected Xlib implementation

    Corrected Xlib implementation

    This pull request includes a few fixes from @jnv and @Talv and adds the following:

    • Errors from Xlib are actually handled, and not just lost.
    • All printable characters are supported without having to resort to symbol names, using the table found here.
    opened by moses-palmer 6
  • PyMouse & Mac

    PyMouse & Mac

    Readme.md Line 37

    x_dim, y_dim = m.screen(size)

    should be

    x_dim, y_dim = m.screen_size()

    But any reason why this takes a long long time to run on the Mac? (like 30 odd seconds)

    opened by willwade 6
  • Qwartz - Quartz

    Qwartz - Quartz

    If I'm not mistaken the references to "Qwartz" should be Quartz right?

    The python setup.py install will fail as no package Qwartz exists..

    Thanks! :)

    opened by willwade 6
  • Capture mouse and keyboard events at the same time

    Capture mouse and keyboard events at the same time

    Hi,

    It would be nice to be able to capture mouse and keyboard events at the same time. Currently this doesn't seem to be possible because each event class starts an endless loop.

    Best Regards, Jonas

    opened by JonasPf 5
  • Bug fixes

    Bug fixes

    Fixed "ValueError: depythonifying 'int', got 'NoneType'" when passing y_move/x_move/z_move None to CGEventCreateScrollWheelEvent.

    Fixed typo in scroll_event calls (y_movement should be y_move, x_movement should be x_move, z_movement should be z_move).

    opened by jhosmer 4
  • examples not working on mac..

    examples not working on mac..

    I may be being stupid..

    from pymouse import PyMouse
    from pykeyboard import PyKeyboard
    
    m = PyMouse()
    k = PyKeyboard()
    
    dir(k)  #Use dir() on a PyKeyboard instance
    k.numpad_keys.viewkeys()
    k.function_keys
    

    gives: AttributeError: 'PyKeyboard' object has no attribute 'numpad_keys' (and if I comment the numpad line) AttributeError: 'PyKeyboard' object has no attribute 'function_keys'

    (running latest zip on mac)

    The initial readme could do with a one liner on how to send a normal key as well as a function key..

    opened by willwade 4
  • mac import problem

    mac import problem

    When I attempt to run the fibonacci example code, I get this error:

    Traceback (most recent call last): File "pymouse.py", line 1, in from pymouse import PyMouseEvent File "/Users/mfenner/Desktop/pymouse.py", line 1, in from pymouse import PyMouseEvent ImportError: cannot import name PyMouseEvent

    when I try to import pymouse, I get the same error. Any idea what's wrong with my install?

    EDIT: I checked and the modules are all in my site packages and python does recognize them, the import just fails

    opened by mfenner0422 4
  • Allow reusing PyMouseEvent instance multiple times.

    Allow reusing PyMouseEvent instance multiple times.

    Currently if you run an instance of PyMouseEvent after it is stopped once, it will immediately stop itself because self.state is set to False.

    I wanted to reuse some of my PyMouseEvent classes so I simply added self.state=True in self.run().

    I see no reason for this to not be a default behavior.

    Here is a simple usecase/code for this.

    from pymouse import PyMouseEvent
    
    class OnetimeClickListener(PyMouseEvent):
        """ Waits for a user to click and save the position """
        def run(self):
            self.state = True
            super(OnetimeClickListener, self).run()
        def click(self, x, y, button, press):
            if not press:
                # Ignore Mouse Up events
                return
            self.position = (x, y)
            self.stop()
    
    # Example code
    
    listener = OnetimeClickListener()
    
    print("Please click to set position1")
    listener.run()
    pos1 = listener.position
    
    print("Please click to set position2")
    listener.run()
    pos2 = listener.position
    
    print("Please click to set position3")
    listener.run()
    pos3 = listener.position
    
    
    opened by qria 3
  • Issue with PyUserInput

    Issue with PyUserInput

    I am attempting to use this to start up a firmware, save results to a file, then parse the file, although the way this works is the firmware always starts up after the script is completed, this leaves the parser unable to open a file that is not created yet, so the parser is always working on the previously created file. I was wondering if there is anyone I may communicate this issue with or get some guidance in this case.

    opened by aebanuelos 0
  • How do I specify that I want to click where the mouse pointer is, and not move the mouse anwhere?

    How do I specify that I want to click where the mouse pointer is, and not move the mouse anwhere?

    Currently this script moves the mouse to the top left corner of my screen.

    I am trying to write a script that continuously sends left mouse clicks at the current mouse cursor position while the left mouse button is held down and stops clicking on release of the left mouse button.

    from pynput.mouse import Listener as MouseListener
    from pynput.keyboard import Listener as KeyboardListener
    
    
    def on_press(key):
        print("Key pressed: {0}".format(key))
    
    def on_release(key):
        print("Key released: {0}".format(key))
    
    def on_move(x, y):
        print("Mouse moved to ({0}, {1})".format(x, y))
    from pymouse import PyMouse
    import time
    sleep_time = 2
    def on_click(x, y, button, pressed):
        if pressed:
            m = PyMouse()
            print('Mouse clicked at ({0}, {0}) with {2}'.format(x, y, button))
            m.click(0, 0, 1)
            time.sleep(sleep_time)
            m.click(0, 0, 1)
    
    
    
            print('Mouse clicked at ({0}, {0}) with {2}'.format(x, y, button))
        else:
            print('Mouse released at ({0}, {0}) with {2}'.format(x, y, button))
    
    def on_scroll(x, y, dx, dy):
        print('Mouse scrolled at ({0}, {1})({2}, {3})'.format(x, y, dx, dy))
    
    
    # Setup the listener threads
    keyboard_listener = KeyboardListener(on_press=on_press, on_release=on_release)
    mouse_listener = MouseListener(on_move=on_move, on_click=on_click, on_scroll=on_scroll)
    
    # Start the threads and join them so the script doesn't end early
    keyboard_listener.start()
    mouse_listener.start()
    keyboard_listener.join()
    mouse_listener.join()
    
    

    I also plan to try while pressed: instead of if pressed:

    opened by NSC9 0
  • Line 80 appears to have a misalignment

    Line 80 appears to have a misalignment

    https://github.com/SavinaRoja/PyUserInput/blob/master/pymouse/x11.py

    def button_code_to_scroll_direction(button):
        # scrollup=4, scrolldown=5, scrollleft=6, scrollright=7
        return {
            4: (1, 0),
            5: (-1, 0),
            6: (0, 1),
            7: (0, -1),
        }[button]
    

    is this better? only asking cause the highlighting was off when i was looking at this code

    def button_code_to_scroll_direction(button):
        # scrollup=4, scrolldown=5, scrollleft=6, scrollright=7
        return {
            4: (1, 0),
            5: (-1, 0),
            6: (0, 1),
            7: (0, -1),
            }[button]
    
    opened by NSC9 0
  • 'PyKeyboard' object has no attribute 'enter_key'

    'PyKeyboard' object has no attribute 'enter_key'

    #!/usr/bin/python

    -- coding: UTF-8 --

    from pykeyboard.mac import PyKeyboard from pymouse import PyMouse import time

    m = PyMouse() k =PyKeyboard() print(m.position()) time.sleep(1) m.click(766,1375) time.sleep(0.1) m.click(1138,39) time.sleep(0.1) k.type_string("www.google.com") k.tap_key(k.enter_key)

    mac.py Traceback (most recent call last): File "/Users/yzw/PycharmProjects/pachong/mouse.py", line 16, in k.tap_key(k.enter_key) AttributeError: 'PyKeyboard' object has no attribute 'enter_key'

    opened by yzw1993 0
  • ```ImportError: cannot import name 'PyKeyboard' from 'pykeyboard' ```

    ```ImportError: cannot import name 'PyKeyboard' from 'pykeyboard' ```

    I'm getting this error, ImportError: cannot import name 'PyKeyboard' from 'pykeyboard', but I checked and I do have pykeyboard installed. Any advice on how to fix?

    opened by rhearamaiya 2
Owner
Paul Barton
Paul Barton
Brogrammer-keyboard - FIrmware for the Brogrammer Keyboard v1.0

Brogrammer Keyboard Firmware The package contains the firmware that runs on the Brogrammer Keyboard v1.0 See https://imgur.com/a/oY5QZ14 This keyboard

Devin Hartleben 1 Apr 21, 2022
This is a Virtual Keyboard which is simple yet effective to use.

Virtual-Keyboard This is a Virtual KeyBoard which can track finger movements and lets you type anywhere ranging from notepad to even web browsers. It

Jehan Patel 3 Oct 1, 2021
Hook and simulate global mouse events in pure Python

mouse Take full control of your mouse with this small Python library. Hook global events, register hotkeys, simulate mouse movement and clicks, and mu

BoppreH 722 Dec 31, 2022
A python script for macOS to enable scrolling with the 3M ergonomic mouse EM500GPS in any application.

A python script for macOS to enable scrolling with the 3M ergonomic mouse EM500GPS in any application.

null 3 Feb 19, 2022
PyLog - Simple keylogger that uses pynput to listen to keyboard input.

Simple keylogger that uses pynput to listen to keyboard input. Outputs to a text file and the terminal. Press the escape key to stop.

null 1 Dec 29, 2021
The ABR Control library is a python package for the control and path planning of robotic arms in real or simulated environments.

The ABR Control library is a python package for the control and path planning of robotic arms in real or simulated environments. ABR Control provides API's for the Mujoco, CoppeliaSim (formerly known as VREP), and Pygame simulation environments, and arm configuration files for one, two, and three-joint models, as well as the UR5 and Kinova Jaco 2 arms. Users can also easily extend the package to run with custom arm configurations. ABR Control auto-generates efficient C code for generating the control signals, or uses Mujoco's internal functions to carry out the calculations.

Applied Brain Research 277 Jan 5, 2023
Python implementation of ZMP Preview Control approach for biped robot control.

ZMP Preview Control This is the Python implementation of ZMP Preview Control app

Chaobin 24 Dec 19, 2022
This application works with serial communication. Use a simple gui to send and receive serial data from arduino and control leds and motor direction

This application works with serial communication. Use a simple gui to send and receive serial data from arduino and control leds and motor direction

ThyagoKZKR 2 Jul 18, 2022
Python module for the qwiic serial control motor driver

Qwiic_SCMD_Py Python module for the qwiic motor driver This python package is a port of the existing SparkFun Serial Controlled Motor Driver Arduino L

SparkFun Electronics 6 Dec 6, 2022
Hook and simulate global keyboard events on Windows and Linux.

keyboard Take full control of your keyboard with this small Python library. Hook global events, register hotkeys, simulate key presses and much more.

BoppreH 3.2k Dec 30, 2022
I made this so I can control my Tapo L510 light bulb and Govee H6159 light strip using the PyP100 module and the Govee public API

TAPO-And-Govee-Controller I made this so I can control my Tapo L510 light bulb and Govee H6159 light strip using the PyP100 module and the Govee publi

James Westhead 0 Nov 23, 2021
KIRI - Keyboard Interception, Remapping, and Injection using Raspberry Pi as an HID Proxy.

KIRI - Keyboard Interception, Remapping and Injection using Raspberry Pi as a HID Proxy. Near limitless abilities for a keyboard warrior. Features Sim

Viggo Falster 10 Dec 23, 2022
Make your MacOS keyboard brightness fade in and out

Make your MacOS keyboard brightness fade in and out. (It's working depends on the Kbrightness file, which only works for <2015 Macs, so this will only work on <2015 Macs.)

null 1 Dec 16, 2021
A custom mechanical keyboard inspired by the CFTKB Mysterium

Env-KB A custom mechanical keyboard inspired by the CFTKB Mysterium Build Guide and Parts List What is to do? Right now for the first 5 PCBs I have, i

EnviousData 203 Jan 4, 2023
Lenovo Legion 5 Pro 2021 Linux RGB Keyboard Light Controller

Lenovo Legion 5 Pro 2021 Linux RGB Keyboard Light Controller This util allows to drive RGB keyboard light on Lenovo Legion 5 Pro 2021 Laptop Requireme

null 36 Dec 16, 2022
Keystroke logging, often referred to as keylogging or keyboard capturing

Keystroke logging, often referred to as keylogging or keyboard capturing, is the action of recording the keys struck on a keyboard, typically covertly, so that a person using the keyboard is unaware that their actions are being monitored.

Bhumika R 2 Jan 11, 2022
A install script for installing qtile and my configs on Raspberry Pi OS

QPI OS - Qtile + Raspberry PI OS Qtile + Raspberry Pi OS :) Installation Run this command in the terminal

RPICoder 3 Dec 19, 2021
A simple small scale electric car was build which can be driven by remote control and features a fully autonomous parking procedure.

personal-autonomous-parking-car-raspberry A simple electric car model was build using Raspbery pi. The car has remote control and autonomous operation

Kostas Ziovas 2 Jan 26, 2022
Simple Microservice to control 433Mhz wireless sockets over HTTP, e.g. on a RaspberryPi

REST-light is a simple microservice to control 433Mhz wireless sockets over HTTP, e.g. on a RaspberryPi. The main usage is an easy integration of 433M

Pascal Höhnel 1 Jan 9, 2022