[Kivy] Spinnerの設定 作成と選択肢のフォントの指定

Spinnerの作成と選択肢部分のフォントや書式の指定

 KivyのSpinnerは、クリックすると選択可能な値(テキスト)のドロップダウンメニューが表示されて、その中から値を選択するとメインの部分に選択した値が表示されます(そのテキストを選択した状態になります)。

 Spinnerに日本語を表示する場合、Spinnerのfont_nameに日本語に対応したフォントを指定しただけでは、選択中の項目(Spinnerに表示されるテキスト)のフォントは変更されますが、選択肢部分(ドロップダウンリスト)のテキストのフォントはデフォルトのままであり、日本語が表示されません。

 今回は、SpinnerのKv Languageでの作成方法とドロップダウンリスト部分のフォントや書式を指定する方法について紹介します。

今回紹介する内容
 ・ Spinnerを作成する
 ・ Spinnerの選択肢部分のフォントを指定する。

KivyのSpinnerの選択肢の追加方法については、以下の記事があります。

Spinnerを作成する

 Kv LanuguageでSpinnerを定義するには以下のように、Spinner:と記入してその下に対象のプロパティや関数の内容を記入します。

            Spinner:
                id: spinner
                font_name: 'NotoSansJP-Regular.ttf'
                font_size: '16pt'
                option_cls: Factory.MySpinnerOption
                on_text:
                    print(self.text)

Spinnerの選択肢部分のフォントを指定する。

 Spinnerの選択肢部分(ドロップダウンリスト)のフォントや書式は、①SpinnerOptionを定義して、②それをspinnerのoption_clsに設定することにより変更できます。

SpinnerOptionの定義

 ドロップダウンリスト部分は、Kvファイルの中に<ドロップダウンリストの名前@SpinnerOption>として定義します。名前部分は、Spinnerのoption_clsでFactoryの後に記入したものと同じにします。

 以下の例では、書式(halign,valign)とフォント名、フォントサイズを指定しています。

#:import Factory kivy.factory.Factory

<MySpinnerOption@SpinnerOption>:
    halign: 'center'
    valign: 'middle'
    font_name: 'NotoSansJP-Regular.ttf'
    font_size: '16pt'

Spinnerのoption_clsに指定

 Spinner側では、option_clsを使用してドロップダウンリストを指定します。指定時には、’Factory.ドロップダウンリストの名前’で指定します。そして、Factoryを使用するため、Kv languageには、#:import Factory kivy.factory.Factoryを記入します。

#:import Factory kivy.factory.Factory

# 省略

            Spinner:
                id: spinner
                font_name: 'NotoSansJP-Regular.ttf'
                font_size: '16pt'
                option_cls: Factory.MySpinnerOption
                on_text:
                    print(self.text)

サンプルプログラム

 下記の2つのファイルと任意の日本語対応フォント(kvファイルのfont_nameをそのフォントのファイル名に変更してください。)を同じフォルダに保存して、プログラムを実行すると左図の画面が表示されます。spinnerを左クリックすると、右のような選択肢が表示されます。

#:kivy 2.0
#:import Factory kivy.factory.Factory

<MySpinnerOption@SpinnerOption>:
    halign: 'center'
    valign: 'middle'
    font_name: 'NotoSansJP-Regular.ttf'
    font_size: '16pt'

<DataInputWidget>:
    BoxLayout:
        size: root.size
        orientation: 'vertical'
        spacing: 20
        padding: 20
        canvas.before:
            Color:
                rgba: 0.7, 0.7, 0.7, 1
            Rectangle:
                size: self.size
                pos: self.pos

        BoxLayout:
            spacing: 20
            size_hint: 1, 0.2

            Label:
                text: 'Date'

            Spinner:
                id: spinner
                font_name: 'NotoSansJP-Regular.ttf'
                font_size: '16pt'
                option_cls: Factory.MySpinnerOption
                on_text:
                    print(self.text)

        Label:
            size_hint_y: 0.8

# -*- coding: utf-8 -*-

import os
import datetime
import calendar

import kivy

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.config import Config

from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup

kivy.require('2.2.0')

# 画面サイズの指定
Config.set('graphics', 'width', '600')
Config.set('graphics', 'height', '500')

Builder.load_file(os.path.dirname(__file__) + "/interface.kv")


class DataInputWidget(Widget):

    def __init__(self, **kwargs):
        super(DataInputWidget, self).__init__(**kwargs)

        # Spinnerの日付情報準備
        date = datetime.date.today()
        date2 = date - datetime.timedelta(days=1)
        date3 = date + datetime.timedelta(days=1)

        # Spinnerへのデータ追加
        self.ids.spinner.values.append(
            date2.strftime('%Y年%m月%d日') + self.get_weekday(date2))
        self.ids.spinner.values.append(
            date.strftime('%Y年%m月%d日') + self.get_weekday(date))
        self.ids.spinner.values.append(
            date3.strftime('%Y年%m月%d日') + self.get_weekday(date3))
        self.ids.spinner.text = date.strftime('%Y年%m月%d日') + self.get_weekday(date)

    def get_weekday(self, date):
        # デフォルトでは、月曜日が0
        weekday = calendar.weekday(date.year, date.month, date.day)

        match weekday:
            case 0:
                return '(月)'
            case 1:
                return '(火)'
            case 2:
                return '(水)'
            case 3:
                return '(木)'
            case 4:
                return '(金)'
            case 5:
                return '(土)'
            case 6:
                return '(日)'


class DataInputApp(App):
    def __init__(self, **kwargs):
        super(DataInputApp, self).__init__(**kwargs)
        self.title = 'Label Test'

    def build(self):
        return DataInputWidget()


if __name__ == '__main__':
    app = DataInputApp()
    app.run()
タイトルとURLをコピーしました