본문 바로가기

코딩/파이썬 kivy

kivy 스터디 015. Kivy Input Management - on_touch_move()

Kivy Input Management - on_touch_move()

마우스 조작과 관련한 on_touch_move 메서드는 마우스 버튼을 누른 상태에서 위치를 이동할 때 호출된다.

 

하나의 버튼을 가지며 on_touch_move 메서드를 포함하는 코드를 작성한 후 실행한다.

 

<코드 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_move(self, touch):
        print('on_touch_move')

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 위를 이동하면 개발환경 출력창에 작성한 문구가 표시된다.

 

 

마우스 오른쪽 버튼 클릭 시 생성되는 작은 동그라미를 마우스 왼쪽 또는 오른쪽 버튼을 누른 채 이동해도 on_touch_move 문구가 표시된다.

 

 

<코드 1> 내 on_touch_move 메서드를 수정하여 마우스로 움직이는 좌표를 표시해 본다.

 

<코드 2>

    def on_touch_move(self, touch):
        if self.collide_point(*touch.pos):
            if super(MyButton, self).on_touch_move(touch):
                print(touch.button, '{0:>3d} -> {1:>3d} , {2:>3d} -> {3:>3d}'.format(
                    int(touch.px), int(touch.x), int(touch.py), int(touch.y)))
                return True

 

마우스 왼쪽 버튼을 클릭한 상태에서 화면 왼쪽 상단에서 화면 오른쪽 하단으로 이동하면 아래와 같이 움직이는 좌표가 표시된다.

 

 

위의 출력 결과에서 발견하게 되는 것은 동일한 좌표가 두번 출력되고 있는 것이다.

x와 y의 좌표는 float 타입인데 int 타입으로 값을 변경한 이유도 있겠으나 kivy의 이벤트 처리 또한 제대로 하고 있지 않은 것으로 생각된다.

 

kivy 가이드엔 아직 이에 대한 설명이 없는게 아쉽다.

 

일단 <코드 1>에서 이전 x 좌표값 및 y 좌표값이 현재의 touch.x와 touch.y 값과 같은 경우는 출력을 건너뛰기로 한다.

이를 위해 MyButton 클래스 생성자 메서드 __init__ 내에 객체 변수 self.my_x와 self.my_y를 생성하고 on_touch_move 메서드 내에서 값 비교를 한다.

 

<코드 3>

class MyButton(Button):
    def __init__(self, **kwargs):
        super(MyButton, self).__init__(**kwargs)
        self.my_x = -1
        self.my_y = -1

 

<코드 4>

    def on_touch_move(self, touch):
        if self.collide_point(*touch.pos):
            if super(MyButton, self).on_touch_move(touch):
                if self.my_x != int(touch.x) or self.my_y != int(touch.y):
                    print(touch.button, '{0:>3d} -> {1:>3d} , {2:>3d} -> {3:>3d}'.format(
                        int(touch.px), int(touch.x), int(touch.py), int(touch.y)))
                    self.my_x = int(touch.x)
                    self.my_y = int(touch.y)
                return True

 

<코드 1>, <코드 3>, <코드 4>를 통합한 코드를 작성한 후 실행하면 그 결과는 다음과 같다.

 

참고

2021.08.07 - [학습 노트/Kivy] - kivy 스터디 013. Kivy Input Management - on_touch_down()

2021.08.08 - [학습 노트/Kivy] - kivy 스터디 014. Kivy Input Management - on_touch_up()