简体   繁体   中英

custom widget triggers another custom widget's on_touch_down event

Whenever I press any area in MyWidget then it trigger the first MyButton 's on_touch_down event inside MyLayout class. I am new to kivy and don't understand why this is happening.

<MyButton@Button>:
  background_normal: ''
  background_color: [1,0,1,1]
  font_size: "44dp"
  color:[1,1,0,1]
  border:(1,1,1,1)
  text_size:self.size

<MyWidget@Widget>:
  id:customwidget
  canvas.before:
    Color:
      rgba:0.2,0.44,0.66,1
    Rectangle:
      pos:self.pos
      size:self.size

<MyLayout>:
  MyWidget:
    id:mywidget

  MyButton:
    id:button1
    text: "User Name"
    spacing: "10dp"
    on_touch_down: button1.text= self.text + "?"
    opacity: .8

  MyButton:
    text: "ikinci"
    on_touch_down: root.export_to_png("filename.png")
  MyButton:
    text: "ucuncu"

And this is python:

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

class MyLayout(BoxLayout):
    pass

class KivyApp(App):
    def build(self):
        return MyLayout()

if __name__ == "__main__":
    KivyApp().run()

Python code

  1. Create a class MyButton() and implement on_touch_down() method to check for collision of the touch with our widget.

Snippet - Python code

class MyButton(Button):

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            print("\tMyButton.on_touch_down:")
            if self.text == 'User Name':
                self.text= self.text + "?"
            elif self.text == 'ikinci':
                App.get_running_app().root.export_to_png("filename.png")
            return True
        return super(MyButton, self).on_touch_down(touch)

kv file

  1. Rename dynamic class <MyButton@Button>: to classs rule, <MyButton>:
  2. Remove all on_touch_down: from MyButton:

Snippet - kv file

<MyButton>:
    background_normal: ''
    background_color: [1,0,1,1]
    font_size: "44dp"
    color:[1,1,0,1]
    border:(1,1,1,1)
    text_size:self.size
...
    MyButton:
        id:button1
        text: "User Name"
        spacing: "10dp"
        opacity: .8

    MyButton:
        text: "ikinci"

    MyButton:
        text: "ucuncu"

Touch event basics

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 

Output

Img01-单击的按钮用户名 Img02-单击的按钮-ikinci

The on_touch events are not specific to any widget, but are propagated to all your widgets. See the documentation . If you only want your Button to respond, you probably want to use on_press or on_release events instead (See button behavior ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM