【问题标题】:Python - How to get current keylock status?Python - 如何获取当前的键锁状态?
【发布时间】:2012-10-29 21:15:17
【问题描述】:

我正在尝试编写一个简单的程序来显示不同键锁的当前状态,但我无法找到如何在 Python 中获取它们当前状态的解决方案。谢谢。

【问题讨论】:

  • 对不起,应该提到。 Linux。
  • 你可以使用python-keyboardleds(仅限Linux)
  • @LukasGraf 谢谢,但我想我会选择另一个选项,因为这不需要我拉入任何外部包。不管怎样,谢谢!
  • @DoDoGo 不错的选择 :) 如果您想消除对 xset 的依赖以及 shell 调用,您可以通过在 /dev/console 上执行正确的 ioctls 从 Python 自己完成这一切。弄清楚如何从查看 python-keyboardleds 的源代码应该是微不足道的(不幸的是,从 /dev/console 读取将需要 root 权限)。
  • 我会尝试将其作为练习,但我打算让它在用户空间中运行。不过感谢您的建议,因为这让我可以在周末尝试一下。任何事情都会有所帮助,因为我最近才开始使用 Python。

标签: python capslock


【解决方案1】:

如果您可以等待一两天,我会将此功能添加到 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}

使用@ronak 提到的xset 会容易得多,因为您不必对任何输入设备具有读取权限。不幸的是,它只能在 X 下工作(而 X 又使用evdev 接口(至少在 linux 上))。


好吧,我花了足够长的时间,但它在里面。让 LED 'ON' 的界面最终是:

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

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

获取设备上所有可用的 LED:

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

【讨论】:

  • 这看起来很棒!如果您不介意添加,我喜欢这个解决方案(以及它长期解决问题的事实)!
  • 感谢您执行此操作,@gvalkov。在今天的实现中,似乎必须使用dev.leds() 来获得list 的活动LED,每个都是int
【解决方案2】:

好的,在阅读了source code for python-keyboardledsconsole_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权限。

有关所涉及概念的详细信息,请参阅 ioctlsbitmasking 上的维基百科页面,以及 Python fcntl module 的文档。

【讨论】:

  • 谢谢,虽然我不会使用它,但我很欣赏 ioctls 上的示例。我一定会在周末去看看这个!
【解决方案3】:
└──> 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

大写锁定打开时,LED 掩码应为 1,如果 LED 掩码关闭,则应为 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 )

【讨论】:

  • 谢谢!我看到 0 是无,1 是大写锁定,2 是数字锁定,4 滚动锁定,然后它加起来。太好了!
  • 来自文档,Deprecated since version 2.6: The commands module has been removed in Python 3. Use the subprocess module instead.
  • 在某些情况下,键盘 LED 不能准确地表示大写锁定状态。
【解决方案4】:

另见 tkinter - 有 Caps-Lock 的事件。 当我打开面板时,我使用 xset 查找 Caps-Lock 的初始状态,然后在面板打开时使用 tkinter 事件来跟踪。 1)我不确定如何在 tkinter 中获得初始状态 - 一定有办法 2 xset 在 tkinter 事件 proc 中似乎不可靠 - proc 并不总是通过 xset 显示大写锁定更改...

示例代码:

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

另见: Python - How to get current keylock status?

【讨论】:

    【解决方案5】:

    为了扩展 ronak 提供的答案,python3 版本按其应有的方式工作,但仅在 num lock 开启时。

    subprocess.check_output('xset q | grep LED', shell=True)[65] 返回值 48 到 51,具体取决于 numlock 和 caps lock 的状态(capslock 加 1,而 numlock 加 2)

    考虑到数字锁定,这应该可以工作:

    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")```
    

    【讨论】:

      【解决方案6】:

      如果您的操作系统是 Windows,请尝试:

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

      【讨论】:

        【解决方案7】:

        在 Windows 下查看https://stackoverflow.com/a/21160382/10871895 的大写锁定键,无需加载其他模块。

        【讨论】:

          猜你喜欢
          • 2023-03-17
          • 1970-01-01
          • 1970-01-01
          • 2020-03-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-15
          相关资源
          最近更新 更多