def test_signal_list_ids(self): with self.assertRaisesRegex(TypeError, 'type must be instantiable or an interface.*'): GObject.signal_list_ids(GObject.TYPE_INT) ids = GObject.signal_list_ids(C) self.assertEqual(len(ids), 1) # Note canonicalized names self.assertEqual(GObject.signal_name(ids[0]), 'my-signal') # There is no signal 0 in gobject self.assertEqual(GObject.signal_name(0), None)
def test_signal_list_ids(self): with self.assertRaisesRegex( TypeError, 'type must be instantiable or an interface.*'): GObject.signal_list_ids(GObject.TYPE_INT) ids = GObject.signal_list_ids(C) self.assertEqual(len(ids), 1) # Note canonicalized names self.assertEqual(GObject.signal_name(ids[0]), 'my-signal') # There is no signal 0 in gobject self.assertEqual(GObject.signal_name(0), None)
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)
def test_signal_lookup(self): ids = GObject.signal_list_ids(C) self.assertEqual(ids[0], GObject.signal_lookup('my_signal', C)) self.assertEqual(ids[0], GObject.signal_lookup('my-signal', C)) with self.assertRaisesRegex( TypeError, 'type must be instantiable or an interface.*'): GObject.signal_lookup('NOT_A_SIGNAL_NAME', GObject.TYPE_INT) # Invalid signal names return 0 instead of raising self.assertEqual(GObject.signal_lookup('NOT_A_SIGNAL_NAME', C), 0)
def test_signal_lookup(self): ids = GObject.signal_list_ids(C) self.assertEqual(ids[0], GObject.signal_lookup('my_signal', C)) self.assertEqual(ids[0], GObject.signal_lookup('my-signal', C)) with self.assertRaisesRegex(TypeError, 'type must be instantiable or an interface.*'): GObject.signal_lookup('NOT_A_SIGNAL_NAME', GObject.TYPE_INT) # Invalid signal names return 0 instead of raising self.assertEqual(GObject.signal_lookup('NOT_A_SIGNAL_NAME', C), 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
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
def test_signal_query(self): my_signal_id, = GObject.signal_list_ids(C) # Form is: (id, name, gtype, arg_count, return_type, (arg_type1, ...)) my_signal_expected_query_result = [my_signal_id, 'my-signal', C.__gtype__, 1, GObject.TYPE_NONE, (GObject.TYPE_INT,)] # signal_query(name, type) self.assertEqual(list(GObject.signal_query('my-signal', C)), my_signal_expected_query_result) # signal_query(signal_id) self.assertEqual(list(GObject.signal_query(my_signal_id)), my_signal_expected_query_result) # invalid query returns None instead of raising self.assertEqual(GObject.signal_query(0), None) self.assertEqual(GObject.signal_query('NOT_A_SIGNAL', C), None)
def test_signal_query(self): my_signal_id, = GObject.signal_list_ids(C) # Form is: (id, name, gtype, arg_count, return_type, (arg_type1, ...)) my_signal_expected_query_result = [ my_signal_id, 'my-signal', C.__gtype__, 1, GObject.TYPE_NONE, (GObject.TYPE_INT, ) ] # signal_query(name, type) self.assertEqual(list(GObject.signal_query('my-signal', C)), my_signal_expected_query_result) # signal_query(signal_id) self.assertEqual(list(GObject.signal_query(my_signal_id)), my_signal_expected_query_result) # invalid query returns None instead of raising self.assertEqual(GObject.signal_query(0), None) self.assertEqual(GObject.signal_query('NOT_A_SIGNAL', C), None)
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))
def test_signal_list_ids_with_invalid_type(self): with self.assertRaisesRegex( TypeError, 'type must be instantiable or an interface.*'): GObject.signal_list_ids(GObject.TYPE_INVALID)
def reset(self): signals = list(GObject.signal_list_ids(type=Gtk.Widget)) signals = filter(lambda s: self.handler_is_connected(s), signals) for s in signals: self.disconnect(s)
def test_signal_list_ids_with_invalid_type(self): with self.assertRaisesRegex(TypeError, 'type must be instantiable or an interface.*'): GObject.signal_list_ids(GObject.TYPE_INVALID)