kivyMDチュートリアル其の肆 Themes - Color Definitions篇


さあ、今週もやってまいりました。kivyMDチュートリアルのお時間です。
今週初めくらいから爆弾低気圧が来た影響でHPが2くらいしか残ってないですが、
みなさんの体調はどうでしょうか。気持ちだけはめげずに、今日も元気にやって
いこうと思います。# 少し今日は省エネモードかも

Color Definitions

冒頭では前々回くらいからあるように色の決まりごととか見ておいてねという
案内から始まってます。ここではMaterialDesignタグを入れてますが、ほとんど
詐欺のような形で触れません。興味ある方は見ておいてくださいということで次に
進んでいこうと思います。

See also

Material Design spec, The color system
https://material.io/design/color/the-color-system.html

Material Design spec, The color tool
https://material.io/resources/color/#!/?view.left=0&view.right=0

ですが、ここもさらっと行こうと思ったんですけど上記The Color toolは面白いと思ったので
少し紹介しておきます。これはあらかじめUIのフレームとかは定義されていましたが、色のテーマ
とかをカスタム含め好きな色を決めてアプリのイメージを決められるツールとなっています。

適当に触ってみただけなのですが、意外とそれっぽく作れる感じはあります。
キャプチャは下の通りです。

色のセンスねーなとかいうツッコミはなしの方向でww
あくまで適当に選んだだけなので。

これを実際に使ってみたいなーという方には朗報です。
なんと色のテーマを定義したファイルをエクスポートすることも出来ます。
種類としてはAndroid, Swift, CodePenと3種類で残念ながらkivyMDは
ありませんでしたー泣。まぁ、こだわりたいという方はカスタムかもしくは
今日紹介する形で落としどころを決めましょう。

Material colors palette to use in kivymd.theming.ThemeManager.
colors is a dict-in-dict where the first key is a value
from palette and the second key is a value from hue.
Color is a hex value, a string of 6 characters (0-9, A-F) written in uppercase.

For example, colors["Red"]["900"] is "B71C1C".

kivymd.theming.ThemeManagerで使用するマテリアルカラーパレット。
色はdict-in-dictで、最初のキーはパレットからの値で、2番目のキーは色相からの値です。
色は16進値で、大文字で書かれた6文字(0-9、A-F)の文字列です。

たとえば、colors ["Red"] ["900"]は "B71C1C"です。

と、いきなり翻訳を依頼しましたが今日のテーマとして非常に重要なので
このkivymd.theming.ThemeManagerの仕様については覚えておきましょう。
テストがあったら絶対に出るところでしょう。

API - kivymd.color_definitions

kivymd.color_definitions.colors

Color palette. Taken from 2014 Material Design color palettes.

To demonstrate the shades of the palette, you can run the following code:

とまぁ、さっそくkivymd.color_definitionsのAPIの説明に入ってますが、
カラーパレットについては2014年にマテリアルデザインが公表されてそれをもとに
使うからねーという説明になっています。あとはコードの説明に入っていってます。

省略

省略かい!とツッコミが出そうですが、なぜか動きませんでしたー!w
結構ところどころ動かないサンプルがあるので困ったものです。
# 解析しろやと言われそうですがそんな技術力はどこにもありません
動いてたら説明が少ないのでコードの説明とかも交えようかなと思ってた
のですが、今日は動かなかったので一部だけ。

class Palette(MDApp):
    title = "Colors definitions"

  省略

    def on_tab_switch(self, instance_tabs, instance_tab, instance_tabs_label, tab_text):
        self.screen.ids.box.clear_widgets()
        for value_color in colors[tab_text]:
            self.screen.ids.box.add_widget(
                ItemColor(
                    color=get_color_from_hex(colors[tab_text][value_color]),
                    text=value_color,
                )
            )

  省略

今日の肝で先ほどテスト出るよといったところになりますが、
さっそくマテリアルカラーパレットが出てきていますね。

まず、メソッドとしてはタブの切り替え専用メソッドを宣言して、そこでタブを切り替えたときに
色を変えれるようにロジックを組んでいます。メソッドの引数の説明とかはMDTabsを触ったときにまた改めて。
初めにself.screen.ids.box.clear_widgets()で切り替え時にリセットされるようにしているのかな。
ここでids.boxと見慣れないものが出てきましたが、このようにすることでkvファイルで決めておいた
UIパーツとバインディングして中身をいじれるようになっています。これからkivy・kivyMD関係なく
このような形がよく出てくるので覚えておいて損はないです。よく見るとdemoで定義したkvレイアウトでは、
以下のようにScrollViewが宣言されています。

demo = '''
<Root@BoxLayout>
    orientation: 'vertical'

    MDToolbar:
        title: app.title

    MDTabs:
        id: android_tabs
        on_tab_switch: app.on_tab_switch(*args)
        size_hint_y: None
        height: "48dp"
        tab_indicator_anim: False

    ScrollView:

        MDList:
            id: box
(省略)

上記のようにkv側でもid: boxとちゃんと宣言されていますね。他にもMDTabsとかでもid: android_tabs
とあったりパーツを宣言する上ではこのような形がよく出てきます(kivyとかkivyMD関係なく)。

んで、メソッドの方に戻りますが、そのあとはfor value_color in colors[tab_text]:とイテレートして
同色の色相を取り出して、その色が反映されるようItemColorオブジェクトにカラーパレットを流し込んでいます。
このItemColorオブジェクトは色を16進数値にしないとちゃんと反映されないのかな。んでそのItemColorって
なんなのよっていうと、kv側で以下のように定義されていますね。

demo = '''

(省略)

<ItemColor>:
    size_hint_y: None
    height: "42dp"

    canvas:
        Color:
            rgba: root.color
        Rectangle:
            size: self.size
            pos: self.pos

    MDLabel:
        text: root.text
        halign: "center"

どうやらItemColorというのはcanvasとMDLabelで構成されているようです。
MDLabelはこれまでも出てきているしで、説明するまでもないですがまた機会が
あればそこで。canvasはもともと図形描画用のウィジェットなのですが、ここでは
巧みにそのウィジェットを使用しています。そうしてサンプルのような色付きの矩形を
表現できるようにしています。あ、あとcanvasの詳しい仕様は以下にて。

Canvas
https://kivy.org/doc/stable/api-kivy.graphics.instructions.html

ここまでくると最初から説明した方がいいかもですね(出来ないけど)。
またまた、メソッドの方に戻りますがこれらが

           self.screen.ids.box.add_widget(
                ItemColor(
                    color=get_color_from_hex(colors[tab_text][value_color]),
                    text=value_color,
                )
            )

をよく表しています。要はkv側で決めておいたパーツにこれらを流し込みたかったのですね。
最後に作ったItemColorをMDList(box)に流し込んで表示するということをやっていました。
とまぁ、コードの説明はこの辺りで。あとはPropertyとかon_start側のon_tab_switch(
呼び出し側)とかも気になるところですが、またUIパーツで触るしで今度の機会ということで。
自分の気になるところでいうと、Factory.Root()とScreenオブジェクトでscreenを生成
するのは何が違うんだろうと思ってしまいます。# 自分へのメモ

これでいったん、コードの方は手じまいということで。
じゃぁねーと終わりたいところですが、まだ残っています。とほほ。

kivymd.color_definitions.palette = ['Red', 'Pink', 'Purple', 'DeepPurple', 'Indigo', 'Blue', 'LightBlue', 'Cyan', 'Teal', 'Green', 'LightGreen', 'Lime', 'Yellow', 'Amber', 'Orange', 'DeepOrange', 'Brown', 'Gray', 'BlueGray']

Valid values for color palette selecting.

これだけの色が選べるんだぜということですね。恩恵を授かりましょう。

kivymd.color_definitions.hue = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700']

Valid values for color hue selecting.

こちらは色相になります。これも恩恵を授かりましょう。

この2つは特に重要なので、おさらいをしておきます。
さっきのコード上のカラーパレットでいうとこのような形をしていました。

colors[tab_text][value_color]

このtab_textがまさにパレット(kivymd.color_definitions.palette)の選択で、value_colorが
色相(kivymd.color_definitions.hue)の選択なのでした。これらのことは大事なので、今日は3回ほど
言いました。

kivymd.color_definitions.text_colors

Text colors generated from light_colors. “000000” for light and “FFFFFF” for dark.

How to generate text_colors dict

コード上では触れられてませんが、テキストカラーも黒か白を選べるようです。
確かに色の組み合わせでは読みにくくなりますからね。コードは載せませんが、
一応こんな感じの使い方もできるぜというサンプルも挙げられています。

kivymd.color_definitions.theme_colors = ['Primary', 'Secondary', 'Background', 'Surface', 'Error', 'On_Primary', 'On_Secondary', 'On_Background', 'On_Surface', 'On_Error']

Valid theme colors.

テーマカラーを選べるようです。使い方は一向にわかりません。
メイン側でプロパティとして読み取るのかしら。

まとめ

さぁ、今回はいかがでしたでしょうか。
若干、消化不良感は否めませんがこれにて締めくくりたいと思います。
まぁ、動かなかったらしょうがないですよねーと自分を甘やかしておきます。
次回はiconについてになります。

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

参照

Color Definitions
https://kivymd.readthedocs.io/en/latest/themes/color-definitions/