kivyMDチュートリアル其の参什弍 Components - Toolbar篇

はろー、Qiita(そろそろこの挨拶ネタ切れ)。いかがお過ごしでしょうか。

今週は特に暑かったですね。夏が終わらないのではという思いもありましたが、来週
からは気温も落ち着かれることを祈るばかりです。まぁ、こればっかりは自然のこと
なのでどうすることもできないというのはありますが。

コンポーネンツ章も残りわずか2回となりました。と言いたいのですが、まだ残りまく
っていますよね。はい、飛ばしまくったらいつの間にか1週目は残りわずかとなりま
した。今日はToolbar篇となりますが、来週のTooltipが終わったときには念願の
バージョンアップを図ろうと思います。どんな機能が改善されたかわくわくしますね。

ということで、今週もというか今日も暑いですが、元気にやっていきましょうー。
えいえい、えいーーー。

## Toolbar

暑いので、マテリアルデザインのリンクは飛ばします・・
すみません、嘘ですw

飛ばすのは恒例行事でしたね。失礼しました。
まぁ、今回ようやく触れ込むことが出来たという次第になります。これまでも何回か
出てきましたね。アプリの顔とも呼べるコンポーネントと言っても過言ではない、大事
な大事なコンポーネントとなります。

最悪なくてもアプリは作れるっちゃ作れるとは思いますが、アプリの受付・窓口係とも
なるコンポーネントなので、代替品を作ろうとなると結構設計が難しくなりそうです。
特にこれといって理由などなければ、置いておきたいものです。

で、続けてマニュアルには以下のように記載があります。

> KivyMD provides the following toolbar positions for use:
> ● Top
> ● Bottom

今までは上側(Top)によく出現されていましたが、実は下側(Bottom)にもあるのですね。
私もこれは知りませんでした。今日はここも見ていきましょう。

ということでさっそくTopから入っていきますね。

### Top

さっそくコードに入っていきたいのですが、マニュアルはオプションごとに説明が分かれて
います。ここでは、触れ込みコストを下げることとコードの省エネ化(意味不明)を図るために
これらをまとめていきたいと思います。あ、いや、全然そんな、楽したいだなんて、あはは。
そそそんなこと、思っては、ななないですよ。

ごほん、ということで改めまして、何をまとめているのかを以下に記載しておきます。簡単に
言えばTopからBottomを除く間のオプションを全てまとめたということになりますね。

* Add left menu
* Add right menu
* Add two item to the right menu
* Change toolbar color
* Change toolbar text color
* Shadow elevation control

上記は全てサンプルコードに付け加える形となっていますね。

ということで、さっそくコードに入っていきましょう。

```python:xxxii/toolbar.py
from kivy.lang import Builder

from kivymd.app import MDApp

KV = '''
MDBoxLayout:
    orientation: "vertical"

    MDToolbar:
        title: "MDToolbar"
        left_action_items: [["menu", lambda x: app.call()]]
        right_action_items: [["dots-vertical", lambda x: app.call_kebab()], ["clock", lambda x: app.call_clock()]]
        md_bg_color: app.theme_cls.accent_color
        specific_text_color: app.theme_cls.primary_color
        elevation: 10

    MDLabel:
        text: "Content"
        halign: "center"
'''


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

    def call(self):
        print("left action from hamburger menu!")
    
    def call_kebab(self):
        print("right action from kebab menu!")

    def call_clock(self):
        print("right action from clock menu!")

Test().run()
```

特に今回は取り止めもなく、新しいものというとMDToolbarのあたりになります。
なので、今回はImport文とクラス側は省略していこうかと思います。

で、今回あたらしく登場したのはMDToolbarのオプションプロパティのあたりに
なりますね。1つ1つ見ていきましょう。

まずtitleは触れなくても良いと思いますが、念のため。ツールバーに記載される
テキストのタイトルになります。

left/right_action_itemsはマニュアルの「Add left menu」と「Add right
 menu/Add two item to the right menu」に該当します。右側のメニューは
1つだけでなく2つ定義していますね。また、マニュアルにはNoteとして以下のように
記載がありますが、この形式だと動かないことも確認済みです。あくまで参考程度に。

:::note
The callback is optional. left_action_items: [["menu"]] would 
also work for a button that does nothing.
:::

あとは、オプションのコールバックメソッドにクラス側で実体として持っている
メソッドを指定しています。具体的な中身は見てもらえれば分かる内容ですが、
単にprint文を置いているだけになります。

続いて、md_bg_colorプロパティですが、こちらはマニュアルとして「Change 
toolbar color」に該当します。プロパティとしては初見とかではないので、
何を指定するかなどは分かられる方は多いのではないでしょうか。まぁ、分から
なくともAPIの方で詳細は記載します。

続いて、specific_text_colorプロパティですが、こちらはマニュアルとして
「Change toolbar text color」に該当します。こちらも指定はmd_bg_col-
orとよく似ていますね。詳細はAPIの方で。

最後にelevationですが、「Shadow elevation control」がマニュアルとして
該当します。こちらも顔馴染みとも言えるかもしれません。一言で言えば影の高度。
一文字でいうならば影ですが、ちょっと切り落とししすぎかな。

ということで以上となります。あ、あと言い忘れていましたがプロパティの値としては
マニュアルからそう変わりはありません。強いていうなら、テキストの色を少し変えて
いるかなという次第です。ではそのあたりも見ていきましょう。

#### 結果

さて、お待ちかね。実際に動かしてみたものを見てみましょう。今回は画像になります。

![145.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/0589ffbf-434c-1332-ea9b-eaaebc0ee67c.png)

一気に今まで見てきたものから印象は変わりますよね。子供向きのアプリ感が増して
いるような気もしますが、自分だけかな。

で、あとは実際にメニューボタンを押すとどうなるかということを、ターミナルの挙動を
見ながらキャプチャしたものが以下になります。

![146.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/3fdd7a50-4d28-6061-9a29-e724b6ab911b.png)

押したことがちゃんと反映されていますね。本格的にアプリを作るとなると、イベントを
結びつけることをしていくのだろうということが予想されます。サイドメニューを開くと
いうことやらメニューを開くということやらですね。

### Bottom

さて今度は下部にツールバーを置くにはどうすればよいのだ?ということをやっていきます。
あまり、実際のアプリではなかなかお目にかかる機会はないですが、どのようなものになる
のかも必見なところです。

この節でも同様にサンプルコードをベースに使用したオプションなどを付け加える方式で
やっていきたいと思います。ということで、さっそくコードからレッツラゴ。

```python:xxxii/toolbar_bottom.py
from kivy.lang import Builder

from kivymd.app import MDApp

KV = '''
MDBoxLayout:

    # Will always be at the bottom of the screen.
    MDBottomAppBar:
        md_bg_color: 0, 1, 0, 1

        MDToolbar:
            title: "Title"
            icon: "git"
            type: "bottom"
            left_action_items: [["menu", lambda x: x]]
            on_action_button: app.call(self.icon)
            mode: "free-end"
            icon_color: 0, 1, 0, 1
'''


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

    def call(self, icon):
        print("icon is : " + icon)


Test().run()
```

今回もImport文とクラス側は省略します。

さて、使用方法から入りますと、今回は単にMDToolbarを使用するだけではダメ
ということになります。再度Usageの該当部分を抜粋することとします。

```python
(略)

KV = '''
MDBoxLayout:

    # Will always be at the bottom of the screen.
    MDBottomAppBar:

        MDToolbar:
            title: "Title"
            icon: "git"
            type: "bottom"
            left_action_items: [["menu", lambda x: x]]
'''

(略)
```

というように、MDToolbarの上位にMDBottomAppBarウィジェットを配置しなけ
ればなりません。これを置かなければところどころ、おかしい挙動になります。試し
にやってみたところ、Usageでは中央配置されるボタンが出現されないということが
起こりました。

で、あとは先述したコードで使用したオプションですが目新しいものはicon、type、
on_action_button、mode、icon_colorプロパティになります。これらのプロパ
ティで、type以外は全てBottom配置されるときに出てくる、ActionButton(造語)
に関連するプロパティとなります。

icon/icon_colorだとか、on_action_buttonとかはButton篇とかでも関連する
内容が出てくるので、こちらもマニュアルや以下リンクが参照してもらえればと思い
ます。on_action_buttonなどはkivyにおけるon_releaseコールバックメソッド
と似たようなものと思ってもらえればと思います。

https://qiita.com/virty/items/29d792d5ecf4ad0f86be

ここに使っているものも以下に列挙していきます。と言っても、マニュアルからそれ
ほど使い方は変えてはいません。

* Event on floating button
* Floating button position
* Custom color

あとは、マニュアルを読み比べるかこの後にでてくるAPIのところを先に見るかを
しておいてください。というか暑すぎてバテました・・・まぁ、こんな日がたまに
あってもよい、、、ダメですよね。。まぁこればっかりは勘弁のほどを。。

#### 結果

ということで逃げるように、実行結果の方に入っていきたいと思います。実際に見て
確かめたほうが理解の定着に役立ちそうな気はします。

![147.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/5cb05085-3427-f241-2813-2565c951f558.png)

キャプチャの方も、省エネ化します。これにはエネゴリ君もニッコリ。

はい、すみません。今ゼーゼー言いながら、あ、ごめんなさい、それは言いすぎま
した。でも結構HP3くらいの状態で書いているので、少し省エネ化させて頂きます。

ということはどうでもよくて、下部のツールバーとしては上のキャプチャのように
なります。右下あたりのなんか浮いているボタンがアクションボタンで、それを連打
すると左のターミナルのようになります。あ、これは上記記載ないですが、modeプロ
パティで"free-end"を指定したのでこのようになります。中央か右端に配置か、それ
に加えツールバーにくっつけるか少し浮かせるかの4パターンが選択できます。

あとは、注意点としては、MDBottomAppBarが持つmd_bg_colorプロパティですが、
有効化されなかったことが挙げられます。これも次回の確認事項として列挙しないと
ですね。

[追記 2021/8/28 22:28]

マニュアルでは以下リンクも見てよね、という案内もあります。
結構ウィジェットの切り替えとかも参考になるので、興味のある方はこちらを覗くと
結構kivyMD力が上がるかもしれません。ここでは、スタミナ切れにより省略をさせて
もらえれば本望です。

[Components-Bottom-App-Bar](https://github.com/kivymd/KivyMD/wiki/Components-Bottom-App-Bar)

### API - kivymd.uix.toolbar.toolbar

おいおい、「MDToolbar with Menus」と「Tooltips」が残っているだろうが！と
思われるかもしれませんが、これはバテて端折ったからではありません。単に動かなか
っただけになりますね。うん、これはしょうがない。バージョンアップしたときのお楽
しみということになります。はぁ、やることがどんどん増える・・

ということで今日使用したAPIに入っていきます。コメントなどもところどころないかも
ですが、悪しからずでお願いします。

#### class kivymd.uix.toolbar.toolbar.MDToolbar(**kwargs)

`on_action_button`

> Method for the button used for the MDBottomAppBar class.

bottom配置するときに使うといった認識をしておいた方がよさそうですね。

`left_action_items`

> The icons on the left of the toolbar. To add one, append a list like the following:

> left_action_items: [`'icon_name'`, callback, tooltip text]

> where ‘icon_name’ is a string that corresponds to an icon definition, 
> callback is the function called on a touch release event and tooltip text` 
> is the text to be displayed in the tooltip. Both the ``callback and tooltip 
> text are optional but the order must be preserved.

> left_action_items is an ListProperty and defaults to [].

左側でボタンなどのアイテムを配置するときに使用します。
なにやら、長文が記載されています。ここはツールチップが使用できなかったのであくまで
参考程度にしておいたほうが良さそうです。

`right_action_items`

> The icons on the left of the toolbar. Works the same way as left_action_items.

> right_action_items is an ListProperty and defaults to [].

今度は右側で配置するときですね。使用としては左側配置と変わらないようです。

`title`

> Text toolbar.

> title is an StringProperty and defaults to ‘’.

いわずもがなーのところです。

`anchor_title`

> Position toolbar title. Available options are: ‘left’, ‘center’, ‘right’.

> anchor_title is an OptionProperty and defaults to ‘left’.

へぇータイトルの位置も変更できるのですね。デフォは左なので、今回は左配置されて
いました。

`mode`

> Floating button position. Only for MDBottomAppBar class. 
> Available options are: ‘free-end’, ‘free-center’, ‘end’, ‘center’.

> mode is an OptionProperty and defaults to ‘center’.

これはbottom配置するときのオプションですね。デフォはcenterとなります。

`icon`

> Floating button. Onle for MDBottomAppBar class.

> icon is an StringProperty and defaults to ‘android’.

これもbottom配置するときのプロパティとなります。デフォはandroid君が配置
されます。

`icon_color`

> Color action button. Onle for MDBottomAppBar class.

> icon_color is an ColorProperty and defaults to [].

これもいわずもがなーのところです。有効化はされていましたね。

`type`

> When using the MDBottomAppBar class, the parameter type must be set to ‘bottom’:

> MDBottomAppBar:

> MDToolbar:
> type: "bottom"

> Available options are: ‘top’, ‘bottom’.

> type is an OptionProperty and defaults to ‘top’.

これも長いは長いですが、bottom配置するときの付き物ですね。top配置するときに
指定は必要ないかと思われます。

#### class kivymd.uix.toolbar.toolbar.MDBottomAppBar(**kwargs)

> Float layout class. See module documentation for more information.

なるほど、FloatLayoutを継承しているのですね。気になる方は以下ページも参考情報
となります。

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

`md_bg_color`

> Color toolbar.

> md_bg_color is an ColorProperty and defaults to [0, 0, 0, 0].

こちらについては有効化されていなかったので、参考情報として。

## まとめ

終わったー！
というふうに意気揚々としてたら、なんだかHPも10くらいに回復してきました。
まぁもともといくらくらいあるんだということですが、おそらく50くらいですかね。
結構さきほどまではグロッキー状態でした。

まぁそんなどうでもよいことは置いておいて、いかがだったでしょうか。
結構顔馴染みのあるコンポーネントでしたが、意外と知らない情報がありましたね。
これであなたもToolbarマスターになれるかも。

ということで今日はここまで！来週は最後ッ!とはならないTooltip篇となります。
結構サンプルとしては簡素化されているので、追加として隠しキャラ(コード)も
登場するかも。お楽しみに！

それでは、ごきげんよう。

## 参照

> Components » Toolbar
> https://kivymd.readthedocs.io/en/latest/components/toolbar/

## 番外編

少し時間を置いたらHPが40くらいまで復活したので、やりたかったことをやって
みました。簡単に述べると、bottom配置したときに以前やったTapTargetView
を組み合わせるとどうなるんじゃいという実験ですね。

これも実際に見た方が早いので、やってみたキャプチャを載せておきます。今度は
動画キャプチャになります。

![148.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/303996dd-8036-02fc-73d2-769bfecf61da.gif)

見事にダメでしたねw
じゃ、なんで載せたのよってツッコミが入りそうですが、一応アンチパターンとして
共有しておきました。やっぱりTapTargetViewウィジェットはボタンを指定した方
がよさそうです。円形の表示にかけて計算だとかが狂ってくるのですね。というか
仕様で書かれてなければ良いけど・・・

ということで現場からは以上です！良い子はマネしないでね！