Kivyの基本ウィジェットであるButtonの使い方について説明します。Buttonの背景に画像を使う方法、背景色を変更する方法、Buttonを無効にする方法など書いています。Buttonは無効にすることによってLabelのように使うことも可能です。
Buttonの使い方
Buttonは基本的にはイベントをトリガーさせるために使うウィジェットです。デフォルトでボタンを押したときに水色に変わります。ボタンは背景色をプロパティで設定できるので、ボタンを無効にすることによってLabelの代用として使うことも可能です。
Button:
Buttonのプロパティ
textを装飾するプロパティについては下記の記事をご覧ください。
ウィジェットのサイズを設定するプロパティは下記の記事をご覧ください。
ウィジェットの位置を設定するプロパティは下記の記事をご覧ください。
Button特有のプロパティについて説明します。
- background_color: ボタンの背景色を設定する。
- background_normal: ボタンの通常時の背景画像を設定する。
- background_down: ボタンが押された時の背景画像を設定する。
- background_disabled_normal: ボタン無効時の通常時の背景画像を変える。
- background_disabled_down: ボタン無効時のボタンが押された時の背景画像を設定する。
- disabled: ボタンを無効にする。
- disabled_color: ボタン無効時の文字色を設定する。
ボタンの背景色を設定する
ボタンの背景色を変えるにはbackground_colorを使います。ボタンの背景色はデフォルトではグレーです。このグレーの乗数として計算されるので、background_colorだけを定義した場合、実際には設定した色より暗い色が表示されます。
適切に色を表示させるにはbackground_normalのデフォルト値をクリアする必要があります。このデフォルト値には画像へのパスが入っているので、それを一度削除することによって色の設定ができるようになります。
background_normalに空の値を指定し、background_colorで色を指定します。
Button:
text: "Buttonの背景色を設定する"
background_normal: "" # 空文字で通常時の背景を無効化
background_color: 169/255, 101/255, 117/255, 1 #赤茶系の色
color: 1, 1, 1, 1 # 白
色の指定については下記の記事をご覧ください。
ボタンクリック時の背景色
ボタンを押したとき、デフォルトでは水色ですが、これ自体を変更するプロパティはありません。背景色を変更するとボタンを押したときの背景色も変わるので、通常時の背景色を元に計算されていると思われます。これをどうしても変更したい場合は、ボタンを押したときの背景画像は設定できるので単色の画像で試してみてください。私はcanvasを試してみましたが、うまくいきませんでした。
ボタンに背景画像を設定する
ボタンの背景に画像を設定するにはbackground_disabled_normalを使います。また、ボタンを押したときの背景画像を設定するにはbackground_disabled_downを使います。
背景色の場合は、background_normalに空の値を指定しますが、こちらはそれをする必要はありません。
Button:
background_normal: 'images/image-ts-005.png'
background_down: 'images/image-ts-006.png'
ボタンを無効にする
ボタンを無効にすることも可能です。つまり、ボタンを押しても背景色は変わりません。動的にボタンを無効にしたい場合や、Labelの代替として使うといった用途が考えられます。
ボタンを無効にするにはdisabledプロパティをTrueに指定します。また、ボタン無効時の文字色を変更するには、disabled_colorを使います。
Button:
text: "ボタンを無効にする"
disabled: True
background_disabled_normal: "" # 空文字で通常時の背景を無効化
background_color: 0, 0.5, 1, 1 # 背景色(青)
color: 1, 1, 1, 1 # 文字色(白)
disabled_color: 0.5, 0.5, 0.5, 1 # 無効時の文字色(グレー)
ボタン無効時の背景画像を設定する
ボタンを無効にした時の背景画像の設定にはbackground_disabled_normalを使います。また、ボタンを押したときの背景画像を設定するにはbackground_disabled_downを使います。しかし、これはボタンを無効にしてるので意味のないプロパティです。
Button:
disabled: True
background_disabled_normal: 'images/image-ts-005.png'
background_disabled_down: 'images/image-ts-006.png' #意味のないプロパティ
ボタンに設定した画像のアスペクト比
ボタンの背景に画像を設定した場合のアスペクト比は崩れる場合があります。画像はウィジェットボックスいっぱいに広がり画像のアスペクト比を維持しません。アスペクト比を維持するには画像サイズとウィジェットボックスのサイズを調整する必要があります。
画像をボタンとして機能させる方法もある
KivyのBehaviorモジュールのButtonBehaviorクラスを使用すると画像をボタンのように扱うこともできます。こちらも検討してみてください。
Buttonのイベント
Buttonのイベントにはon_press()とon_release()があります。on_press()はButtonを押したときに呼ばれるイベントで、on_release()はボタンを押してから離したタイミングで呼ばれます。
# pyファイル
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class RootWidget(BoxLayout):
def callback_function(self):
self.ids.label.text += "\nButton released"
class Button1(App):
def build(self):
return RootWidget()
if __name__ == "__main__":
Button1().run()
# kvファイル
<RootWidget>
Label:
id: label
text: "Label"
Button:
text: "Click It"
background_normal: ""
background_color: 169/255, 101/255, 117/255, 1
color: 1, 1, 1, 1 # 文字色(白)
on_press: label.text = "Button pressed"
on_release: root.callback_function()
on_touch_downなどのon_touch系のイベントも使用できます。こちらは通常のイベントと違って伝播の仕組みがあるので扱いが厄介です。詳しくは下記の記事をご覧ください。
Button textのレスポンシブ対応
BoxLayoutやGridLayoutなどの自動整列するレイアウトを使用した場合のButtonなどのウィジェットは、画面に配置すると自動的にレスポンシブ対応されているのですが、textはそうではありません。下図のように画面サイズを変更すると文字がボタンからはみ出します。

このようになるのは良くないので画面サイズが変更されたら、文字を折り返したり、文字サイズをウィジェットに合わせるなどの処理が必要です。どの画面サイズにも対応できるようにする手法をレスポンシブといいます。テキストのレスポンシブ対応の例を下記の記事で紹介しているので合わせてご覧ください。
Buttonのサンプルコード
ボタンの無効化とLabelの代わりにbuttonを使う例を紹介します。例えば背景色にcanvasを使用しないのでButtonの方が扱いやすいかもしれません。またLabelの記事と同様にButtonにマウスホバーを実装しました。(マウスホバーの解説はLabel記事で説明しています)
button2.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.properties import ListProperty
from kivy.uix.button import Button
class CustomButton(Button):
bg_color = ListProperty([1, 1, 1, 1])
def __init__(self, **kwargs):
super().__init__(**kwargs)
Window.bind(mouse_pos=self.on_mouse_move)
def on_mouse_move(self, window, pos):
x, y = self.to_widget(*pos)
if self.collide_point(x, y):
self.bg_color = self.background_normal = ""
self.bg_color = self.background_color = (169/255, 101/255, 117/255, 1)
else:
self.bg_color = self.background_normal = ""
self.bg_color = self.background_color = (0.5, 0.5, 0.5, 1)
class RootWidget(BoxLayout):
pass
class Button2(App):
def build(self):
return RootWidget()
if __name__ == "__main__":
Button2().run()
button2.kv
<RootWidget>:
orientation: "vertical"
spacing: 10
padding: 20
Button:
id: button1
text: "Labelの代わりにボタンを使う"
disabled: True
background_disabled_normal: ""
background_color: 255/255, 253/255, 246/255, 1
disabled_color: 132/255, 124/255, 92/255, 1
on_touch_down:
if self.disabled == True: button2.disabled = False
CustomButton:
id: button2
text: "Hover over me!"
font_size: 24
on_press:
if self.disabled == False: self.disabled = True
このコードはbutton2を押すと自身のボタンを無効にします。button1を押すと無効化を解除し、ボタンを有効にします。また、button2の上にマウスポインタが乗ると背景色が変わります。
Buttonを無効にした場合、on_press()やon_release()は使えませんでした。下記のon_touch_down()は正式な書き方ではありません。kvコードではif文の入れ子ができないのでcollide_point()を省略しています。このコードの場合はこのように書いても問題ないです。
on_touch_down:
if self.disabled == True: button2.disabled = False
Comment