kivyMDチュートリアル其の肆什肆 Behaviors - Focus篇

ハロー、Qiita!いかがお過ごしでしょうか。

もう寒くないとは言えない(当たり前)時期になってきていますが、どうでしょうか。
体調など崩してはいないでしょうか。

アドベントカレンダーも真っ最中という状況ですね。投稿者はまったく参加していない
のですが、中には投稿している方もいらっしゃるのではないでしょうか。KivyMDはタグ
すらなかったので、まず前提に立たされていないというのは余談ではありますが、投稿
などしなくとも、何か気になる記事など見つかったでしょうか。

ということで賑わってる中、投稿者はもくもく週1でやっているというのはあるのですが、
本題に入りまして今日はというとFocus篇となります。次回予定のHover篇とどう違うの
だろうと思っているところですが、それを解き明かすのは次回あたりになりそうです。

まず今週は、Focusを解き明かすのが先決でしょうか。では前置きはこのあたりにして
おいてさっそく取り掛かるとします。それでは、レッツラゴ。

## Focus

冒頭にはこう書かれていますね。最初の1文を見てみましょう。

> Changing the background color when the mouse is on the widget.

依頼するまではないですね。書かれている通りになるかと。
ですが、ここまでだとHoverとどう違うのかは分かりません。

次に書いてある文も見てみましょう。

> To apply focus behavior, you must create a new class that is 
> inherited from the widget to which you apply the behavior 
> and from the FocusBehavior class.

ここでは使い方が書かれていますね。使用するには、FocusBehaivorクラスを
用いなければなりません。

この辺りに関しては、コードと実行結果を見てみるしかないようです。ではさっそく
コードの方から覗いていきましょう。

### Usage

これも見た方が早いので、コードを記載しておきます。

```python:xliv/focuswidget.py
from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.behaviors import RectangularElevationBehavior, FocusBehavior
from kivymd.uix.boxlayout import MDBoxLayout

KV = '''
MDScreen:

    FocusWidget:
        md_bg_color: 0, 0, 1, 1
        size_hint: .5, .3
        pos_hint: {"center_x": .5, "center_y": .5}
        focus_color: 1, 0, 1, 1
        unfocus_color: 0, 0, 1, 1

        MDLabel:
            text: "Label"
            theme_text_color: "Primary"
            pos_hint: {"center_y": .5}
            halign: "center"
'''


class FocusWidget(MDBoxLayout, RectangularElevationBehavior, FocusBehavior):
    pass


class Test(MDApp):
    def build(self):
        return Builder.load_string(KV)


Test().run()
```

少し公式マニュアルのサンプルコードと改変があるのでご注意ください。

全体を通して見てみると、それほど難しくはないかと思われます。どんな変更が
あったかというと、主にkv側のFocusWidgetの部分になりますね。少しこのまま
だとどんな変更があったのか分かりにくいので、抜粋して見てみます。

```diff_python
KV = '''
MDScreen:
-   md_bg_color: 1, 1, 1, 1

    FocusWidget:
        
        size_hint: .5, .3
        pos_hint: {"center_x": .5, "center_y": .5}
        md_bg_color: app.theme_cls.bg_light
+       focus_color: 1, 0, 1, 1
+       unfocus_color: 0, 0, 1, 1

(略)

```

まずこうしたことによってどんなことになったのかを端的に言うと、マニュアルの
focus/defocus(サンプルコードの下あたり)の部分を取り入れたのと、初期表示
から青色を表示したことになります。

focus/defocusのところはマニュアルからでも分かるように、単にフォーカスあり
なしで色を変更しているだけになります。MDScreen配下のmd_bg_colorプロパティ
を削除した理由は、FocusWidgetのmd_bg_colorプロパティを見せるためになり
ます。

さらに理由を言うと、もともとのサンプルコードはこのプロパティを敷くことによって
また別の意味を持たせていたというのはあるのですが、focus/defocusを導入すること
によってFocusWidgetのmd_bg_colorが適用されないような見た目になったためです。
まぁ、何言ってんのという方は実行結果を見てもらえればと思います。

あとは、触れてはいませんがTestクラスの方で、ダークテーマの設定を削除している
こともあります。

最後にFocusWidgetクラスですが、以下のようにFocusBehaviorクラスを継承する
ことによって、フォーカス機能が使用されるようになります。

```python
class FocusWidget(MDBoxLayout, RectangularElevationBehavior, FocusBehavior):
    pass
```

### 実行結果

あれこれ言っても、分かりにくいこともあるかと思いますので、どうなったか結果の
方を見てみましょう。論より証拠を徹底的に追い求めたいと思います。

![203.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/2873f82d-7539-923b-5deb-5d3a73a22e97.gif)

最初の方を見ると、focus/defocusされる矩形の部分は白色で塗られていることが
分かります。GIFファイルとかだと見えにくいな。これは動かして試してもらうとです。
この部分がmd_bg_colorプロパティを削除したことも関わっていますね。

その後、focus/defocusを繰り返すと、決めた色が選択されることも分かるかと思い
ます。

### API - kivymd.uix.behaviors.focus_behavior

#### class kivymd.uix.behaviors.focus_behavior.FocusBehavior(**kwargs)

最後にまとめに入る前に、使用したAPIについてまとめておきます。

`on_enter`

> Called when mouse enters the bbox of the widget AND the widget is visible

`on_leave`

> Called when the mouse exits the widget AND the widget is visible

直接的には使用されていませんが、focus/defocusされるときに呼ばれるイベント
プロパティになりますね。裏ではこういうのが使われているよというのは知っておき
たいところ。

`focus_color`

> The color of the widget when the mouse enters the bbox of the widget.

> focus_color is a ColorProperty and defaults to None.

`unfocus_color`

> The color of the widget when the mouse exits the bbox widget.

> unfocus_color is a ColorProperty and defaults to None.

今日実際に使ったプロパティになります。ColorPropertyしか受け付けていません。

## まとめ

さて、いかがだったでしょうか。

よくよく考えてみると、少しモバイルアプリというよりかはデスクトップアプリの
方が使われるのかなと思いましたが、デスクトップアプリを開発するとなるとより
リアクティブなアプリになれる可能性を持っています。モバイルはあまり候補に
上がってこないかな。

ですが、使用するとしてもそれほど開発コストが少なく(というかもともとKivyMD
は開発コストが少ない)、障害となるようなこともないような気がしてます。デスク
トップアプリを開発するときは取り入れてはいかがでしょうか。

ということで、今週はここまで！来週はというと、少し先週で触れていたかもしれま
せんが、とうとうファーストアップのお出ましです。て言ってもそんなに大したもの
ではないし、完成度もそんなにというのはあるのですが。。すみません、業務が忙し
くて、という言い訳をしておきます。

一旦、今日はこの辺で。それでは、ごきげんよう。

## 参照

> Behaviors » Focus
> https://kivymd.readthedocs.io/en/latest/behaviors/focus/