MacOS读取蓝牙摇杆讯号,利用python修改pynput程序码实现 - 2.研究 pynput

请参考之前的文章:第一篇

4. 研究 pynput

首先,在Visual Studio Code界面中,将滑鼠移动到from pynput.keyboard import Listener,同时按下Macbook的command按键,就会出现超联结的鼠标,点击之後就可以看到pynput.keyboard的程序码了。(内心os:之前我都是靠故意写错代码,然後在终端机报错栏给的超联结进入import的module,不但麻烦而且很不方便)

进入pynput.keyboard之後可以看到:

from pynput._util import backend, Events

backend = backend(__name__)
KeyCode = backend.KeyCode
Key = backend.Key
Controller = backend.Controller
Listener = backend.Listener
del backend

Listener = backend.Listener 就是我们要找的,这个时候如果将__name__ print出来,就会发现是pynput.keyboard。接着继续看pynput._util的程序码

def backend(package):
    """Returns the backend module for a package.

    :param str package: The package for which to load a backend.
    """
    backend_name = os.environ.get(
        'PYNPUT_BACKEND_{}'.format(package.rsplit('.')[-1].upper()),
        os.environ.get('PYNPUT_BACKEND', None))
    if backend_name:
        modules = [backend_name]
    elif sys.platform == 'darwin':
        modules = ['darwin']
    elif sys.platform == 'win32':
        modules = ['win32']
    else:
        modules = ['xorg']

    errors = []
    resolutions = []
    for module in modules:
        try:
            return importlib.import_module('._' + module, package)
        except ImportError as e:
            errors.append(e)
            if module in RESOLUTIONS:
                resolutions.append(RESOLUTIONS[module])

    raise ImportError('this platform is not supported: {}'.format(
        '; '.join(str(e) for e in errors)) + ('\n\n'
            'Try one of the following resolutions:\n\n'
            + '\n\n'.join(
                ' * {}'.format(s)
                for s in resolutions))
            if resolutions else '')

我们将package print出来,发现还是pynput.keyboard
我们将sys.platform print出来,可以得到darwin
我们将'._' + module, package print出来,可以得到._darwin pynput.keyboard

上面这一段代码,最後会return importlib.import_module('._' + module, package)
这是什麽意思研究很久也没有结论,只能猜测应该是要import pynput.keyboard._darwin

接着我们进去pynput.keyboard._darwin看看,不过由於里面的程序码有点复杂,我不太会分析,所以只好利用插入大量的print,个人习惯是print(111) print(222) print(333)……,接着看看程序在执行的时候,自己插入的哪些段落有被print出来,就可以反推出有哪些程序码被执行过,以下就是找到的结果:

class Listener(ListenerMixin, _base.Listener):
    # 省略多行程序码
    def _handle(self, _proxy, event_type, event, _refcon):
        # 省略多行程序码
        elif event_type == Quartz.NSSystemDefined:
        sys_event = Quartz.NSEvent.eventWithCGEvent_(event)
        if sys_event.subtype() == kSystemDefinedEventMediaKeysSubtype:
            # The key in the special key dict; True since it is a media
            # key
            key = ((sys_event.data1() & 0xffff0000) >> 16, True)
            if key in self._SPECIAL_KEYS:
                flags = sys_event.data1() & 0x0000ffff
                is_press = ((flags & 0xff00) >> 8) == 0x0a
                if is_press:
                    self.on_press(self._SPECIAL_KEYS[key])
                else:
                    self.on_release(self._SPECIAL_KEYS[key])

读到这里,我们就可以知道pynput是藉由importQuartz来读取蓝牙的讯号
我们将sys_event print出来,可以看到:

NSEvent: type=SysDefined loc=(266.629,634.41) time=232454.5 flags=0 win=0x0 winNum=0 ctxt=0x0 subtype=8 data1=1051392 data2=-1
NSEvent: type=SysDefined loc=(266.629,634.41) time=232454.5 flags=0 win=0x0 winNum=0 ctxt=0x0 subtype=8 data1=1182208 data2=-1
NSEvent: type=SysDefined loc=(266.629,634.41) time=232454.8 flags=0 win=0x0 winNum=0 ctxt=0x0 subtype=8 data1=1182464 data2=-1
NSEvent: type=SysDefined loc=(266.629,634.41) time=232454.8 flags=0 win=0x0 winNum=0 ctxt=0x0 subtype=8 data1=1051136 data2=-1

观察可以发现只有data1才有变化
接着我将蓝牙摇杆的四个摇杆方向,以及其他6个键盘会接收到data1值做整理,如下:
https://ithelp.ithome.com.tw/upload/images/20220130/20141667uWq3rERRg7.png
整理後发现

# 上下左右,前上前下,ABCD都会出现
1051392
1051136
# 上 单独出现
1182208
1182464
# 下 单独出现
1116672
1116928
# 左 单独出现
1313280
1313536
# 右 单独出现
1247744
1248000

续看,请参考:第三篇


<<:  MacOS读取蓝牙摇杆讯号,利用python修改pynput程序码实现 - 1.起始

>>:  MacOS读取蓝牙摇杆讯号,利用python修改pynput程序码实现 - 3.修改pynput

apt-get upgrade 和dist-upgrade的差别

Debian/Ubuntu Linux都使用apt,升级时都是: apt-get update ap...

Day 45 (Node.js)

1.版本 https://nodejs.org/en/ 下载LTS (长期稳定版本) 用10以上版本...

Day 12 Azure cognitive service: OCR- 光学字元辨识

Azure cognitive service: OCR- 光学字元辨识 OCR- Optical ...

[第29天]理财达人Mx. Ada-布林通道(Bollinger Band)

前言 本文说明使用TA-Lib函式库计算及呈现布林通道。 布林通道 布林通道(Bollinger B...

【Day 29】Hook 09:自定义 Hook(Custom hook)

打造自己的 Hook 自 React 16.8 以後, 使用者就可以在 React 中 创建自定义的...