mieki256's diary



2017/09/16() [n年前の日記]

#1 [pi3d][python][raspberrypi] pi3dでキー入力を取得その2

pi3dでキー入力を取得する方法について、まだ調べていたり。pi3d.Keyboard() を使うと「タッ……タタタタタ」的に、キー入力のオートリピートが働いてしまうので、なんとかならんものかと。

ふと、pygameと併用したらどうだろうと思いついたわけで。

pygameと併用。 :

試してみたり。

get_keyboard_with_pygame_ss.gif

_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 上では動かない…。
OSresult
Windows10 x64 + Python 2.7.12 + pi3d 2.21 + pygame 1.9.3PASS
Ubuntu Linux 16.04 LTS + Python 2.7.12 + pi3d 2.21 + pygame 1.9.3PASS
Raspberry Pi Zero W + raspbian stretch + Python 2.7.13 + pi3d 2.21 + pygame 1.9.3FAIL

肝心の 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 でインストール。
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でインストール。
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 もエラー。ダメだこりゃ。

以上です。

過去ログ表示

Prev - 2017/09 - Next
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project