Search code examples
pythonuser-interfacekivytouchmouse

Add widget on mouse pressed in gui - kivy python


I have problem with adding and showing image to the layout every time I press the screen using mouse.

class Myszka(ClickAndGo, Widget):

    def on_touch_down(self, touch):
        super().build()
        flaga_path = os.path.join(self.img_path, "test.png")
        x, y = touch.pos
        self.flaga = Image(source=flaga_path, size_hint=(None, None), size=(64, 64),
                           pos=(round(x, 1), round(y, 1)))
        self.camlayout.add_widget(self.flaga)
        print(touch.pos)
  • Actual results: only touch position is printed, image has not been shown.
  • Expected results: Image should have been shown, every time mouse down.

Solution

  • Problem

    I have problem with adding and showing image to the layout every time I press the screen using mouse.

    Root Cause

    The image is not showing because it is adding to a local attribute, self.camlayout in method on_touch_down()of class Myszka().

    Solution

    Replace self.camlayout.add_widget(self.flaga) with App.get_running_app().root.add_widget(self.flaga) i.e. get an instance of the root (camlayout).

    Snippets - py

    class Myszka(Widget):
    
        def on_touch_down(self, touch):
            ...
            App.get_running_app().root.add_widget(self.flaga)
    

    Example

    The following example illustrates adding Image at the position of the mouse click on a FloatLayout.

    main.py

    import os
    from kivy.app import App
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.image import Image
    
    
    class Mouse(FloatLayout):
    
        def on_touch_down(self, touch):
            img_path = "/home/iam/Pictures/AppImages"
            flag_path = os.path.join(img_path, "Android_celebrate.png")
            flag = Image(source=flag_path, size_hint=(None, None), size=(64, 64),
                         pos=(round(touch.pos[0], 1), round(touch.pos[1], 1)))
            self.add_widget(flag)
    
    
    class TestApp(App):
    
        def build(self):
            return Mouse()
    
    
    if __name__ == "__main__":
        TestApp().run()
    

    Output

    Result