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

年もおしせまり、何かと忙しい頃となりました。
>linked by 手紙の書き方 > 手紙の基本 > 時候の挨拶

https://www.midori-japan.co.jp/letter/letter-manners/jikouaisatsu/4328

さて今年も残り1ヶ月を切りましたが、いかがお過ごしでしょうか。
忙しい時期にはなると思うのですが、小生、残念ながら年末に忙しくなるという
境遇に至ったことがありません。。

なので、この時期がなぜ忙しいのかだとか、どの業界などがどういう風に忙しい
のかなど分からずここまでやってきました。自分の組織ではこういう理由で忙し
いんだよ!というようなコメントを頂けるととても嬉しいです。

前置きを一旦を置いておいて、今週はというとBehaviors章の2回目となります。
今日は今までよく出てきたElevationを取り扱おうと思います。それでは参ります。
※先に言っておくとElevation篇は2週連続としたいと思います

## Elevation

冒頭は丁寧に始めていますが、いつものごとくマテリアルデザインのリンクは
ぶっきらぼうにスルーします。興味のある方は呼んでいただければと思います。

冒頭にはこう書かれています。

> Elevation is the relative distance between two surfaces along the z-axis.

この先でもどうせ依頼することにはなるだろうと思うので、もう依頼を投げよう
と思います。投げてみたらこういう結果が返ってきました。

> 標高とは、Z軸に沿った2つの面の相対的な距離のこと。

本当に機械翻訳ということは言い得て妙ということでしょうか。無駄なことは
一切話すことはありません。そういうことも魅力のうちなんですけどね。

ここでの標高は、仮想的なということになるでしょうか(当たり前)。こうい
った現実にはないが、仮想的にあるように見せるというのはマテリアルデザ
インの本質と言っても過言ではないように思えます。

さらに説明は続きます。

> There are 5 classes in KivyMD that can simulate shadow:

> 1. FakeRectangularElevationBehavior
> 2. FakeCircularElevationBehavior
> 3. RectangularElevationBehavior
> 4. CircularElevationBehavior
> 5. RoundedRectangularElevationBehavior

影をシミュレートするクラスはこのように用意したぜ!とありますね。この
後にこれらが出てくるのは間違いない事実になると思われます。

さらに説明は続きます。今日は多いですね。

> By default, KivyMD widgets use the elevation behavior implemented 
> in classes FakeRectangularElevationBehavior and FakeCircularEleva-
> tionBehavior for cast shadows. These classes use the old method 
> of rendering shadows and it doesn’t look very aesthetically pleasing. 
> Shadows are harsh, no softness:

これも依頼してみます。するとこう返ってきました。

> デフォルトでは、KivyMDのウィジェットは、FakeRectangularElevationBehaviorと
> FakeCircularElevationBehaviorクラスで実装されているエレベーション・ビヘイビアを
> キャストシャドウに使用します。これらのクラスは、影をレンダリングする古い方法を使用して
> おり、それは非常に美しい外観を持っていません。影は厳しく、柔らかさがありません。

なかなかなお仕事をされていますね。ですが、完璧な翻訳というのはなかなか
難しいのではとどうしても思ってしまいます。それはどうでもよくて、この2つは
デフォで使われているというのは覚えておきたいところです。

さらにさらに説明は続きます。これも続けて依頼をしてみます。DeepL君も今月は
忙しそうだ。

> [依頼内容]
> The RectangularElevationBehavior, CircularElevationBehavior, 
> RoundedRectangularElevationBehavior classes use the new shadow 
> rendering algorithm, based on textures creation using the Pillow 
> library. It looks very aesthetically pleasing and beautiful.

> [依頼結果]
> RectangularElevationBehavior、CircularElevationBehavior、Rounded-
> RectangularElevationBehaviorクラスは、Pillowライブラリを使って作成した
> テクスチャをベースにした、新しいシャドウレンダリングアルゴリズムを使用してい
> ます。非常に審美性に優れた美しい仕上がりになっています。

ということになりました。どうやら、これらを使うと綺麗になるぜ!ということが
分かりますね。

もう終わったかなと思うと、まだあるようです。でも今度は注意喚起のようですね。

:::note warn
Remember that RectangularElevationBehavior, CircularElevationBehavior, 
RoundedRectangularElevationBehavior classes require a lot of resources 
from the device on which your application will run, so you should not 
use these classes on mobile devices.
:::

うーん、これも依頼を投げてみましょう。

> RectangularElevationBehavior、CircularElevationBehavior、RoundedRect-
> angularElevationBehaviorクラスは、アプリケーションを実行するデバイスに多くの
> リソースを必要とするため、モバイルデバイスではこれらのクラスを使用しないようにして
> ください。

ええぇー、とつい思ってしまいました。まぁ、でもそれだけ重い処理になっているのかなと
思いました。しばらくは、デスクトップアプリ用ということになるでしょうか。あ、でも
試しに実装してみてどれだけ負担になっているか確認してみるのもよさそうですね。メモメモ。

### Deprecated Shadow vs. New Shadow

というわけでようやくサンプルに入れるようです。一旦はコードを見てみるしか話になりません
ので、さっそく見てみようと思います。
※節のタイトルなんかは適当に付けております

```python:DeprecatedShadowAndNewShadow.py
from kivy.lang import Builder
from kivy.uix.widget import Widget

from kivymd.app import MDApp
from kivymd.uix.card import MDCard
from kivymd.uix.behaviors import RectangularElevationBehavior
from kivymd.uix.boxlayout import MDBoxLayout

KV = '''
<Box@MDBoxLayout>
    adaptive_size: True
    orientation: "vertical"
    spacing: "36dp"


<BaseShadowWidget>
    size_hint: None, None
    size: 100, 100
    md_bg_color: 0, 0, 1, 1
    elevation: 36
    pos_hint: {'center_x': .5}


MDFloatLayout:

    MDBoxLayout:
        adaptive_size: True
        pos_hint: {'center_x': .5, 'center_y': .5}
        spacing: "56dp"

        Box:

            MDLabel:
                text: "Deprecated shadow rendering"
                adaptive_size: True

            DeprecatedShadowWidget:

            MDLabel:
                text: "Doesn't require a lot of resources"
                adaptive_size: True

        Box:

            MDLabel:
                text: "New shadow rendering"
                adaptive_size: True

            NewShadowWidget:

            MDLabel:
                text: "It takes a lot of resources"
                adaptive_size: True
'''


class BaseShadowWidget(Widget):
    pass


class DeprecatedShadowWidget(MDCard, BaseShadowWidget):
    '''Deprecated shadow rendering. Doesn't require a lot of resources.'''


class NewShadowWidget(RectangularElevationBehavior, BaseShadowWidget, MDBoxLayout):
    '''New shadow rendering. It takes a lot of resources.'''


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


Example().run()
```

さてどこから触れようかとマウスを行ったり来たりしていますが、まずは前提
知識を満たさないわけにはいきません。今回のElevation以外に使われている
KivyMDのコンポーネントだとかウィジェットだとかは、以下リンクに詳細を
書いているので、リンクもしくは該当マニュアルをご覧頂ければと思います。

https://qiita.com/virty/items/d5fa0a529912e6b0beb0

https://qiita.com/virty/items/4302b275e91ea3cf9717

※これ↑はどちらでもよいかも

https://qiita.com/virty/items/8475f11f314b76af21e1

ということで、これを見終わった方あるいはすでに知識のある方だとそれほど
難しくないことが分かられると思います。しかし、カスタムレイアウトとかも
使っているので、少し直感的とは言いにくいと思いちょっとだけピンポイント
で触れ込んでいきたいと思います。

まず、それぞれ2つのクラスをフォーカスしてみたいと思います。先程のコード
からピックアップしてみます。

```python
class DeprecatedShadowWidget(MDCard, BaseShadowWidget):
    '''Deprecated shadow rendering. Doesn't require a lot of resources.'''


class NewShadowWidget(RectangularElevationBehavior, BaseShadowWidget, MDBoxLayout):
    '''New shadow rendering. It takes a lot of resources.'''
```

プロパティとかもないので、ここは比較的シンプルかと思われます。Elevation
のことで言うと、2つの違いは継承元のクラスがRectangularElevationBeha-
viorがあるかどうかということになります。

まぁ、他ではMDCardとMDBoxLayoutの違いというのもあるのですが。。これは
統一してほしいなというのはあるのですが、現状の仕様で表示できないというのが
あれば仕方のないところではあります。

逆に言えば、共通するものでいうと、BaseShadowWidgetというのもありますね。
これはどんなものかというと、抜粋したものを以下に再掲しておきます。

```python
KV = '''

~

<BaseShadowWidget>
    size_hint: None, None
    size: 100, 100
    md_bg_color: 0, 0, 1, 1
    elevation: 36
    pos_hint: {'center_x': .5}

~

'''
```

Elevation以外のプロパティで特徴付けられるならば、背景色に青色を指定(md_
bg_colorプロパティ)しているくらいになりますでしょうか。あとはelevation
プロパティはもちろん、センター配置してサイズを決めているくらいになります。
(ほとんど言った)

端折ってはいますが、このクラスはWidgetクラスを継承しているくらいで特に
変わったことはありません。これだけ見ていると、このコードが何をしたいのか
は分かってくると思います。

### 実行結果

ということで、結果がどうなったか見たいところでもあるので、さっそく実行
結果を見てみましょう。まぁマニュアルの方でもあるんだけどね。。

![198.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/d70e87dc-9a13-9e58-f123-337e5bdaddee.png)

左がいわゆる「非常に美しい外観を持っていません」ということになりますね。
今まではこればっかり見てきたのでなんとも思いませんでしたが、右の「非常に
審美性に優れた美しい仕上がり」のものを見ると確かにその様子が伺えるかと
思われます。少し左は不均一でくどい(言い過ぎ)ように思えます。

## まとめ

はい、ということで今日はここまでとしたいと思います。
なんか結果の方で悪く言って終わったので、小学校のとき友達とケンカして帰る
日の夕方(どういうこと)みたいな気持ちにはなってますが。。

少し触れただけでまとめも何もないですが、いかがだったでしょうか。少しでも
Elevationなんかわかるぞ!となりましたらこの上なく幸せです。あとは先行して
見るぞ!となった方は、代わりに来週投稿頂けたら、またこの上なく幸せです。(甘え)

ということで今週はさっぱりした触れ込みになりましたが、一旦ここで終わりたい
と思います。来週も(投稿者がいなければ)お楽しみに〜。

それではごきげんよう。

## 参照

> Behaviors » Elevation
> https://kivymd.readthedocs.io/en/latest/behaviors/elevation/

> DeepL 翻訳ツール
> https://www.deepl.com/ja/translator