GObject的对象属性

GObject的对象属性

 

glib对象系统中,一般的类都是从Gobject类继承过来的。尽管glib是用C语言开发的,它却几乎支持所有的面向对象的特性。这里不谈glib的面向对象机制,只是说说关于GObject对象属性的一些问题。

 

OOP中,对象的属性一般用成员变量来表示。编程高手常常告诫我们,把对象的属性隐藏起来,用成员函数去访问,可以减少与使用者之间的耦合,同时可以提高程序的健壮性。

 

实际上,仅仅是把对象的属性封装起来,有时是不够的。比如,你无法通过基类的指针去访问子类的属性。要做到这一点,需要把这些setter/getter函数实现成虚函数,在子类中去重载它们。不过,这样做会让基类的接口显示很庞杂,而且实际上你也无法预知子类中的会有哪些属性。

 

另外一个更重要问题是,有时候外部对象可能会关心某个对象的属性改变。比如,像对话框可能关心其上控件的属性的变化,控件的属性变化时,对话框需要做一些调整。如果能实现一种机制支持这种功能将有很大用处。

 

Gobject定义了两个函数(get_property/set_propery),用于存取对象的属性,在子类中重载这两个函数就行了,不用实现一大堆setter/getter函数,同时它提供了一种对象属性监视机制,在对象属性改变时通知相关关注者。

 

下面这个例子演示了以上所有功能:

 

/*

 * fooobject.h

 * Copyright (C) 2006 gclassfactory

 *

 * This library is free software; you can redistribute it and/or

 * modify it under the terms of the GNU Lesser General Public

 * License as published by the Free Software Foundation; either

 * version 2 of the License, or (at your option) any later version.

 *

 * This library is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

 * Lesser General Public License for more details.

 *

 * You should have received a copy of the GNU Lesser General Public

 * License along with this library; if not, write to the

 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,

 * Boston, MA 02111-1307, USA.

 */

#ifndef FOO_OBJECT_H

#define FOO_OBJECT_H

 

#include <glib.h>

#include <glib-object.h>

 

G_BEGIN_DECLS

 

#define FOO_TYPE_OBJECT                 (foo_object_get_type ())

#define FOO_OBJECT(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_OBJECT, FooObject))

#define FOO_OBJECT_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_OBJECT, FooObjectClass))

#define FOO_IS_OBJECT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_OBJECT))

#define FOO_IS_OBJECT_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_OBJECT))

#define FOO_OBJECT_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_OBJECT, FooObjectClass))

 

typedef struct _FooObject        FooObject;

typedef struct _FooObjectClass   FooObjectClass;

 

struct _FooObject

{

         GObject gobject;

 

         gint width;

         gint height;

         gboolean visible;

 

};

 

struct _FooObjectClass

{

         GObjectClass parent_class;

 

 

 

};

 

GType foo_object_get_type(void) G_GNUC_CONST;

FooObject* foo_object_new(void);

 

G_END_DECLS

 

#endif /*FOO_OBJECT_H*/

/*

 * fooobject.c

 * Copyright (C) 2006 gclassfactory

 *

 * This library is free software; you can redistribute it and/or

 * modify it under the terms of the GNU Lesser General Public

 * License as published by the Free Software Foundation; either

 * version 2 of the License, or (at your option) any later version.

 *

 * This library is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

 * Lesser General Public License for more details.

 *

 * You should have received a copy of the GNU Lesser General Public

 * License along with this library; if not, write to the

 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,

 * Boston, MA 02111-1307, USA.

 */

#include "fooobject.h"

 

enum {

         PROP_0,

         PROP_VISIBLE,

         PROP_WIDTH,

         PROP_HEIGHT,

         PROP_LAST

};

 

static GObjectClass* parent_class = NULL;

 

static void foo_object_class_init(FooObjectClass   *class);

static void foo_object_init      (FooObject        *object);

static void foo_object_set_property     (GObject        *object,

                                         guint           property_id,

                                         const GValue   *value,

                                         GParamSpec     *pspec);

static void foo_object_get_property     (GObject        *object,

                                         guint           property_id,

                                         GValue         *value,

                                         GParamSpec     *pspec);

GType

foo_object_get_type (void)

{

         static GType object_type = 0;

 

         if (!object_type)

         {

                   static const GTypeInfo object_info =

                   {

                            sizeof (FooObjectClass),

                            NULL,       /* base_init */

                            NULL,       /* base_finalize */

                            (GClassInitFunc) foo_object_class_init,

                            NULL,       /* class_finalize */

                            NULL,       /* class_data */

                            sizeof (FooObject),

                            0,      /* n_preallocs */

                            (GInstanceInitFunc) foo_object_init,

                   };

                  object_type = g_type_register_static (G_TYPE_OBJECT, "FooObject", &object_info, 0);

         };

 

         return object_type;

}

 

FooObject* foo_object_new(void)

{

         return (FooObject*)g_object_new(FOO_TYPE_OBJECT, 0);

}

 

static void foo_object_class_init(FooObjectClass   *class)

{

         GObjectClass* gobject_class = G_OBJECT_CLASS(class);

 

         gobject_class->set_property = foo_object_set_property;

         gobject_class->get_property = foo_object_get_property;

 

         g_object_class_install_property (gobject_class,

                   PROP_VISIBLE,

                   g_param_spec_boolean ("visible",

                             ("Visible"),

                             ("Whether the widget is visible"),

                             FALSE,

                             G_PARAM_READWRITE));

 

  g_object_class_install_property (gobject_class,

                   PROP_HEIGHT,

                   g_param_spec_int ("height",

                             ("Height"),

                             ("Override for height request of the widget, or -1 if natural request should be used"),

                             -1,

                             G_MAXINT,

                             -1,

                             G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,

                   PROP_WIDTH,

                   g_param_spec_int ("width",

                             ("Width request"),

                             ("Override for width request of the widget, or -1 if natural request should be used"),

                             -1,

                             G_MAXINT,

                             -1,

                             G_PARAM_READWRITE));

 

         return;

}

 

static void foo_object_init      (FooObject        *object)

{

         return;

}

 

static void foo_object_set_property     (GObject        *object,

                                         guint           property_id,

                                         const GValue   *value,

                                         GParamSpec     *pspec)

{

         FooObject* foo_object = FOO_OBJECT(object);

 

         switch(property_id)

         {

                   case PROP_VISIBLE:

                   {

                            foo_object->visible = g_value_get_boolean(value);

                            break;

                   }

                   case PROP_WIDTH:

                   {

                            foo_object->width = g_value_get_int(value);

                            break;

                   }

                   case PROP_HEIGHT:

                   {

                            foo_object->height = g_value_get_int(value);

                            break;

                   }

                   default:

                   {

                            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);

                            break;

                   }

         }

 

         return;

}

static void foo_object_get_property     (GObject        *object,

                                         guint           property_id,

                                         GValue         *value,

                                         GParamSpec     *pspec)

{

         FooObject* foo_object = FOO_OBJECT(object);

 

         switch(property_id)

         {

                   case PROP_VISIBLE:

                   {

                            g_value_set_boolean(value, foo_object->visible);

                            break;

                   }

                   case PROP_WIDTH:

                   {

                            g_value_set_int(value, foo_object->width);

                            break;

                   }

                   case PROP_HEIGHT:

                   {

                            g_value_set_int(value, foo_object->height);

                            break;

                   }

                   default:

                   {

                            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);

                            break;

                   }

         }

 

         return;

}

 

static void property_change (gpointer     data1,

         gpointer     arg_1,

         gpointer     data2)

{

         GParamSpec     *pspec = (GParamSpec*) arg_1;

 

         g_printf("property %s change/n", g_param_spec_get_name(pspec));

         return;

}

        

int main(int argc, char* argv[])

{

         GValue value = {0};

 

         FooObject* object = NULL;

        

         g_type_init();

        

         object = foo_object_new();

 

         g_signal_connect(G_OBJECT(object), "notify", G_CALLBACK(property_change), object);

         g_value_init(&value, G_TYPE_BOOLEAN);

         g_value_set_boolean(&value, TRUE);

         g_object_set_property(G_OBJECT(object), "visible", &value);

 

         g_value_unset(&value);

        

         g_value_init(&value, G_TYPE_INT);

        

         g_value_set_int(&value, 400);

         g_object_set_property(G_OBJECT(object), "width", &value);

        

         g_value_set_int(&value, 300);

         g_object_set_property(G_OBJECT(object), "height", &value);

        

         g_object_unref(object);

        

         return 0;

}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值