用简单的方法来访问GObject对象的私有属性

这里只用到了最简单的方法,给我的感觉就是使用g_object_get/set函数来完成对已经安装的属性的存取工作。

目前我们还没有涉及到‘信号’这个NB的东西,连interface'接口'是什么,我也还没看到。

不过目前这点可怜的知识,能够对看懂gdk的源码产生一定的帮助了。

至少那些.h中的茫茫多的枚举和结构体的存在理由已经被我们找到了。

#include<glib-object.h>

#define SOME_OBJECT_TYPE		(some_object_get_type())
#define SOME_OBJECT(obj)		(G_TYPE_CHECK_INSTANCE_CAST((obj), SOME_OBJECT_TYPE, SomeObject))
#define SOME_IS_OBJECT(obj)		(GTYPE_CHECK_TYPE((obj), SOME_OBJECT_TYPE))
#define SOME_OBJECT_CLASS(c)		(G_TYPE_CHECK_CLASS_CAST((c), SOME_OBJECT_TYPE,SomeObjectClass))
#define SOME_IS_OBJECT_CLASS(c)		(G_TYPE_CHECK_CLASS_TYPE((c), SOME_OBJECT_TYPE))
#define SOME_OBJECT_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), SOME_OBJECT_TYPE, SomeObjectClass))
#define SOME_OBJECT_GET_PRIVATE(obj)	(G_TYPE_INSTANCE_GET_PRIVATE((obj), SOME_OBJECT_TYPE, SomeObjectPrivate))

typedef struct _SomeObject		SomeObject;
typedef struct _SomeObjectClass		SomeObjectClass;
typedef struct _SomeObjectPrivate	SomeObjectPrivate;

struct _SomeObject {
	GObject parent_obj;
	SomeObjectPrivate *priv;
};

struct _SomeObjectClass {
	GObjectClass parent_class;
	void (*born)(void);			// 出生
	void (*grow)(SomeObject *self);		// 成长
};

struct _SomeObjectPrivate {
	guint age;
	gchar *name;
};

enum 
{
	OBJECT_PROPERTY_0,
	OBJECT_PROPERTY_AGE,
	OBJECT_PROPERTY_NAME,
	OBJECT_PROPERTY_BORN,
	OBJECT_PROPERTY_GROW
};

void some_object_grow(SomeObject *self);
void some_object_give_name(SomeObject *self, gchar *name);

G_DEFINE_TYPE (SomeObject, some_object, G_TYPE_OBJECT)

void some_object_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
	SomeObject *self = SOME_OBJECT(object);

	switch(property_id) {
		case OBJECT_PROPERTY_AGE:
			self->priv->age = g_value_get_uint(value);
			g_print("%s age: %d.\n",__func__, self->priv->age);
			break;
		case OBJECT_PROPERTY_NAME:
			g_free(self->priv->name);
			self->priv->name = g_value_dup_string(value);
			g_print("%s name: %s.\n", __func__, self->priv->name);
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
			break;
	}
}

void some_object_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
	SomeObject *self = SOME_OBJECT(object);

	switch (property_id) {
		case OBJECT_PROPERTY_AGE:
			g_value_set_uint(value, self->priv->age);
			break;
		case OBJECT_PROPERTY_NAME:
			g_value_set_string(value, self->priv->name);
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
			break;
	}
}

static void born(void)
{
	g_print("a object was born.\n");
}

static void grow(SomeObject *self)
{
	guint age =0;
	g_object_get(G_OBJECT(self), "property-age", &age, NULL);
	age += 1;
	g_object_set(G_OBJECT(self), "property-age", age, NULL);
}

void some_object_dispose(GObject *gobject)
{
	SomeObject *slef = SOME_OBJECT(gobject);
	g_print("-- %s # %i\n",__func__, __LINE__);
	G_OBJECT_CLASS(some_object_parent_class)->dispose(gobject);
}

void some_object_finalize(GObject *gobject)
{
	SomeObject *self = SOME_OBJECT(gobject);
	g_free(self->priv->name);
	g_print("-- %s # %i\n",__func__, __LINE__);
	G_OBJECT_CLASS(some_object_parent_class)->finalize(gobject);
}

static void some_object_class_init(SomeObjectClass* g_class)
{
	g_type_class_add_private(g_class, sizeof(SomeObjectPrivate));

	GObjectClass *this_class = G_OBJECT_CLASS(g_class);
	GParamSpec *spec;

	g_print("-- %s # %i\n",__func__, __LINE__);
	this_class->dispose = &some_object_dispose;
	this_class->finalize = &some_object_finalize;
	this_class->set_property = &some_object_set_property;
	this_class->get_property = &some_object_get_property;

	spec = g_param_spec_uint("property-age",
		                "the age",
				"Set/Get age",
				0,
				150,
				0,
				G_PARAM_READWRITE);
	g_object_class_install_property(this_class, OBJECT_PROPERTY_AGE, spec);
	spec = g_param_spec_string("property-name",
		                "the name",
				"Set/Get name",
				"no-name-set",
				G_PARAM_READWRITE);
	g_object_class_install_property(this_class, OBJECT_PROPERTY_NAME, spec);
}

void some_object_init(SomeObject *self)
{
	SomeObjectPrivate *priv;
	born();
	self->priv = priv = SOME_OBJECT_GET_PRIVATE(self);
	priv->age = 0;
	priv->name = g_strdup("no-name");
	g_print("-- %s # %i\n",__func__, __LINE__);
	g_object_set(G_OBJECT(self),"property-age",0,"property-name","no-name",NULL);
}

void some_object_grow(SomeObject *self)
{
	grow(self);
	guint age = 0;
	g_object_get(G_OBJECT(self),"property-age", &age, NULL);
	g_print("%s I'm %d years old.\n",__func__, age);
}

void some_object_give_name(SomeObject *self, gchar *name)
{
	g_object_set(G_OBJECT(self), "property-name", name, NULL);
	g_print("%s hi, my name is %s.\n",__func__, name);
}

int main()
{
	g_print("****init the type system****\n");
	g_type_init();
	g_print("****init type system OK ****\n");
	SomeObject *testobj = g_object_new(SOME_OBJECT_TYPE, NULL);;
	some_object_give_name(testobj, "Tom");
	some_object_grow(testobj);
	some_object_grow(testobj);
	some_object_grow(testobj);
	g_object_unref(testobj);
	g_print("****finish GObject Demo ****\n");
	return 0;
}
Makefile:

all:
	gcc `pkg-config --cflags --libs gobject-2.0` someobject.c -o test

输出结果:

****init the type system****
****init type system OK ****
-- some_object_class_init # 117
a object was born.
-- some_object_init # 146
some_object_set_property age: 0.
some_object_set_property name: no-name.
some_object_set_property name: Tom.
some_object_give_name hi, my name is Tom.
some_object_set_property age: 1.
some_object_grow I'm 1 years old.
some_object_set_property age: 2.
some_object_grow I'm 2 years old.
some_object_set_property age: 3.
some_object_grow I'm 3 years old.
-- some_object_dispose # 98
-- some_object_finalize # 106
****finish GObject Demo ****

虽然我们的技巧还很烂,不过能够交互了不是么,O(∩_∩)O哈哈哈~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值