[Kivy]汎用的なメッセージポップアップ

プログラミング

Kivyでメッセージを表示をしようとしたとき、MessageBox的なものを探したけれど用意されていないらしい。

一応をポップアップ画面を表示する仕組みはあるみたいだけど、Webの経験が長い自分としては、JavaScript でいう alert とか confirm みたいな感じで手軽に使えるメッセージ表示の仕組みが欲しい。

ということで、汎用的に使えるメッセージポップアップクラスを用意したのでメモを残します。

プログラムソース

Pythonソース、KVにそれぞれクラスを追加したら使えるようになるはず。

from kivy.properties import StringProperty
from kivy.uix.popup import Popup

class ConfirmPopup(Popup):
    message = StringProperty('')
    ok_text = StringProperty('OK')
    cancel_text = StringProperty('Cancel')

    __events__ = ('on_ok', 'on_cancel')

    def ok(self):
        self.dispatch('on_ok')
        self.dismiss()
    def cancel(self):
        self.dispatch('on_cancel')
        self.dismiss()
    def on_ok(self):
        pass
    def on_cancel(self):
        pass
    def __init__(self, **kwargs) -> None:
        super(ConfirmPopup, self).__init__(**kwargs)
        self.size_hint = (0.8, 0.3)
        self.pos_hint={'center_x':0.5, 'center_y':0.5}
        self.auto_dismiss = False

class MessagePopup(Popup):
    message = StringProperty('')
    ok_text = StringProperty('OK')

    __events__ = ('on_ok',)

    def ok(self):
        self.dispatch('on_ok')
        self.dismiss()
    def on_ok(self):
        pass
    def __init__(self, **kwargs) -> None:
        super(MessagePopup, self).__init__(**kwargs)
        self.size_hint = (0.8, 0.3)
        self.pos_hint={'center_x':0.5, 'center_y':0.5}
        self.auto_dismiss = False
<ConfirmPopup>:
    FloatLayout:
        Label:
            size_hint: 0.8, 0.6
            pos_hint: {'x': 0.1, 'y':0.4}
            text: root.message
            text_size: self.size
            halign: 'center'
            valign: 'middle'
        Button:
            size_hint: 0.4, 0.35
            pos_hint: {'x':0.1, 'y':0.05}
            text: root.cancel_text
            on_release: root.cancel()
        Button:
            size_hint: 0.4, 0.35
            pos_hint: {'x':0.5, 'y':0.05}
            text: root.ok_text
            on_release: root.ok()

<MessagePopup>:
    FloatLayout:
        Label:
            size_hint: 0.8, 0.6
            pos_hint: {'x': 0.1, 'y':0.4}
            text: root.message
            text_size: self.size
            halign: 'center'
            valign: 'middle'
        Button:
            size_hint: 0.4, 0.35
            pos_hint: {'x':0.5, 'y':0.05}
            text: root.ok_text
            on_release: root.ok()

使い方

上記のソースのとおり2つのクラスを用意しました。

ConfirmPopup:OK/キャンセル、Yes/No とかボタンが2つのポップアップ

MessagePopup:ボタンが1つのメッセージ用ポップアップ

MessagePopup はボタンが1つ少ないだけで使い方は同じなので、ConfirmPopup を中心に使い方を説明します。

使い方

表示イメージ
        self.popup = ConfirmPopup(title='表示確認です', message='イメージつかめますか?')
        self.popup.bind(
            on_ok=self.ok_action,
            on_cancel=self.cancel_action
        )
        self.popup.open()

こんな感じで呼び出すことができます。

「title」でタイトル(線よりも上の部分)に表示するメッセージ、「message」でメイン部分に表示するメッセージを渡してクラスを呼び出します。

受け取ったクラスに、ボタンが押された後に行いたい処理を「on_ok」「on_cancel」にそれぞれbindしてあげます。例では “ok_action” が、OKボタン(右)が押されたときに実行したい関数です。

一つ注意点として、ポップアップから戻るときにpopupクラス自身も返ってくるため、bindする関数では *args や変数を用意するなどして、引数を受け取れるようにしておいてください。

    def ok_action(self, *args):
        self.label1.text = "OK"

    def cancel_action(self, popup):
        self.label1.text = "CANCEL"

キャンセルのときは特に何もする必要がなければ、bindする必要はありません。

        self.popup.bind(
            on_ok=self.ok_action
        )

open()でポップアップを表示します。

ボタンの表示を変える

表示イメージ
        self.popup = ConfirmPopup(title='ボタン変更', message='チョメチョメしますか?', ok_text='する', cancel_text='しない')
        self.popup.bind(
            on_ok=self.ok_action
        )
        self.popup.open()

はい/いいえ のようにボタンの選択肢を変えたい場合は、「ok_text」「cancel_text」に文言を渡せば変更することもできます。

タイトル部分を消す

表示イメージ
        self.popup = ConfirmPopup(title='', message='タイトルなんていらない?' , separator_height=0)
        self.popup.bind(
            on_ok=self.ok_action,
        )
        self.popup.open()

タイトル部分の表示が不要な場合は、「title」に渡す文言を空にして、「separator_height=0」を指定することで表示しないようにできます。

メッセージ表示

表示イメージ
        self.popup = MessagePopup(title='', message='ただのメッセージ' , separator_height=0)
        self.popup.open()

MessagePopupについても使い方は同じです。通知だけの目的で特に処理の必要がない場合は割とシンプルに呼び出せます。

カスタマイズ

ここからは、使用先に合わせたカスタマイズのためのメモです。

デフォルトのボタン文言

デフォルトのボタン文言を変更する場合はクラスプロパティを書き換えます。

    ok_text = StringProperty('OK')
    cancel_text = StringProperty('Cancel')

サイズ・位置の調整

ポップアップの位置やサイズ感はクラスの__init__に指定箇所があります。

    def __init__(self, **kwargs) -> None:
        super(ConfirmPopup, self).__init__(**kwargs)
        self.size_hint = (0.8, 0.3) #表示サイズ
        self.pos_hint={'center_x':0.5, 'center_y':0.5} #表示位置
        self.auto_dismiss = False

※ポップアップ自体のレイアウトやボタンデザインはKVをお好みで修正

背景・文字色変更

色をうまく変える方法は見つけられなかったけど、背景画像の指定は可能です。

①クラスの__init__に追記をします。背景を変えるとデフォルトの文字色だと見えづらくなりがちなので、文字色の変更も併せて変更します。

    def __init__(self, **kwargs) -> None:
        super(ConfirmPopup, self).__init__(**kwargs)
        self.size_hint = (0.8, 0.3)
        self.pos_hint={'center_x':0.5, 'center_y':0.5} 
        self.background='background.png' # 背景画像
        self.title_color=[50/255, 50/255, 50/255, 1] # タイトル部分文字色
        self.auto_dismiss = False

②メインメッセージの文字色は、KV側のLabel にcolorプロパティを設定します。

        Label:
            size_hint: 0.8, 0.6
            pos_hint: {'x': 0.1, 'y':0.4}
            text: root.message
            text_size: self.size
            halign: 'center'
            valign: 'middle'
            color:[50/255, 50/255, 50/255, 1]

画像は引き延ばされるので、単色であれば小さい画像で問題ありません。

表示イメージ

オーバーレイ部分の色変更

クラスの__init__に追記します。色と透明度を設定。

    def __init__(self, **kwargs) -> None:
        super(ConfirmPopup, self).__init__(**kwargs)
        self.size_hint = (0.8, 0.3)
        self.pos_hint={'center_x':0.5, 'center_y':0.5} 
        self.overlay_color = (0/255,255/255,0/255, 0.5) # オーバーレイ部分
        self.auto_dismiss = False

こんな感じになります。

表示イメージ

日本語表示

この記事を読んでいるのは日本の方が多いと思います。デフォルトのフォントを日本語に変えていない場合などは、個別にフォント指定をすることも可能です。

※日本語フォントはお好みのものを用意している前提です。例では、IPAが無償配布している ipaexm.ttf をfontフォルダおいている想定で説明します。

①クラスの__init__に追記をします。

    def __init__(self, **kwargs) -> None:
        super(ConfirmPopup, self).__init__(**kwargs)
        self.size_hint = (0.8, 0.3)
        self.pos_hint={'center_x':0.5, 'center_y':0.5} 
        self.title_font='fonts/ipaexm.ttf' # フォント指定
        self.auto_dismiss = False

②KVファイルで「font_name」をLabel、Bottonのプロパティに追記します。

font_name: 'fonts/ipaexm.ttf'

おわりに

以上です、メッセージポップアップを用意してみた話でした。今のところ割と思い通りに使えています。

カスタマイズの内容はポップアップメッセージに限らずダイアログやらモーダルやら(呼び方が曖昧)の他の機能を作る際にも応用が利きそうな気がします。

(参考)

Kivy: confirmation popup dialog
Kivy: confirmation popup dialog. GitHub Gist: instantly share code, notes, and snippets.

コメント

タイトルとURLをコピーしました