본문 바로가기

코딩/파이썬 kivy

kivy 스터디 012. kivy 프라퍼티 이벤트 (property event) - ListProperty 이벤트

kivy : property events : listproperty

kivy 프라퍼티 이벤트 (property event) - ListProperty 이벤트

생성한 kivy 프라퍼티에 어떤 변화가 발생했을 때, 이를 이벤트로 원하는 코드가 실행되도록 할 수 있다.

 

kivy에서 사용 가능한 kivy 프라퍼티는 다음과 같다.

  • StringProperty
  • NumericProperty
  • BoundedNumericProperty
  • ObjectProperty
  • DictProperty
  • ListProperty
  • OptionProperty
  • AliasProperty
  • BooleanProperty
  • ReferenceListProperty

ListProperty 이벤트

kivy 프라퍼티는 기본적으로 on_<property name> 이벤트를 제공한다.

on_<property name> 이벤트는 kivy 프라퍼티의 값이 변경되었을 때 호출된다.

 

아래 이미지와 같이 BoxLayout 클래스와 Button 클래스를 이용해 화면에 버튼 2개를 생성한다.

 

버튼 2개를 가지는 kivy 애플리케이션

 

왼쪽 버튼 Button은 Button 클래스를 이용해 생성하고, 오른쪽 버튼 My Button은 Button 클래스를 상송하는 MyButton 클래스를 이용해 생성한다.

 

import kivy
kivy.require('2.0.0')

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

class MyButton(Button):
    def __init__(self, **kwargs):
        super(MyButton, self).__init__(**kwargs)

    def on_touch_down(self, touch):
        super(MyButton, self).on_touch_down(touch)
        if self.collide_point(*touch.pos):
            print('MyButton')
            return True

class RootWidget(BoxLayout):
    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
        self.add_widget(Button(text='Button'))
        self.add_widget(MyButton(text='My Button'))

class MyApp(App):
    def build(self):
        return RootWidget()

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

 

위의 코드에서 오른쪽 버튼 My Button을 누르면, My Button의 이벤트 on_touch_down이 호출되고 문자열 MyButton이 개발환경(파이참)에 출력된다.

 

MyButton의 출력

 

kivy 프라퍼티 ListProperty를 사용하기 위해 ListProperty 프라퍼티를 import 한다.

MyButton 클래스 내에 my_btn_pressed 이름의 ListProperty 프라퍼티를 생성한다.

MyButton 클래스의 on_touch_down 메서드 내에 마우스 입력 위치 touch.pos를 ListProperty인 my_btn_pressed에 대입하는 코드를 추가한다.

MyButton 클래스 내에 ListProperty인 my_btn_pressed의 값이 변경되었을 때 호출되는 메서드 on_my_btn_pressed를 추가한다.

 

import kivy
kivy.require('2.0.0')

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.properties import ListProperty

class MyButton(Button):
    my_btn_pressed = ListProperty([0, 0])

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

    def on_touch_down(self, touch):
        super(MyButton, self).on_touch_down(touch)
        if self.collide_point(*touch.pos):
            print('MyButton')
            self.my_btn_pressed = touch.pos
            return True

    def on_my_btn_pressed(self, instance, pos):
        print('ListProperty : {pos}'.format(pos=pos))

class RootWidget(BoxLayout):
    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
        self.add_widget(Button(text='Button'))
        self.add_widget(MyButton(text='My Button'))

class MyApp(App):
    def build(self):
        return RootWidget()

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

 

위의 코드를 실행한 후, 오른쪽 버튼 My Button을 누르면 개발환경(파이참)에 문자열 MyButton과 함께 마우스의 x, y 위치 정보가 표시된다.

 

ListProperty 이벤트의 실행

 

Button과 My Button을 생성하는 RootWidget 클래스 내에서 MyButton 클래스에 정의되어 있는 ListProperty인 my_btn_pressed의 값이 변경되었을 때 이를 이벤트로 감지하는 코드는 MyButton 클래스 객체의 bind 메서드를 이용해 구현한다.

 

import kivy
kivy.require('2.0.0')

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.properties import ListProperty

class MyButton(Button):
    my_btn_pressed = ListProperty([0, 0])

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

    def on_touch_down(self, touch):
        super(MyButton, self).on_touch_down(touch)
        if self.collide_point(*touch.pos):
            print('MyButton')
            self.my_btn_pressed = touch.pos
            return True

    def on_my_btn_pressed(self, instance, pos):
        print('ListProperty : {pos}'.format(pos=pos))

class RootWidget(BoxLayout):
    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
        self.add_widget(Button(text='Button'))
        my_button = MyButton(text='My Button')
        my_button.bind(my_btn_pressed=self.btns_pressed)
        self.add_widget(my_button)

    def btns_pressed(self, instance, pos):
        print('RootWidget :', '{pos}'.format(pos=pos))

class MyApp(App):
    def build(self):
        return RootWidget()

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

 

MyButton 클래스 객체인 my_button에 대하여 bind 메서드로 ListProperty인 my_btn_pressed의 값이 변경되었을 때 RootWidget 클래스의 btns_pressed 메서드가 호출되도록 한다.

 

my_button.bind(my_btn_pressed=self.btns_pressed)

 

My Button 버튼을 누르면, 아래와 같이 개발환경(파이참)에 문자열 RootWidget : xxx 정보가 표시된다.

 

RootWidget 클래스에서 ListProperty 이벤트의 감지