KivyのRecycleViewを複数カラムを持つTableみたいに表示させるの巻

KivyのRecycleViewを複数カラムを持つTableみたいに表示させるの巻

はじめに

いやもうね、公式ドキュメントを見ても検索しても、私のような初心者はそれらの内容を理解するにも、それらを参考に試行錯誤するにもすごい時間がかかってしまって。

やり方がようやくわかってもすぐ忘れそうなので備忘録として残しとこうと。

今回のやりたいことはこんな感じです。KivyのRecycleViewをいくつかの列に分けてTableみたいに表示させる、と。

kivy_recycleview_3columns

とりあえず基にするRecycleViewを表示してみる

まずはじめに、公式ページのスクリプトで最小構成とされているものを実行すると、1行1列で表示する形になりますので、これを基にしてやってみます。

この.pyファイル(ここでは簡単にするために10行の表示になるよう改変しています)を実行すると、

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView


Builder.load_string('''
<RV>:
    viewclass: 'Label'
    RecycleBoxLayout:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
''')

class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.data = [{'text': str(x)} for x in range(10)]


class TestApp(App):
    def build(self):
        return RV()

if __name__ == '__main__':
    TestApp().run()

こうなる、と。1行に1列ですね、はい。

kivy_recycleview_1column

複数列で表示するやり方

で、RecycleViewを複数列での表示にするには、

データを格納している”data”を複数列に対応した形にすれば良いのですが、はて、どうやるの?って話で。。。

ひとまずここで、”data”について確認してみると、

print(self.data)

[{'text': '0'}, {'text': '1'}, {'text': '2'}, {'text': '3'}, {'text': '4'}, {'text': '5'}, {'text': '6'}, {'text': '7'}, {'text': '8'}, {'text': '9'}]

となっていて、RecycleViewの”data”はリストの中に辞書が入っている形で、1つの辞書が1つの行に順番に対応しているのだな、ということがわかります(公式ドキュメントに書いてあるけど文章だけだとイメージが湧きにくいんですよね。。。)

というわけで、RecycleViewで1行に複数の列を表示することは、これらの辞書の要素を複数にすることに対応するのね、と。

はい、.pyファイルに戻ります。

現在のスクリプトのviewclassは”Label”になっています。

これにより、Labelウィジェットの”text”にデータを入れる形になっています。

これは1対1の対応になっているのでこのままでは複数の要素を複数の列にして表現することができない模様。

なので、viewclassを”BoxLayout”に変えて、そこに複数のLabelをぶら下げて複数の列を表現できるようにします。

ここでは<RVBox@BoxLayout>としてBoxLayoutを継承したクラスを新しく定義することにしました。

というわけで

[Kivy言語の記述部分]
・<RV>のviewclassのところを”RVBox”に変えます。

・<RVBox@BoxLayout>を宣言します。

・text1とtext2とtext3を子インスタンスとして宣言しておきます。このときは空(”)でいいみたい。

・RVBoxにLabelをぶら下げて、それぞれのtextにそれぞれtext1, text2, text3が入るようにします。

[Pythonの記述部分]
・クラスRVの定義のところで、”data”のリストにtext1, text2, text3の要素で構成された辞書を入れ込むようにします。

で、こうなりました。

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView


Builder.load_string('''
<RV>:
    viewclass: 'RVBox'
    RecycleBoxLayout:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'

<RVBox@BoxLayout>
    text1:''
    text2:''
    text3:''
    Label:
        text: root.text1
    Label:
        text: root.text2
    Label:
        text: root.text3
''')

class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.data = [{'text1': str(x), 'text2': str(x**2), 'text3': str(x**3)} for x in range(10)]

class TestApp(App):
    def build(self):
        return RV()
        
if __name__ == '__main__':
    TestApp().run()

実行すると、こうなります。

kivy_recycleview_3columns

でけた。

おわりに

方法が分かってしまえば、簡単なことなのだろうと思いますが、分かるようになるまでえらい時間がかかりました。。。

さて、本記事ではBoxLayoutを使いましたが、並列で表示できる使いたいウィジェットを使えばいいと思います。

RecycleViewを使うなら、viewclassにSelectableLabelを設定することが多いでしょうか。SelectableLabelはそれ自身で複数列の表示に対応できます。どうやらLabelでなくてGridLayoutの仲間のようなので。

以上、KivyのRecycleViewで複数列を表示するやり方でした。

KivyのRecylceViewの理解が少し進みましたとさ(たぶん)。めでたしめでたし。

おしまい

実施環境

Python 3.9.4

Kivy                     2.0.0

macOS Catalina ver.10.15.7

参考にしたサイト

  1. https://kivy.org/doc/stable/api-kivy.uix.recycleview.html; Kivy 2.0.0 公式ドキュメント
  2. How to put multiple columns into a kivy RecycleView?


https://business.xserver.ne.jp/

https://www.xdomain.ne.jp/

★LOLIPOP★

.tokyo

MuuMuu Domain!