cometix
cometix

Reputation: 31

In Kivy, why doesn't popup.dismiss() delete the popup from memory?

I'm currently struggling with a memory usage problem in Kivy.

When a popup is created and opened, memory usage goes up a little (which is normal), but when the user closes it (with the dismiss() method, which closes the popup and removes it from its parent), the memory isn't released.

So, if the user decides to open the popup a lot of times, the program will eventually use a lot of memory. Here is a part of my code that shows the problem by creating, opening and then dismissing a popup 500 times.

# py file
class OptionsView(Screen):

    def popupLoop(self):
        for x in range(0, 500):
            popup = self.MyPopup()
            popup.open()
            popup.dismiss()

    class MyPopup(Popup):
        pass


# kv file
<OptionsView>:
    BoxLayout:
        orientation: "vertical"
        Button:
            text: "Popup Loop"
            on_press: root.popupLoop()

<MyPopup>:
    size_hint: (.6, .6)
    title: "Confirmation"
    BoxLayout:
        Button:
            text: "Cancel"
            on_press: root.dismiss()

Pressing the "Popup Loop" button in the OptionView screen causes the program to jump from 1.2% memory usage to 11.7% (according to top). Resizing the window (which calls gc.collect()) does bring this number down a little bit, but it remains really high.

How can I prevent this from happening? (Bear in mind that I'm far from being a Python/Kivy expert, so even if the solution is really obvious to you, please try to explain it to me!)

Upvotes: 3

Views: 2372

Answers (1)

qua-non
qua-non

Reputation: 4182

popup.dismiss() will not remove the popup from memory immediately.

Maybe this will help How to force deletion of a python object?

Second; on why sometimes your popups get dismissed and sometimes they don't, you have to understand that UI frameworks need to be programmed using events. Events/progression do not happen in linear fashion.

Kivy events loop

Better test for what you are trying to check would be using Clock

    self.pops = 0
    Clock.schedule_once(self.test_pops)

def test_pops(self, dt):
    if self.pops > 10:
        return
    self.pops += 1
    pup = self.MyPopup()
    pup.bind(on_parent=self.dismiss_pup)
    pup.open()

def dismiss_pup(self, pup, parent)
    # popup was opened, please close it now
    pup.unbind(on_parent=self.dismiss_pup)
    pup.dismiss()
    Clock.schedule_once(self.test_pops)

It would be a lot simpler to just use the web debugger module geared towards this instead though.

http://kivy.org/docs/api-kivy.modules.webdebugger.html

Upvotes: 2

Related Questions