Kivy Input Management - on_touch_down()
kivy는 다양한 타입의 입력을 처리한다.
- mouse
- touchscreen
- accelerometer
- gyroscope
- etc
kivy에서 임의 입력이 처리되는 구조는 아래와 같다.
모든 입력 이벤트는 MotionEvnet 클래스로 다음과 같이 2가지 타입의 이벤트를 발생시킨다.
- touch events : x와 y의 위치 정보를 가지는 motion에 대한 이벤트로 모든 touch 이벤트는 widget tree에 전달됨
- no-touch events : accelerometer와 같은 연속성을 가지는 이벤트로 no-touch 이벤트는 widget tree에 전달되지 않음
motion에 대한 이벤트는 input provider에 의해 생성된다. 다음은 input provider의 종류의 예이다.
- TuioMotionEventProvider : TUIO 관련
- WM_MotionEventProvider : Window 관련
- ProbeSysfsHardwareProbe : Linux 관련
이벤트 발생에 따른 메서드 호출에 있어 motion 이벤트와 touch 이벤트를 구분하는 듯한데, kivy 가이드는 아래와 같이 설명한다. 범위 차원에서 touch 이벤트 ⊂ motion 이벤트로 보여진다.
- 발생한 이벤트가 motion 이벤트이면, 이는 on_motion()에 전달된다.
- 발생한 이벤트가 touch 이벤트이면, 이는 on_touch_down(), on_touch_move(), on_touch_up()에 전달된다.
윈도우 10을 기준으로 임의 버튼을 마우스로 누르면, on_touch_down() 및 on_touch_up() 메서드가 실행됨을 확인한다.
아래의 코드는 하나의 버튼을 가지는 애플리케이션을 만드는 코드로 마우스 왼쪽 버튼으로 My Button을 클릭하면 개발환경 출력 창에 몇 가지 문구가 출력된다.
<코드 1>
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):
if self.collide_point(*touch.pos):
print('my_button : on_touch_down')
ret = super(MyButton, self).on_touch_down(touch)
print('my_button : super.on_touch_down ->', ret)
return True
class MyRootWidget(BoxLayout):
def __init__(self, **kwargs):
super(MyRootWidget, self).__init__(**kwargs)
self.add_widget(MyButton(text='My Button'))
class MyApp(App):
def build(self):
self.title = 'My Kivy App'
return MyRootWidget()
if __name__ == '__main__':
MyApp().run()
만약 마우스 오른쪽 버튼으로 My Button을 클릭하면 아래와 같이 My Button을 누른 상태가 유지되고 버튼을 누른 위치에 하나의 작은 동그라미가 표시된다.
위 상태에서 마우스 왼쪽 버튼으로 My Button을 클릭하면(작은 동그라미 또는 그외 영역), 아래와 같이 My Button은 누르지 않은 상태로 돌아온다. 아래의 이미지는 My Button 내 작은 동그라미 외의 영역을 누른 경우이다.
마우스 오르쪽 버튼 사용으로 생성된 작은 동그라미는 마우스 왼쪽 버튼으로 제거할 수 있는데, 이 경우 on_touch_down 메서드는 호출되지 않는다.
특이한 점은 마우스 버튼이 아닌 마우스 휠을 움직여도 개발환경 출력 창에 on_touch_down이 호출된다는 것이다.
kivy의 이벤트 처리는 python 기반의 wxPython이나 tkinter와는 사뭇 다른 것 같다.
아무래도 모바일 기기를 고려한 설계라 생각되는데 추가 확인이 필요해 보인다.
touch 이벤트에 사용 가능한 프라퍼티의 예는 아래와 같다.
- is_touch
- profile
- pos
- button
첫번째 작성한 <코드 1>에서 위의 프라퍼티를 사용한 코드를 추가해 본다.
<코드 2>
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
print('my_button : on_touch_down')
print('my_button : touch.is_touch = ', touch.is_touch)
print('my_button : touch.profile [] = ', touch.profile)
print('my_button : touch.pos () = ', touch.pos)
print('my_button : touch.button = ', touch.button)
ret = super(MyButton, self).on_touch_down(touch)
print('my_button : super.on_touch_down ->', ret)
print()
return True
<코드 1>을 수정한 후 실행하고 마우스를 다음의 순서로 조작하면,
- 마우스 왼쪽 버튼 -> 마우스 오른쪽 버튼 -> 마우스 왼쪽 버튼으로 작은 동그라미 클릭 -> 마우스 휠 down -> 마우스 휠 up
아래 이미지와 같이 각 마우스 조작 마다 touch 이벤트의 각 프라퍼티 값이 변경되는 것을 볼 수 있다.
kivy의 특성이라고 보이는 특이점 중의 하나는 touch 이벤트의 pos 프라퍼티 값이다.
아래의 이미지와 같이 마우스 왼쪽 하단을 클릭하면,
pos 프라퍼티의 x, y 값은 24와 27 정도가 된다. 아무래도 x, y 기본 좌표는 왼쪽, 하단이 0, 0인 것으로 판단된다.
다음은 touch 이벤트 객체인 touch의 타입 정보이다.
<class 'kivy.input.providers.mouse.MouseMotionEvent'>
아래는 윈도우 기준 몇 가지 추가적으로 사용할 수 있는 touch 이벤트의 프라퍼티이다.
- is_double_tap
- double_tap_time
- is_triple_tap
- triple_tap_time
'코딩 > 파이썬 kivy' 카테고리의 다른 글
kivy 스터디 015. Kivy Input Management - on_touch_move() (0) | 2021.08.10 |
---|---|
kivy 스터디 014. Kivy Input Management - on_touch_up() (0) | 2021.08.08 |
kivy 스터디 012. kivy 프라퍼티 이벤트 (property event) - ListProperty 이벤트 (0) | 2021.07.26 |
kivy 스터디 011. 위젯 이벤트 (widget events) - Button & on_touch_down 메서드 (0) | 2021.07.25 |
kivy 스터디 010. 클럭 이벤트 3 (clock events) - create_trigger() (0) | 2021.07.21 |