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

ハロハロー、みなさん。お元気でしょうか。
私の方はまずまずといったところです。

ここ最近、手持ちのMacで日本語入力に悩まされていたのですが、以下ページの手順を
1通り試すと大幅に速度が改善されました。最初はBigSurにアップグレードした影響か
と思っていましたが、関係はなさそうでした。

https://qiita.com/kozimon/items/6abd7446a1f1908ee318
※ ここにてkozimonさんに謝辞を述べます

購入当初(と言っても中古)とまでは言わないですけども、それに近いところまで速度が
改善されました。確かにリンクで言われている通り、最初のセーフブートだけでも結構
改善されたことも確認しています。速度に悩まされている方は試されてみてはいかがで
しょうか。

## 今後の対応

さて、重要な発表になります。いや、ごめんなさい、それほど重要なことではないかもです。

先週から言っていた、kivyMDでの動かないところが結構出てきたという点ですね。
どれくらいあるかというと、先行調査で実際に動かしたところ以下のようになりました。

* MDSwiper(飛ばしたもの)
* Menu(先週報告済み)
* Navigation Drawer
* Navigation Rail
* Pickers(今日やる予定のもの)
* Selection
* Snackbar
* Tabs

結構ありますよね。ということで列記したもの動かないから飛ばしまーすみたいなことは
なるべくしたくないので、何かしら対応を考えます。といっても簡単な話で、上記は先週
もお伝えした通りでkivyMD 0.104.2へとアップデートをすれば済むようなものばかり
です。なぜかは先週のMenu篇でもお伝えしているのでそちら参照のほどを。

ということでまとめますが、一旦は現バージョン(0.104.1)で動くところまで進めます。
そのあとは、アップデートをしてから(これも方法はページに起こす予定です)上記リスト
で動かなかったところを再開していくという感じになるでしょうか。

まず今週から出来ることでいうと、Pickers篇を今日できるところまでやって(ん?)タグ
に新規として「kivyMD-v0.104.1」を追加するくらいでしょうか。

## Pickers

ということで、今週は先週お伝えしている通りでPickersを触れ込んでいきます。先に
言っておくと、Pickersは途中までしか動きませんw

まぁ、対応を新しくしてもMaterialDesignのリンクは触れ込んでいかないんですけど
もね。こればっかりはご了承ください。よく見たことはあると思います。これが出来ると
時間を扱いたい場合は大抵解決するような感じはあると思います。

kivyMDとしては以下の3つのPickerを持っていることになります。

* MDTimePicker
* MDDatePicker(×)
* MDThemePicker(×)

まぁ、×が付いているのでお察しかもしれませんが、MDTimePickerより後は動きません。
なので、今日についてはMDTimePicker単体の触れ込みになります。

### MDTimePicker

ということで見た方が断然早いので、Usageから結果まで一気に見てみましょう。

#### Usage

早速コードの方に移ります。

```python:xxiii:mdtimepicker.py
from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.picker import MDTimePicker

KV = '''
MDFloatLayout:

    MDRaisedButton:
        text: "Open time picker"
        pos_hint: {'center_x': .5, 'center_y': .6}
        on_release: app.show_time_picker()

    MDLabel:
        id: timelabel
        text: "Hello, world!"
        halign: "center"
'''


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

    def show_time_picker(self):
        '''Open time picker dialog.'''

        time_dialog = MDTimePicker()
        time_dialog.bind(time=self.get_time)
        time_dialog.open()
    
    def get_time(self, instance, time):
        self.root.ids["timelabel"].text = time.strftime("%H:%M")
    

Test().run()
```

少しマニュアルのままだとなんかつまらないなーと思い、少しだけ改変をしています。
ここも恒例行事ですが、分けて触れ込むこととします。

##### import文

ここはとくにとりとめもありません。
追加分としては、クラス側で必要になるのでMDTimePickerオブジェクトを指定して
います。

```python
from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.picker import MDTimePicker
```

##### kv側

ここは改変をおこなっているので、少し触れ込みたいと思います。

```python
KV = '''
MDFloatLayout:

    MDRaisedButton:
        text: "Open time picker"
        pos_hint: {'center_x': .5, 'center_y': .6}
        on_release: app.show_time_picker()

    MDLabel:
        id: timelabel
        text: "Hello, world!"
        halign: "center"
'''
```

まぁ、ここもとりとめもないっちゃないんですけどもね。もともとあるMDRaise-
Buttonはよいですかね。詳細を知りたい方は、以下のButtonをまとめたページを
参照ください。

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

ここでは中央少し上部に表示をさせて、on_releaseコールバックメソッドにTest
クラス側のshow_time_pickerを指定しています。こちらの方はTestクラス側の
方で触れます。

MDLabelもとりとめがありません。初期テキスト文字列に「Hello,world!」を
指定して、センター配置をしています。あと、idプロパティも後ほど分かることに
なります。MDLabelの方も詳細を知りたいという方は以下をご参照ということで。

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

##### Testクラス側

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

    def show_time_picker(self):
        '''Open time picker dialog.'''

        time_dialog = MDTimePicker()
        time_dialog.bind(time=self.get_time)
        time_dialog.open()
    
    def get_time(self, instance, time):
        self.root.ids["timelabel"].text = time.strftime("%H:%M")
```

buildメソッドの方はとくにとりとめもなく、まずはshow_time_pickerメソッド
ですね。こちらは先程kv側でも出た、MDRaiseButtonでもあったon_releaseプロ
パティのコールバックメソッドの実体でもあります。ここでは差分のあるものとして
以下の部分があります。

```python
time_dialog.bind(time=self.get_time)
```

これは何をしているのかというと、というか自分でもよくは分かっていないのですけど
もw、ダイアログが持つtimeプロパティのまたコールバックメソッドに後述するget_-
timeメソッドを指定しているということでしょうか。

そしてget_timeメソッドはというと、引数にinstanceとtimeを持つメソッドとなり
ます。んで、中は何をしているかというとおそらくdatetimeモジュール(引数のtime
が処理を受け持っている)を使い、書式文字列を引数としてそれに従い文字列をtimel-
abelのtextプロパティに代入をしています。これで、ダイアログで指定した時間をla-
belの方に表示が出来るというわけになります。

いやー、でも少し分かりにくいかなーと生意気ながら思いましたね。ちょっとget_time
メソッドの使い方も暗黙的で、マニュアルの方にも使い方などは「Binding method -
returning set time」でもありますけど、連携方法もないしで少し混乱しそうです。
マニュアルではそういう使い方をするんじゃないよということでしょうか。

まぁ、でも他のサイトというかYoutubeで引用した自分はなんとも言い難いんですけどねw
あ、ここでいう話でもないですが、今回は自分だけで完結したわけでもなくググっています。
参照としてはこちらになります。他のDatePickerとかもあるので、先にいろいろやってみ
たいというのがあれば、こちらはおすすめです。\# アップデート必要だけど

https://www.youtube.com/watch?v=n_bxsQo5tHs

## API - kivymd.uix.picker

結果の方に移るまえに、APIの紹介だけしておくこととします。

MDTimePickerの最後の方で、以下のように記載があったのでこちらも触れておきます。

> For customization of the MDTimePicker class, see the documentation
> in the BaseDialogPicker class.

###  class kivymd.uix.picker.BaseDialogPicker(**kwargs)

> Base class for MDDatePicker and MDTimePicker classes.

このようにあります。MDTimePickerなどが継承する大元クラスになりますね。

`title_input`

> Dialog title fot input date.

> title_input is an StringProperty and defaults to INPUT DATE.

こんなものもあるんですね。このほかにも、テキスト文字列のカラーやフォントも専用の
プロパティがありましたね。

### class kivymd.uix.picker.MDTimePicker(**kwargs)

> Base class for MDDatePicker and MDTimePicker classes.

先程と同様ですね。ここでは特に指定したプロパティなどはありませんが一応触れて
おきます。

あと、書きはしませんがPickerダイアログを開いたときにOKボタンやCANCELボタンが
ありましたが、実体としてはon_save・on_cancelメソッドが呼び出されているのですね。

`hour`

> Current hour

> hour is an StringProperty and defaults to ‘12’.

最初に開いたときは指定がなければ12時を指し示すのですね。minuteとかでも同様
のようです(minuteでは0がデフォ)。

`set_time(self, time_obj)`

> Manually set time dialog with the specified time.

すごい飛ばしたと思われそうですし自覚済みではあるのですが、こちらはデフォの時間を
変更することも出来るらしいです。詳細の方は、「Open time dialog with the -
specified time」の使用例を見てもらえればと思います。

## 結果

ということで、意外と長くなってしまいましたけれども、ここで実行結果の方に移ります。

![113.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/b8fcb76c-36cd-f554-5c3b-ece803884018.png)

ここまでは、まぁちょっと変わってはいますがマニュアルと変わりはありません。

![114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/c5fe9b96-c8cf-a364-527f-3d32311842d3.png)

で、ボタンを押すと上のキャプチャのようにダイアログが出るので、適当な時間を選択します。
選択できればOKボタンを押します。マニュアルとは結構表示が異なりますが、これもご愛嬌と
いうことで。

![115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/b2dac183-0759-e245-7669-0b1007f5792a.png)

最終的には指定した時間をラベルで表示することが出来ましたー。
ばんざーい、ばんざーいという感じですね。最初は半信半疑でほんとに動くの？
という感じだったのですが、動いたのを見ておぉぉと軽い感動を覚えました。

## まとめ

ということで、いかかだったでしょうか。
時間だけでも使えるのなら、アプリの豊富さというか幅は広がるかと思われます。
これさえあれば、めざましアプリくらいは作れるのではないでしょうか。

関係はないですが、ThemePickerは個人的には触りたかったな〜と強く思って
いました。まぁこれはアップデート後のお楽しみにということで。

さて、来週からのことになりますが、次回は順番通りにProgress篇となります。
これは問題なく動きます。安心してください。ということで、今週はこれまでに
なります。さようなら〜。

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

## 参照

> Components » Pickers
> https://kivymd.readthedocs.io/en/latest/components/pickers/