Python - Как получить текущий статус блокировки клавиатуры?

Я пытаюсь написать простую программу, которая отображает текущее состояние различных блокировок клавиш, но я не могу найти решение о том, как получить их текущий статус в Python. Спасибо.

8 ответов

Решение
└──> xset q | grep LED
  auto repeat:  off    key click percent:  0    LED mask:  00000000
└──> xset q | grep LED
  auto repeat:  off    key click percent:  0    LED mask:  00000001

Когда блокировка шапок включена, маска светодиодов должна быть 1, а если маска светодиодов выключена, то она должна быть 0.

Кроме того, поскольку вы упомянули, что хотите использовать python, вы можете получить значение следующим образом

>>> import commands
>>> # Caps Lock is off.
>>> commands.getoutput('xset q | grep LED')[65]
'0'
>>> # Setting Caps Lock on now.
>>> commands.getoutput('xset q | grep LED')[65]
'1'

версия Python 3:

import subprocess
if subprocess.check_output('xset q | grep LED', shell=True)[65] == 50 :
    capslock = False
if subprocess.check_output('xset q | grep LED', shell=True)[65] == 51 :
    capslock = True
print( "capslock ON is : ", capslock )

Если вы можете подождать день или два, я добавлю эту функцию в python-evdev и обновлю этот ответ. Вероятно, это будет выглядеть примерно так:

from evdev import InputDevice, ecodes

dev = InputDevice('/dev/input/eventX') # your keyboard device
dev.ledstates(verbose=True)
{ (0, 'LED_NUML')    : True,
  (1, 'LED_CAPSL')   : True,
  (2, 'LED_SCROLLL') : False}

С помощью xset как упоминается @ronak, это намного проще, так как вам не нужно иметь права на чтение на любых устройствах ввода. К сожалению, он работает только под X (а X, в свою очередь, использует evdev интерфейс (по крайней мере, в Linux)).


Что ж, это заняло у меня достаточно много времени, но оно вошло. Интерфейс для включения индикаторов 'ON' в итоге оказался:

>>> dev.leds()
[0, 1, 8, 9]

>>> dev.leds(verbose=True)
[('LED_NUML', 0), ('LED_CAPSL', 1), ('LED_MISC', 8), ('LED_MAIL', 9)]

Получение всех доступных светодиодов на устройстве:

>>> dev.capabilities()[ecodes.EV_LED]
[0, 1, 2]

>>> dev.capabilities(verbose=True)[('EV_LED', ecodes.EV_LED)]
[('LED_NUML', 0), ('LED_CAPSL', 1), ('LED_SCROLLL', 2)]

Хорошо, после прочтения исходного кода дляpython-keyboardleds и console_ioctl manpage, вот как это сделать на простом Python:

import os
import struct
import fcntl

DEVICE = '/dev/tty'    

_KDGETLED = 0x4B31

scroll_lock = 0x01
num_lock = 0x02
caps_lock = 0x04

fd = os.open(DEVICE, os.O_WRONLY)

# ioctl to get state of leds
bytes = struct.pack('I', 0)
bytes = fcntl.ioctl(fd, _KDGETLED, bytes)
[leds_state] = struct.unpack('I', bytes)

# Use bitmask to check status caps_lock bit
status = leds_state & caps_lock != 0

print "Caps Lock is On: %s" % status

Примечание. Это работает только для реальных терминалов и VT (1-7, доступных с помощью ctrl+alt+Fx), но не для псевдо-терминалов в эмуляторе терминала X11, например.

Чтобы проверить, запустите tty в вашей консоли:

$ tty
/dev/tty1    # will work

$ tty
/dev/pts/4   # won't work

С помощью /dev/console поскольку запрашиваемое устройство будет работать и в X11, но требует привилегий root.

Для получения подробной информации о концепциях смотрите страницы в Википедии о ioctls и битовой маске, а также документы по Python. fcntl модуль.

для проверки блокировки заглавных букв вы можете использовать это:

      import ctypes

def is_capslock_on():
    return True if ctypes.WinDLL("User32.dll").GetKeyState(0x14) else False

print(is_capslock_on())

Если ваша ОС Windows, попробуйте:

import win32api,win32con
caps_status = win32api.GetKeyState(win32con.VK_CAPITAL)
if caps_status==0:
    print('CapsLock is off')
else:
    print('CapsLock is on')

Чтобы расширить ответ, предоставленный ronak, версия python3 работает так, как должна, но только при включенной блокировке num.

subprocess.check_output('xset q | grep LED', shell=True)[65] возвращает значения с 48 по 51, в зависимости от статуса numlock и caps lock (capslock добавляет значение 1, тогда как numlock добавляет 2)

Это должно работать с учетом numlock:

import subprocess
x=subprocess.check_output('xset q | grep LED', shell=True)[65]
if x==48 or x==50:
    print("caps off")
    if x == 48:
        print("num off")
    else:
        print("num on")
elif x==49 or x==51:
    print("caps on")
    if x == 49:
        print("num off")
    else:
        print("num on")```

Также смотрите tkinter - там есть события для Caps-Lock. Я использовал xset, чтобы найти начальный статус Caps-Lock при открытии панели, а затем использовал событие tkinter, чтобы отслеживать, пока панель открыта. 1) Я не был уверен, как получить начальное состояние в tkinter - должен быть способ, которым 2 xset не казался надежным в рамках события tkinter proc - процесс не всегда отображал изменение caps-lock через xset...

Образец кода:

def capsLock(event):
   caps = event.state & 0x0002

Также смотрите: Python - Как получить текущий статус блокировки клавиатуры?

Посмотрите /questions/30090385/python-3x-poluchenie-sostoyaniya-caps-locknum-lockscroll-lock-v-windows/30090395#30090395 для ключа Caps Lock под Windows без загрузки дополнительных модулей.

Другие вопросы по тегам