[EV3DEV Python] Buttonクラス

# Buttonクラス
インテリジェントブロックボタンに関するクラス

# ev3devにおけるボタンの名前
![ev3_button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/0dd42582-1489-4dbc-7642-bb357b46cbd5.png)
`wait_for_bump()`や`wait_for_pressed()`で指定するボタンには以下の6つのいずれかが入る
1. **enter**
2. **up**
3. **down**
4. **right**
5. **left**
6. **backspace**


# ボタンが 離れた/押された/押されて離された まで待つ

### ・wait_for_bump(*buttons*,*timeout_ms=None*)
指定されたボタンが指定した時間内に**押されて離される（バンプ）**まで待つ。
時間内にボタンがバンプされたら`True`，そうでなければ`False`を返す。

| 引数 | 説明 | デフォルト値 |
|:-:|:-:|:-:|
| *buttons(stringもしくはlist)*  | ボタンの名前(2つ以上の場合はリストで指定)  |   |
| *timeout_ms(float)*  | 処理を中断する待ち時間(ミリ秒)  | None  |

```python:button_wait_for_bump.py
#!/usr/bin/env python3

# クラスのインポート
from ev3dev2.button import Button
from ev3dev2.sound import Sound

# インスタンス化
my_button = Button()
my_sound = Sound()

# 左ボタンが押されて離される（バンプ）まで待つ
my_button.wait_for_bump('left')
my_sound.beep()
```

### ・wait_for_pressed(*buttons*,*timeout_ms=None*)
指定されたボタンが指定した時間内に**押し込まれる**まで待つ。
時間内にボタンが押されたら`True`，押されていなかったら`False`を返す。

```python:button_wait_for_pressed.py
#!/usr/bin/env python3

# インポート
from ev3dev2.button import Button
from ev3dev2.sound import Sound

# インスタンス化
my_button = Button()
my_sound = Sound()

# 上ボタンと下ボタンが押されるまでまつ
my_button.wait_for_pressed(['up','down'])
my_sound.beep()
```

### ・wait_for_pressed(*buttons*,*timeout_ms=None*)
指定されたボタンが指定した時間内に**離される**まで待つ。
時間内にボタンが離されたら`True`，離されなかったら`False`を返す。

```python:button_wait_for_released.py
#!/usr/bin/env python3

# インポート
from ev3dev2.button import Button
from ev3dev2.sound import Sound

# インスタンス化
my_button = Button()
my_sound = Sound()

# 右ボタンが離されるまでまつ
my_button.wait_for_released('right')
my_sound.beep()
```

# いずれかのボタンが押されているかどうか
### ・any()
いずれかのボタンが押されていたら`True`何も押されていなけらば`False`を返す

```Python:button_any.py
#!/usr/bin/env python3

# インポート
from ev3dev2.button import Button
from ev3dev2.sound import Sound
import time

# インスタンス化
my_button = Button()
my_sound = Sound()

# ずっと繰り返す
while True:
    # もしボタンが押されていたら
    if my_button.any():
        my_sound.speak("PUSHED",espeak_opts="-a 200 -p 99")
        break # whileループから抜ける
    else:
        time.sleep(0.01)
```

# ○○ボタンが押されているかどうか
### ・up/down/left/right/enter/backspace
ボタンが押されているかどうかbool型で返される。指定したボタンが押されてたら`True`を返す。

```python:button_push.py
#!/usr/bin/env python3

# インポート
from ev3dev2.button import Button
from ev3dev2.sound import Sound
import time

# インスタンス化
my_button = Button()
my_sound = Sound()

# ずっと繰り返す
while True:
    # もし上ボタンが押されてたら
    if my_button.up:
        my_sound.speak("UP",espeak_opts="-a 200 -p 99")
        break # whileループから抜ける
    else:
        time.sleep(0.01)
```
これらはプロパティとして実装されている。プロパティは読み込み書き込みを制限できる変数みたいなものという理解で良い

# イベントハンドラー
イベントハンドラー・・・特定のイベントが発生した時にあらかじめ登録されている処理を実行する事（ボタンの場合、ボタンが押されたり離されたりした時に呼び出される関数）

### ・process(*new_state=None*)
最後にprocess関数を呼び出した時と現在の各ボタンの状態とを比較し、状態が変わったボタンのイベントハンドラーに登録された関数を実行する。

| 引数 | 説明 | デフォルト値 |
|:-:|:-:|:-:|
| *new_state*  | リファレンスに情報なし(基本的な使い方の時は省略して良い)  | None  |

```py:ButtonEventHandler.py
#!/usr/bin/env python3
# ButtonEventHandler.py 押されたボタンの名前を喋らせる
from time import sleep

from ev3dev2.button import Button
from ev3dev2.sound import Sound

# インスタンス化
my_button = Button()
my_sound = Sound()

# 左ボタンが押された時の処理を関数で宣言
def left(state):
    if state:
        my_sound.speak("left")

# 右ボタンが押された時の処理を関数で宣言
def right(state):
    if state:
        my_sound.speak("right")

# 上ボタンが押された時の処理を関数で宣言
def up(state):
    if state:
        my_sound.speak("up")

# 下ボタンが押された時の処理を関数で宣言        
def down(state):
    if state:
        my_sound.speak("down")

# 決定ボタンが押された時の処理を関数で宣言
def enter(state):
    if state:
        my_sound.speak("enter")


# 各ボタンが押された時に呼びだす関数をそれぞれ紐づける
my_button.on_left = left
my_button.on_right = right
my_button.on_up = up
my_button.on_down = down
my_button.on_enter = enter


while True:
    # 前にprocess()を呼び出した状態と比較して、今の状態が違う場合
    # 上で紐づけられた関数を実行する
    my_button.process()
    sleep(0.01)
```