Inagnikai Inagnikai - 10 months ago 78
Python Question

Assigning custom method to on_touch_down etc. in Kivy

I'm writing what is ultimately to be a mobile game app using Kivy. Given the capabilities of the framework - being able to separate form and function - I'm attempting to do most, if not all, of the design of my GUI within a .kv file using the Kivy language. This works great as far as crafting a layout, but getting touch event handlers to work correctly is proving quite challenging. What I'm attempting to do is this:


from kivy import require
from import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.boxlayout import BoxLayout


class gameScreen(FloatLayout):

def move_scatter(self, sender):
self.ids.moveArea.x = sender.text

def pc_move(self, touch, *args, **kwargs):
# self.ids.protagonist.pos = (self.x + )

class GameApp(App):

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

def build(self):
return gameScreen()

class MoveBox(BoxLayout):

class Pc(Image):

if __name__ == '__main__':

Kivy Code:


orientation: 'vertical'
padding: 20

size: (root.width, root.height)
source: 'bliss.jpg'

id: protagonist

id: debugOut
size_hint: None, None
size: 200, 50
text: 'Hello'

id: moveArea
size_hint: None, None
size: 200, 200
on_touch_down: root.pc_move()
rgba: .2, .2, .2, .5
pos: (self.x + root.width - self.width, self.y)
size: self.size

pos_hint: {'top': .9}
size_hint: None, None
size: 300, 300

When I try this, I get:

TypeError: pc_move() takes at least 2 arguments (1 given)

This obviously make sense, as I am calling the pc_move() method without passing an argument. I know that the easiest way around this issue is just to create the BoxLayout in my Python code and define the on_touch_down method there, but as stated, I'm trying to keep my GUI and functionality separate.

The question is, how do I get the 'touch' parameter to pass as it would if I were to create the widget in Python code? Alternatively, am I just chasing a white whale? Does the event handling have to be done in a widget created in the Python code?

Answer Source

I confess I've never used Kivy, but the documentation for on_touch_down indicates it receives a touch parameter.

The docs also mention that args keyword is available in on_ callbacks.

Putting these two together, you should be able to pass your touch parameter to python via:

on_touch_down: root.pc_move(args[1])

[I'm not positive that it will be the #1 element in args[], but some of the examples seem to indicate that]