2017/09/16(土) [n年前の日記]
#1 [pi3d][python][raspberrypi] pi3dでキー入力を取得その2
pi3dでキー入力を取得する方法について、まだ調べていたり。pi3d.Keyboard() を使うと「タッ……タタタタタ」的に、キー入力のオートリピートが働いてしまうので、なんとかならんものかと。
ふと、pygameと併用したらどうだろうと思いついたわけで。
ふと、pygameと併用したらどうだろうと思いついたわけで。
◎ pygameと併用。 :
試してみたり。
_get_keyboard_with_pygame.py
_airplane_01_64x64.png (CC0 License)
一見すると上手く動いてるようだけど、これはこれで問題が。Windows10 x64 や Ubuntu Linux 上では動くのだけど、Raspberry Pi 上では動かない…。
肝心の Raspberry Pi上で動いてくれないのでは困る。
_pi3d/Display.py を眺めてみたのだけど…。
ちなみに、Ubuntu Linux 上でも、pi3d.Display.create() に use_pygame=False を渡してみたら、pygame を使ったキー入力取得ができなかった。
また、Windowsの場合は、use_pygame=True を指定しなくても、自動で必ず pygame を使うように設定される模様。
_get_keyboard_with_pygame.py
_airplane_01_64x64.png (CC0 License)
u""" pi3d input keyboard with pygame sample. キーボード入力を取得してみるサンプル。 WASDキーで上下左右に動かしてみる。 pygameを使ってキーボードの状態を調べる。 ESCキーで終了する。 Windows10 x64 + Python 2.7.12 32bit + pi3d 2.21 """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import pi3d import pygame # ウインドウ生成 display = pi3d.Display.create(w=640, h=480, frames_per_second=60, use_pygame=True) # シェーダーを生成。uv_flatは照明関係の計算をしない。 shader = pi3d.Shader("uv_flat") # カメラを平行投影に camera = pi3d.Camera(is_3d=False) # テクスチャを読み込み tex = pi3d.Texture("airplane_01_64x64.png", mipmap=False) # スプライトを生成 x, y, z = 0.0, 0.0, 20.0 spr = pi3d.ImageSprite(tex, shader, w=64, h=64, x=x, y=y, z=z) # スプライトをDisplayに登録 display.add_sprites(spr) # キーボード入力を取得するためにpygameを初期化 pygame.init() pikeys = pi3d.Keyboard() print(pikeys) # メインループ while display.loop_running(): quit_fg = False spd = 6.0 pygame.event.pump() # pygameがイベントを処理できるようにする # キー入力で座標を変化させる keys = pygame.key.get_pressed() if keys[pygame.K_w] or keys[pygame.K_UP]: spr.translateY(spd) # スプライトのy座標を変化 if keys[pygame.K_s] or keys[pygame.K_DOWN]: spr.translateY(-spd) if keys[pygame.K_a] or keys[pygame.K_LEFT]: spr.translateX(-spd) # スプライトのx座標を変化 if keys[pygame.K_d] or keys[pygame.K_RIGHT]: spr.translateX(spd) if keys[pygame.K_ESCAPE]: quit_fg = True pikey = pikeys.read() if pikey == 27: # ESC key quit_fg = True if quit_fg: # ループを抜けて終了 display.destroy() break
一見すると上手く動いてるようだけど、これはこれで問題が。Windows10 x64 や Ubuntu Linux 上では動くのだけど、Raspberry Pi 上では動かない…。
OS | result |
---|---|
Windows10 x64 + Python 2.7.12 + pi3d 2.21 + pygame 1.9.3 | PASS |
Ubuntu Linux 16.04 LTS + Python 2.7.12 + pi3d 2.21 + pygame 1.9.3 | PASS |
Raspberry Pi Zero W + raspbian stretch + Python 2.7.13 + pi3d 2.21 + pygame 1.9.3 | FAIL |
肝心の Raspberry Pi上で動いてくれないのでは困る。
_pi3d/Display.py を眺めてみたのだけど…。
- Windows と Linux の場合は、pi3d.Display.create() で use_pygame=True を渡すと、pygameのウインドウを作成して、その中で OpenGL ES(もしかするとOpenGL)を表示してくれるから、pygame関係のアレコレが動いてくれるっぽい。
- しかし、Raspberry Pi 上で動かした場合、問答無用で use_pygame=False に設定されてしまって、pygame のウインドウが出てこない=pygameのアレコレが使えない状態になる。
ちなみに、Ubuntu Linux 上でも、pi3d.Display.create() に use_pygame=False を渡してみたら、pygame を使ったキー入力取得ができなかった。
また、Windowsの場合は、use_pygame=True を指定しなくても、自動で必ず pygame を使うように設定される模様。
◎ pynputを試してみたり。 :
pygame以外にキー入力を調べられるモジュールはないのかなとググってみたら、pynput なるモジュールに遭遇。
_pynput 1.3.7 : Python Package Index
_Pythonでキーイベントを取得したかったけどできなかった話←できました。 - 豆腐とコンソメ
試してみたり。pip でインストール。
サンプルスクリプトをコピペして動作確認。
_pynput_sample.py
しかし…。Windows10 x64 + DOS窓(cmd.exe)上ではそれらしく動いたのだけど、Ubuntu Linux 16.04 LTS + ターミナルエミュレータ(GNOME端末)上では、押したキーが端末上に表示されてしまって…。しかも、カーソルキー等の特殊キーを押した際には、端末上の表示がそれはもう大変なことに。
ということで、pynput では、今回の目的を果たせないようだなと。
_pynput 1.3.7 : Python Package Index
_Pythonでキーイベントを取得したかったけどできなかった話←できました。 - 豆腐とコンソメ
試してみたり。pip でインストール。
pip install pynput
サンプルスクリプトをコピペして動作確認。
_pynput_sample.py
u""" pynput sample. キー入力を調べる pynput の動作確認。 動作確認環境: Windows10 x64 + Python 2.7.12 32bit + pynput 1.3.7 """ import pynput def on_press(key): """Key press.""" try: print('alphanumeric key {0} pressed'.format(key.char)) except AttributeError: print('special key {0} pressed'.format(key)) def on_release(key): """Key release.""" print('{0} released'.format(key)) if key == pynput.keyboard.Key.esc: # Stop listener return False # Collect events until released print("ESC to exit.") with pynput.keyboard.Listener(on_press=on_press, on_release=on_release) as listener: listener.join()
しかし…。Windows10 x64 + DOS窓(cmd.exe)上ではそれらしく動いたのだけど、Ubuntu Linux 16.04 LTS + ターミナルエミュレータ(GNOME端末)上では、押したキーが端末上に表示されてしまって…。しかも、カーソルキー等の特殊キーを押した際には、端末上の表示がそれはもう大変なことに。
ということで、pynput では、今回の目的を果たせないようだなと。
◎ inputsを使ってみる。 :
他にもキーボード入力を取得できるモジュールが無いのかなと探してみたら、inputs なるモジュールに遭遇。
_inputs 0.1 : Python Package Index
_zeth/inputs: Cross-platform Python support for keyboards, mice and gamepads
2016/06/17が最終更新日らしい。
試してみたり。環境は Windows10 x64 + Python 2.7.12。pipでインストール。
クイックスタートに従って、以下を試してみたのだけど。
_'Keyboard' object has no attribute 'name' - Issue #13 - zeth/inputs としてバグ報告はされてるのだけど、github上のソースは去年から全く更新されてない…。
_inputs/examples の _inputs/devices_example.py も _inputs/keyboard_example.py もエラー。ダメだこりゃ。
_inputs 0.1 : Python Package Index
_zeth/inputs: Cross-platform Python support for keyboards, mice and gamepads
2016/06/17が最終更新日らしい。
試してみたり。環境は Windows10 x64 + Python 2.7.12。pipでインストール。
pip install inputs
クイックスタートに従って、以下を試してみたのだけど。
> py Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:19:22) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import inputs >>> for device in inputs.devices: ... print(device) ... Traceback (most recent call last): File "<stdin>", line 2, in <module> File "C:\Python\Python27\lib\site-packages\inputs.py", line 2031, in __str__ return self.name AttributeError: 'Keyboard' object has no attribute 'name'いきなり最初からエラー。
_'Keyboard' object has no attribute 'name' - Issue #13 - zeth/inputs としてバグ報告はされてるのだけど、github上のソースは去年から全く更新されてない…。
_inputs/examples の _inputs/devices_example.py も _inputs/keyboard_example.py もエラー。ダメだこりゃ。
[ ツッコむ ]
以上です。