Справочное описание GObject |
---|
Начиная с версии glib 2.4, GObject интерфейсы могут также иметь свойства.
Декларация свойств интерфейса похожа на декларацию свойств обычных типов GObject как показано в
“Object properties”,
исключая то, что g_object_interface_install_property
используется для декларации свойств вместо g_object_class_install_property
.
Для включения свойства с именем 'name' типа string в код выше приведённого примера интерфейса
maman_ibaz, нам нужно добавить только одну[14]
строчку в maman_ibaz_base_init
[15]
как показано ниже:
static void
maman_ibaz_base_init (gpointer g_iface)
{
static gboolean initialized = FALSE;
if (!initialized) {
/* здесь создаём сигналы интерфейса. */
g_object_interface_install_property (g_iface,
g_param_spec_string ("name",
"maman_ibaz_name",
"Name of the MamanIbaz",
"maman",
G_PARAM_READWRITE));
initialized = TRUE;
}
}
Одно замечание - задекларированному свойству не был присвоен целочисленный ID. Причина в том, что целочисленный ID этого свойства используется только внутри методов получения и установки, а так как интерфейс не реализует свойства, нет необходимости привязывать целочисленный ID к свойствам интерфейса.
История для конструкторов интерфейса также весьма тривиальна.
Конструктор должен задекларировать и определить свойства обычным способом как описано в
the section called “Object properties”,
за исключением одной мелочи: он должен задекларировать свойства интерфейса используя
g_object_class_override_property
вместо
g_object_class_install_property
.
Следующий код демонстрирует изменения необходимые в декларации и реализации MamanBaz показанной выше:
struct _MamanBaz {
GObject parent;
gint instance_member;
gchar *name; /* метка для свойства */
};
enum
{
ARG_0,
ARG_NAME
};
GType
maman_baz_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GTypeInfo info = {
sizeof (MamanBazClass),
NULL, /* base_init */
NULL, /* base_finalize */
baz_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (MamanBaz),
0, /* n_preallocs */
baz_instance_init /* instance_init */
};
static const GInterfaceInfo ibaz_info = {
(GInterfaceInitFunc) baz_interface_init, /* interface_init */
NULL, /* interface_finalize */
NULL /* interface_data */
};
type = g_type_register_static (G_TYPE_OBJECT,
"MamanBazType",
&info, 0);
g_type_add_interface_static (type,
MAMAN_TYPE_IBAZ,
&ibaz_info);
}
return type;
}
static void
maman_baz_class_init (MamanBazClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_ref (G_TYPE_OBJECT);
gobject_class->set_property = maman_baz_set_property;
gobject_class->get_property = maman_baz_get_property;
g_object_class_override_property (gobject_class, ARG_NAME, "name");
}
static void
maman_baz_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
MamanBaz *baz;
GObject *obj;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (G_IS_MAMAN_BAZ (object));
baz = MAMAN_BAZ (object);
switch (prop_id) {
case ARG_NAME:
baz->name = g_value_get_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
maman_baz_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
MamanBaz *baz;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (G_IS_TEXT_PLUGIN (object));
baz = MAMAN_BAZ (object);
switch (prop_id) {
case ARG_NAME:
g_value_set_string (value, baz->name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
[14] Это действительно одна строка расширенная на шесть для ясности
[15]
g_object_interface_install_property
может также быть вызвана из
class_init
но её нельзя вызвать после этой точки.