def auto_connect_by_name(callback_obj, builder):
    '''finds handlers like on_<widget_name>_<signal> and connects them

    i.e. find widget,signal pair in builder and call
    widget.connect(signal, on_<widget_name>_<signal>)'''

    callback_handler_dict = dict_from_callback_obj(callback_obj)

    for item in builder.widgets.items():
        (widget_name, widget) = item
        signal_ids = []
        try:
            widget_type = type(widget)
            while widget_type:
                signal_ids.extend(GObject.signal_list_ids(widget_type))
                widget_type = GObject.type_parent(widget_type)
        except RuntimeError:  # pylint wants a specific error
            pass
        signal_names = [GObject.signal_name(sid) for sid in signal_ids]

        # Now, automatically find any the user didn't specify in glade
        for sig in signal_names:
            # using convention suggested by glade
            handler_names = ["on_%s_%s" % (widget_name, sig)]

            # Using the convention that the top level window is not
            # specified in the handler name. That is use
            # on_destroy() instead of on_windowname_destroy()
            if widget is callback_obj:
                handler_names.append("on_%s" % sig)

            do_connect(item, sig, handler_names, callback_handler_dict,
                       builder.connections)

    log_unconnected_functions(callback_handler_dict, builder.connections)
Example #2
0
def auto_connect_by_name(callback_obj, builder):
    '''finds handlers like on_<widget_name>_<signal> and connects them

    i.e. find widget,signal pair in builder and call
    widget.connect(signal, on_<widget_name>_<signal>)'''

    callback_handler_dict = dict_from_callback_obj(callback_obj)

    for item in builder.widgets.items():
        (widget_name, widget) = item
        signal_ids = []
        try:
            widget_type = type(widget)
            while widget_type:
                signal_ids.extend(GObject.signal_list_ids(widget_type))
                widget_type = GObject.type_parent(widget_type)
        except RuntimeError:  # pylint wants a specific error
            pass
        signal_names = [GObject.signal_name(sid) for sid in signal_ids]

        # Now, automatically find any the user didn't specify in glade
        for sig in signal_names:
            # using convention suggested by glade
            handler_names = ["on_%s_%s" % (widget_name, sig)]

            # Using the convention that the top level window is not
            # specified in the handler name. That is use
            # on_destroy() instead of on_windowname_destroy()
            if widget is callback_obj:
                handler_names.append("on_%s" % sig)

            do_connect(item, sig, handler_names,
             callback_handler_dict, builder.connections)

    log_unconnected_functions(callback_handler_dict, builder.connections)
Example #3
0
 def __get_signals(self, widget):
     '''Return the signals of the widget'''
     signal_ids = []
     try:
         widget_type = type(widget)
         while widget_type:
             signal_ids.extend(GObject.signal_list_ids(widget_type))
             widget_type = GObject.type_parent(widget_type)
     except RuntimeError:
         pass
     signal_names = [GObject.signal_name(sid) for sid in signal_ids]
     return signal_names
Example #4
0
def _get_signal_ids(itype):
    """
    Get a list of all signal names supported by the object

    :param itype: type (GObject.GType) - Instance or interface type.
    :returns: list of strings
    """
    try:
        parent_type = GObject.type_parent(itype)
        parent_signals = _get_signal_ids(parent_type)
    except RuntimeError:
        parent_signals = []
    return GObject.signal_list_ids(itype) + parent_signals
Example #5
0
def list_properties(gtype, parent=True):
    """
    Return a list of all properties for GType gtype, excluding
    properties in parent classes
    """
    pspecs = GObject.list_properties(gtype)
    if parent:
        return pspecs

    parent = GObject.type_parent(gtype)

    parent_pspecs = GObject.list_properties(parent)
    return [pspec for pspec in pspecs
            if pspec not in parent_pspecs]
Example #6
0
    def parse_one(self, toplevel, gobj):
        if not isinstance(gobj, GObject.GObject):
            raise TypeError

        gtype = gobj
        while True:
            name = GObject.type_name(gtype)
            func = getattr(self, name, None)
            if func:
                if func(toplevel, gobj):
                    break
            if gtype == GObject.GObject.__gtype__:
                break

            gtype = GObject.type_parent(gtype)
Example #7
0
    def parse_one(self, toplevel, gobj):
        if not isinstance(gobj, GObject.GObject):
            raise TypeError

        gtype = gobj
        while True:
            name = GObject.type_name(gtype)
            func = getattr(self, name, None)
            if func:
                if func(toplevel, gobj):
                    break
            if gtype == GObject.GObject.__gtype__:
                break

            gtype = GObject.type_parent(gtype)
Example #8
0
    def __init__(self, builder, callback_obj=None, autoconnect=True):
        "Takes a gtk.Builder and makes all its objects easily accessible"

        unconnected_funcs = []

        # Hook up any signals the user defined in glade
        if callback_obj is not None:
            builder.connect_signals(callback_obj)

            # This function list is used below, but created once here
            funcs = dict(inspect.getmembers(callback_obj, inspect.ismethod))

            # test for typos in event handlers
            unconnected_funcs = funcs.keys()

        # Support 'for o in self'
        def iterator():
            return iter(builder.get_objects())

        setattr(self, '__iter__', iterator)

        names = {}
        for obj in self:
            if issubclass(type(obj), gtk.Buildable):
                name = gtk.Buildable.get_name(obj)
            else:
                # The below line is the ideal, but it causes a segfault.
                # See https://bugzilla.gnome.org/show_bug.cgi?id=633727
                #name = obj.get_data('gtk-builder-name')
                # So since we can't get name, just skip this one
                continue
            names[name] = obj

        # Support self.label1
        for (name, obj) in names.items():
            if not hasattr(self, name):
                setattr(self, name, obj)

        # This function mangles non-python names into python ones (used below)
        def make_pyname(name):
            pyname = ''
            for l in name:
                if (l in string.ascii_letters or l == '_'
                        or (pyname and l in string.digits)):
                    pyname += l
                else:
                    pyname += '_'
            return pyname

        # Mangle any bad names (like with spaces or dashes) into usable ones
        for (name, obj) in names.items():
            pyname = make_pyname(name)
            if pyname != name:
                if hasattr(self, pyname):
                    print >> sys.stderr, "BuilderGlue: Not binding %s, name already exists" % pyname
                else:
                    setattr(self, pyname, obj)

            # Support hooking up callback functions defined in callback_obj
            if callback_obj is not None and autoconnect:
                # Now, automatically find any the user didn't specify
                sig_ids = []
                try:
                    t = type(obj)
                    while t:
                        sig_ids.extend(GObject.signal_list_ids(t))
                        t = GObject.type_parent(t)
                except:
                    pass
                sigs = [GObject.signal_name(sid) for sid in sig_ids]

                def connect_if_present(sig, cb_name):
                    if cb_name in funcs:
                        obj.connect(sig, funcs[cb_name])
                        unconnected_funcs.remove(cb_name)

                # We avoid clearer on_OBJ_SIG pattern, because that is
                # suggested by glade, and we don't have a way to detect if
                # the user already defined a callback in glade.
                for sig in sigs:
                    connect_if_present(sig, "%s_%s_event" % (pyname, sig))
                    # Special case where callback_obj is itself a builder obj
                    if obj is callback_obj:
                        connect_if_present(sig, "%s_event" % sig)

        unconnected_event_handlers = [
            x for x in unconnected_funcs if '_event' in x
        ]
        for event_handler in unconnected_event_handlers:
            logging.warn(
                '%s.%s looks like a signal handler, but no signal was found to connect to it!'
                % (callback_obj, event_handler))
Example #9
0
 def test_type_parent(self):
     self.assertEqual(GObject.type_parent(CustomChild), CustomBase.__gtype__)
     self.assertEqual(GObject.type_parent(CustomBase), GObject.TYPE_OBJECT)
     self.assertRaises(RuntimeError, GObject.type_parent, GObject.GObject)
Example #10
0
 def test_type_parent(self):
     self.assertEqual(GObject.type_parent(CustomChild),
                      CustomBase.__gtype__)
     self.assertEqual(GObject.type_parent(CustomBase), GObject.TYPE_OBJECT)
     self.assertRaises(RuntimeError, GObject.type_parent, GObject.GObject)