Re: python classes and signal connects



Hi Simon,

thanks for the detailed answer! See comments bellow.

On Mi, 2012-10-03 at 01:17 -0700, Simon Feltman wrote:
> 1) Don't rely on __del__ for cleanup, __del__ should generally be
> avoided as it doesn't work like a destructor in most languages, add an
> explicit method to cleanup the AddressInfo instance, clear out any
> held widgets by setting them to None, also issue the dbus disconnect
> within this and even disconnect signals if possible. 

Disconnecting signals produces segfaults. See
https://bugzilla.gnome.org/show_bug.cgi?id=685387 .

Setting the Widget to None works fine in the simple example. In d-feet,
I try to use GtkBuilder (with Glade) when possible. So attached is
another example (button-signal-gtkbuilder.py) where the solution "set
all Widgets to None" does no longer work. The example loads the widgets
from an ui xml definition and connects the signals with
gtk_builder_connect_signals().
The instances are never collected by python's gc.

Cheers,

Tom
from gi.repository import Gtk, GObject
import gc

UI = """
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <!-- interface-requires gtk+ 3.0 -->
  <object class="GtkButton" id="button">
    <property name="label" translatable="yes">button</property>
    <property name="visible">True</property>
    <property name="can_focus">True</property>
    <property name="receives_default">True</property>
    <signal name="clicked" handler="button_clicked_cb" swapped="no"/>
  </object>
</interface>
"""

class TestSignals(object):
    def __del__(self):
        print "Deleted object"

    def clean(self):
        self.button.destroy()
        self.button = None
        self.ui = None


    def __init__(self):
        self.ui = Gtk.Builder()
        self.myname = "Tom"
        self.ui.add_from_string(UI)
        self.ui.connect_signals({"button_clicked_cb" : self.button_clicked_cb})
        self.button = self.ui.get_object("button")
    
    def button_clicked_cb(self, button):
        print "button clicked and name is '%s'" % (self.myname)


if __name__ == "__main__":
    gc.collect()
    
    for i in range(0, 10):
        t = TestSignals()
        t.clean()
        gc.collect()

    print "instance generation finished (count: %s)" % (i)
    print "garbage is: ", gc.garbage
    gc.collect()
    raw_input("press enter to exit ...")


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]