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 もエラー。ダメだこりゃ。
[ ツッコむ ]
#2 [python][windows] Python + curses を試す
pi3d を Raspberry Pi上で動かすと、キーボード入力を curses なるもので取得するようで。何ができるモジュールなのかよく分からなかったので、少し試してみようと。
Windows10 x64上でサンプルスクリプトを動かそうとしたら、「_curses なんてモジュールはねえよ」と怒られてしまった。どうやら Windows版Pythonの場合、別途 curses をインストールしないといかんらしい。
_Python で Curses のサンプルを書いてみた - quwaharaの日記
自分が使ってるのは Python 2.7.12 なので、 _Python Extension Packages for Windows - Christoph Gohlke から、curses-2.2-cp27-none-win32.whl をDL。pipでインストール。
_curses_sample.py
python curses_sample.py で実行したら、押したキーが表示された。一応キー入力を取得することはできるらしい。ESCキーかqキーを押せば終了。
しかし…。コレってキーの同時押しを取得できないのでは…。1文字ずつ入力されることを前提にしてるような…。
ちなみに、上記スクリプトは VMware + Ubuntu Linux 16.04 LTS上でも動いた。Linux上ではデフォルトインストール状態で動いてしまうのだな…。ズルイ…。
Windows10 x64上でサンプルスクリプトを動かそうとしたら、「_curses なんてモジュールはねえよ」と怒られてしまった。どうやら Windows版Pythonの場合、別途 curses をインストールしないといかんらしい。
_Python で Curses のサンプルを書いてみた - quwaharaの日記
自分が使ってるのは Python 2.7.12 なので、 _Python Extension Packages for Windows - Christoph Gohlke から、curses-2.2-cp27-none-win32.whl をDL。pipでインストール。
pip install curses-2.2-cp27-none-win32.whlこれで、Windows上でも curses が使えるようになった。
_curses_sample.py
u"""
curses sample.
キー入力を取得して表示する。
ESCキーかqキーで終了。
Windows10 x64 + Python 2.7.12 32bit + curses 2.2
"""
import curses
import os
def main(win):
u"""メイン処理."""
win.nodelay(True)
key = ""
win.clear()
win.addstr("Detected key:")
while 1:
try:
key = win.getkey()
win.clear()
win.addstr("Detected key:")
win.addstr(str(key))
if key == os.linesep or key == "q" or ord(key) == 27:
break
except Exception as e:
# No input
pass
curses.wrapper(main)
python curses_sample.py で実行したら、押したキーが表示された。一応キー入力を取得することはできるらしい。ESCキーかqキーを押せば終了。
しかし…。コレってキーの同時押しを取得できないのでは…。1文字ずつ入力されることを前提にしてるような…。
ちなみに、上記スクリプトは VMware + Ubuntu Linux 16.04 LTS上でも動いた。Linux上ではデフォルトインストール状態で動いてしまうのだな…。ズルイ…。
[ ツッコむ ]
#3 [anime] SWITCHに米林監督が出てたのか
知らなかった…。見損ねた…。知ってたら予約録画しておいたのに…。再放送しないのかな…。
[ ツッコむ ]
以上、1 日分です。
