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;
}
相關文章
- Object物件的屬性Object物件
- javascript原型物件的屬性不能夠覆蓋物件自有屬性JavaScript原型物件
- js物件屬性JS物件
- 理解 JavaScript 物件的屬性JavaScript物件
- XMLHttpRequest物件的status屬性XMLHTTP物件
- XMLHttpRequest物件的responseXML屬性XMLHTTP物件
- JavaScript ----- 操作DOM物件的屬性JavaScript物件
- JavaScript遍歷物件的屬性JavaScript物件
- 連結a物件的pathname屬性物件
- js的屬性物件的specified屬性用法簡單介紹JS物件
- JavaScript物件的資料屬性與訪問器屬性JavaScript物件
- DataView物件buffer屬性View物件
- 修改物件私有屬性物件
- javascript基礎(物件,物件屬性,屬性基本和引用資料型別,字面量建立物件,垃圾回收,屬性的列舉)(十三)JavaScript物件資料型別
- CAD屬性編輯操作——物件屬性教程物件
- python物件屬性管理(2):property管理屬性Python物件
- javascript獲取物件直接量中的屬性和屬性值JavaScript物件
- css屬性與js中style物件的屬性對應表CSSJS物件
- Python深入03 物件的屬性Python物件
- 數字作為物件的屬性物件
- JavaScript物件屬性是有序的嗎?JavaScript物件
- Scala的類、屬性、物件欄位物件
- Unity遍歷物件serialized的屬性Unity物件Zed
- 理解物件以及物件的屬性、方法、事件 (轉)物件事件
- 深入理解物件的資料屬性與訪問器屬性物件
- 獲取物件屬性型別、屬性名稱、屬性值的研究:反射和JEXL解析引擎物件型別反射
- Python - 物件導向程式設計 - 公共屬性、保護屬性、私有屬性Python物件程式設計
- JavaScript訪問物件的屬性和方法JavaScript物件
- Python深入分享之物件的屬性Python物件
- jQuery事件物件event的屬性和方法jQuery事件物件
- Array String物件的方法和屬性物件
- 移出Json物件的三級屬性JSON物件
- jquery 事件物件屬性小結jQuery事件物件
- js 物件方法、類方法、原型方法的區別;私有屬性、公有屬性、公有靜態屬性的區別JS物件原型
- 重新認識javascript物件(一)——物件及其屬性JavaScript物件
- 陣列物件按物件某個屬性排序陣列物件排序
- 波哥學JAVA,定義類 宣告屬性 建立物件 例項化物件 物件呼叫屬性或者方法Java物件
- Python __dict__屬性:檢視物件內部所有屬性名和屬性值組成的字典Python物件