Daniel Daniel - 1 month ago 33
Python Question

Access kivy popup parent

The way popups are implemented in kivy, the popup seems to get attached to the window and not the parent object which created the popup. Popup comes with self.dismiss() to close the popup but I can't figure out any way to access the 'parent' object since despite creating the popup, it seems to exist outside of it.

Example snippets:

class StartButton(ActionButton)
def on_release(self):
self.popup = StartPop(id='popid')
self.popup.open()

class StartPop(Popup):
def close(self):
self.dismiss()
def start(self):
print(self)
print(self.parent)


The result of the print commands is

<__main__.StartPop object at 0x00000000037BBCE0>

<kivy.core.window.window_sdl2.WindowSDL object at 0x000000000373B0B0>


So rather than the parent being StartButton, whose parent I would also expect to access etc. the parent is the Window.

I don't see how I could bind any function that thus interact with the widget I used to create the popup from. I need to be able to get the parent object and its parents to do things based on what I click within the popup but I can't figure out how this could be implemented.

In the .kv file

<StartPop>:
title: 'Popup'
auto_dismiss: True
size_hint: None,None
size: 400,250
BoxLayout:
orientation: 'vertical'
Label:
text: 'sample text here'
text_size: self.size
halign: 'center'
valign: 'middle'
BoxLayout:
orientation: 'horizontal'
Button:
size_hint: 1,0.5
text: 'Cancel'
on_release: root.close()
Button:
size_hint: 1,0.5
text: 'Start Testing'
on_release: root.start()

Answer

It's implemented like that because it needs to be hidden most of the time, yet still active, so that open() could be called. Kivy doesn't seem to handle hiding of the widgets other way that actually removing it and keeping a reference somewhere (there's no hide property), so maybe even because of that. Or because it was easier to implement it this way. It's not bad implementation however and the way OO programming works you can do some fancy stuff with it too. The thing you want can be handled simply with kwargs in __init__:

Inherit from Popup and get a custom keyword argument:

class StartPop(Popup):
    def __init__(self, **kwargs):
        self.caller = kwargs.get('caller')
        super(StartPop, self).__init__(**kwargs)
        print self.caller

Then create an instance of that custom Popup and set the parent:

pop = StartPop(caller=self)
pop.open()

The caller keyword isn't limited only to Kivy widgets. Put there any object you want to do stuff with and you can then access it inside the StartPop object via self.caller

Comments