23

Is there any way, in Python, to programmatically change the CAPS LOCK/NUM LOCK/SCROLL LOCK states?

This isn't really a joke question - more like a real question for a joke program. I intend to use it for making the lights do funny things...

Braiam
  • 1
  • 11
  • 47
  • 78
Lucas Jones
  • 19,767
  • 8
  • 75
  • 88

6 Answers6

18

On Linux here's a Python program to blink all the keyboard LEDs on and off:

import fcntl
import os
import time

KDSETLED = 0x4B32
SCR_LED  = 0x01
NUM_LED  = 0x02
CAP_LED  = 0x04

console_fd = os.open('/dev/console', os.O_NOCTTY)

all_on = SCR_LED | NUM_LED | CAP_LED
all_off = 0

while 1:
    fcntl.ioctl(console_fd, KDSETLED, all_on)
    time.sleep(1)
    fcntl.ioctl(console_fd, KDSETLED, all_off)
    time.sleep(1)
Benji York
  • 2,044
  • 16
  • 20
  • I'm on Linux right now so I'll give that a shot. I was aiming for Windows though - should have made that clear :) – Lucas Jones May 13 '09 at 17:40
  • 7
    Nice, but it needs root privs to open /dev/console (unless permissions are set). Any way for it to run as a normal user? – Lucas Jones May 13 '09 at 17:43
16

If you're using windows you can use SendKeys for this I believe.

http://www.rutherfurd.net/python/sendkeys

import SendKeys

SendKeys.SendKeys("""
{CAPSLOCK}
{SCROLLOCK}
{NUMLOCK}
""")
sclarson
  • 4,362
  • 3
  • 32
  • 44
6

Probably of no use to the OP but worth sharing as someone might be looking for the answer as i was but could not find the solution without using third party modules. This is what i did to turn the caps lock on

import ctypes

def turn_capslock():
    dll = ctypes.WinDLL('User32.dll')
    VK_CAPITAL = 0X14
    if not dll.GetKeyState(VK_CAPITAL):
        dll.keybd_event(VK_CAPITAL, 0X3a, 0X1, 0)
        dll.keybd_event(VK_CAPITAL, 0X3a, 0X3, 0)

    return dll.GetKeyState(VK_CAPITAL)
print(turn_capslock())
Faisal Khan
  • 191
  • 1
  • 8
3

For Windows:

#https://stackoverflow.com/questions/21549847/send-key-combination-with-python
#https://msdn.microsoft.com/en-us/library/8c6yea83(v=vs.84).aspx 

import win32com.client as comclt
wsh= comclt.Dispatch("WScript.Shell")
wsh.SendKeys("abc") #types out abc directly into wherever you have your cursor (ex: right into this editor itself!)

wsh.SendKeys("{NUMLOCK}{CAPSLOCK}{SCROLLLOCK}") #toggles the state of NumLock, CapsLock, and ScrollLock; remove whichever one you don't want to toggle

Sources:

  1. Send key combination with python
  2. https://msdn.microsoft.com/en-us/library/8c6yea83(v=vs.84).aspx

Also, pay careful attention to Uri's answer about how to read the CapsLock state. To set an LED state specifically to true or false, you can't just blindly toggle, you have to know what the current state is first. He shows you how to read the CapsLock state. Here's how to read all 3 LED states:

#https://stackoverflow.com/questions/854393/change-keyboard-locks-in-python/854442#854442abc
#https://support.microsoft.com/en-us/kb/177674
import win32api,win32con

def isCapsLockOn():
    "return 1 if CapsLock is ON"
    return win32api.GetKeyState(win32con.VK_CAPITAL)

def isNumLockOn():
    "return 1 if NumLock is ON"
    return win32api.GetKeyState(win32con.VK_NUMLOCK)

def isScrollLockOn():
    "return 1 if ScrollLock is ON"
    return win32api.GetKeyState(win32con.VK_SCROLL)

print("IsCapsLockOn = ", IsCapsLockOn())
print("isNumLockOn = ", isNumLockOn())
print("isScrollLockOn = ", isScrollLockOn())

For Linux:

Don't know all the details yet, but start here: Change keyboard locks in Python.

Is there a generic Python module for any OS?

Don't know yet.

Related:

  1. How to generate keyboard events in Python? - I need to look into this.
  2. https://pypi.org/project/keyboard/ - looks like it requires sudo for Linux. That's not good, but I need to look into it more.
  3. Another Windows-only module it looks like: https://pypi.org/project/SendKeys/
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
2

To set CAPS LOCK to a specific value using SendKeys it is important to first detect the state of CAPS LOCK. Here's how to do that in python (under windows):

import win32api,win32con

def IsCapsLockOn():
    # return 1 if CAPSLOCK is ON
    return win32api.GetKeyState(win32con.VK_CAPITAL)
uri
  • 392
  • 2
  • 6
0

Use this:

from win32api import GetKeyState
from win32con import VK_CAPITAL

GetKeyState(VK_CAPITAL)

1 == True 0 == False

You can get other keys as well, here is the list: https://learn.microsoft.com/en-au/windows/win32/inputdev/virtual-key-codes

Wudfulstan
  • 129
  • 11