私は基本的なキーボードとそのアプリケーション用に特別に設計されたキーボードを使用できるアプリケーションをPythonで作成したいと思います。さまざまなキーの動作を提供するために、ステッカー付きの小さな数字パッドを使用して簡単に設計します。どちらのキーボードもUSB経由で接続されています。
ただし、これらのキーを押すと、通常の信号(数字、演算子、入力)のみがPythonに送信され、基本キーボードと特殊キーボードの信号を区別できません。
(私が知っている限り)Pythonではこれらの区別を行う方法がないので、オペレーティングシステム自体で区別を作成したいと思います。私はRaspberry Pi用にプログラムするので、Linuxになります。
したがって、主な質問は、特定のキーボードのキーを別のキーコードに再マッピングする方法です。私はFキーを使用することを検討しましたが、他の目的には使用しないか、キーボードに存在しない一部の文字(そのような文字があると仮定)にのみ使用しました。
Linux/Unixでこれは可能ですか?では、どうすればよいですか?
答え1
Linuxを使用している場合、入力デバイスを区別する最良の方法は次のようにすることです。Linuxイベントインターフェース。デバイスのハードウェア関連入力がデコードされた後、中間のLinux関連イベント構造に変換され、デバイスが1つ以上の文字を読み取って使用できるようになります/dev/input/
。ちなみに、これは使用するプログラミング言語とは全く独立しています。
各ハードウェアデバイスには独自のデバイスが/dev/input/eventX
あり、集計もあります(たとえば、/dev/input/mice
システム内のすべてのマウスの動きを表します)。システムには、/dev/input/by-path
およびがあります/dev/input/by-id
。
人間が読める文字列としてデバイス名を返すioctl
呼び出しがあるか、または。EVIOCGNAME
/dev/input/by-id/usb-Logitech_USB_Gaming_Mouse-mouse
デバイスの電源を入れ、入力ハードウェアからイベントが到着するたびにパケットを受信します。 Cを読むことができれば、/usr/include/linux/input.h
この文書がどのように機能するかを正確に示すこの文書を勉強できます。そうでなければできますこの質問を読んでください必要なすべての情報を提供します。
イベントインタフェースの良いことは、必要なデバイスが何であるかを調べるだけで、その入力デバイスから入力を読み取ることができることです。ただ、他のすべての項目は無視されます。また、端末で「調理済み」文字ストリームを読み取るだけでは、一般的に得られないキー、ボタン、およびコントロールについての通知も受け取ることができます。デッドキーなども受けられますShift。
悪いことは、イベントインタフェースが「調理済み」文字を返さずに数値コードをキーとして使用することです(各キーに対応するコードは、前述のヘッダファイルにあり、Pythonソースコードにあります) 。events.py。入力デバイスに異常なキー/ボタンがある場合は、正しい数字が得られるまで少し実験が必要になることがあります。
答え2
もう1つのアプローチ(「キーボード」にキーが多くない場合 - 多くのデバイスがキーボードであるふりをする場合)は、各キーボードに特別にキーマップを適用し、キーが区別されることを確認することです。
これの説明は次のとおりです。https://superuser.com/questions/760602/how-to-remap-keys-under-linux-for-a-specific-keyboard-only。重要なのは、setxkbmap
デバイスパラメータが必要であることです。
raw 入力方式を使用している場合、 lsinput は raw デバイスを探します。
答え3
Pythonを使用している場合 -evdev
ドキュメントから:
このパッケージは、Linuxの共通入力イベントインタフェースへのバインディングを提供します。 evdevインタフェースの目的は、カーネルによって生成されたイベントを通常/ dev / input /にある文字デバイスを介してユーザー空間に直接渡すことです。
このパッケージには、uinput(ユーザー空間入力サブシステム)へのバインディングも付属しています。 Uinputを使用すると、ユーザー空間プログラムはイベントを入力サブシステムに直接注入できる入力デバイスを作成および処理できます。
つまり、python-evdevを使用すると、Linuxで入力イベントを読み書きできます。イベントは、キーまたはボタンを押す、マウスを移動する、またはタッチスクリーンをクリックすることができます。
その後、チュートリアルページで...
複数のデバイスからイベントを読み込む(selectを使用)
>>> from evdev import InputDevice
>>> from select import select
# A mapping of file descriptors (integers) to InputDevice instances.
>>> devices = map(InputDevice, ('/dev/input/event1', '/dev/input/event2'))
>>> devices = {dev.fd: dev for dev in devices}
>>> for dev in devices.values(): print(dev)
device /dev/input/event1, name "Dell Dell USB Keyboard", phys "usb-0000:00:12.1-2/input0"
device /dev/input/event2, name "Logitech USB Laser Mouse", phys "usb-0000:00:12.0-2/input0"
>>> while True:
... r, w, x = select(devices, [], [])
... for fd in r:
... for event in devices[fd].read():
... print(event)
event at 1351116708.002230, code 01, type 02, val 01
event at 1351116708.002234, code 00, type 00, val 00
event at 1351116708.782231, code 04, type 04, val 458782
event at 1351116708.782237, code 02, type 01, val 01
各デバイスを個別に処理できます。