Reputation: 68
I've started making my first kivy app a few days ago and everything went fine up till one point.
I have a Label which has GridLayout inside and 256 buttons (PaletteColorButton
) that are supposed to represent palette. I created an on_touch_down
method for this class and try to click on any of the buttons, they all execute what's inside of on_touch_down
.
Here's the most important part of my code:
class PaletteLabel(ToolBarLabel):
def make_palette(self, layout):
for i in range(0, 256):
palette_color_button = PaletteColorButton()
with palette_color_button.canvas:
Color(i/255, i/255, i/255, 1)
layout.add_widget(palette_color_button)
class PaletteColorButton(Button):
def on_touch_down(self, touch):
if touch.is_double_tap:
print(self.pos)
class BamEditor(App):
Config.set('kivy', 'window_icon', r'.\static\program_icon\BamEditor-icon.png')
def build(self):
main_label = MainLabel()
main_label.ids['palettelabel'].make_palette(main_label.ids['palettelayout'])
return main_label
And here's the data from .kv file:
<PaletteLabel>:
height: 160
width: 640
<PaletteColorButton>:
size:(20,20)
canvas.after:
Rectangle:
pos: self.x + 1 , self.y + 1
size: self.width - 2, self.height - 2
<MainLabel>:
PaletteLabel:
id: palettelabel
pos: (self.parent.x + 120, self.parent.y + 20)
GridLayout:
id: palettelayout
cols: 32
rows: 8
pos: self.parent.x , self.parent.y
size: self.parent.width, self.parent.height
I want to have only the clicked button's pos
printed, but instead I get positions of all 256 buttons, does anyone know how to achieve that? Ofc, I can use on_press
instead and it works, but I'd like my buttons to have different behavior when tapped once and different when tapped twice. Thank you for help.
Upvotes: 0
Views: 1490
Reputation: 5947
from the kivy programming guide:
By default, touch events are dispatched to all currently displayed widgets. This means widgets receive the touch event whether it occurs within their physical area or not.
[…]
In order to provide the maximum flexibility, Kivy dispatches the events to all the widgets and lets them decide how to react to them. If you only want to respond to touch events inside the widget, you simply check:
def on_touch_down(self, touch): if self.collide_point(*touch.pos): # The touch has occurred inside the widgets area. Do stuff! pass
https://kivy.org/docs/guide/inputs.html#touch-events
When you don't want to manage the touch in this button, (so when the collision test fails), you should let the event dispatch to the rest of the widget tree
return super(WidgetClass, self).on_touch_down(touch)
Upvotes: 3