GObject物件系統 3

2021-05-22 11:37:16 字數 4370 閱讀 4133

在gobject系統中,訊號是一種定製物件行為的手段,同時也是一種多種用途的通知機制。初學者可能是在gtk+中首先接觸到訊號這一概念的,事實上在普通的字元介面程式設計中也可以正常應用,這可能是很多初學者未曾想到的。

乙個物件可以沒有訊號,也可以有多個訊號。當有一或多個訊號時,訊號的名稱定義是必不可少的,此時c語言的列舉型別的功能就凸顯出來了,用last_signal來表示最後乙個訊號(不用實現的訊號)是一種非常良好的程式設計風格。這裡為boy物件定義了乙個訊號boy_born,在物件建立時發出,表示boy物件誕生。

同時還需要定義靜態的整型指標陣列來儲存訊號的標識,以便於下一步處理訊號時使用。

物件的類結構是所有物件的例項所共有的,我們將訊號也定義在物件的類結構中,如此訊號同樣也是所有物件的例項所共有的,任意乙個物件的例項都可以處理訊號。因此我們有必要在在類初始化函式中建立訊號(這也可能是gobject設計者的初衷)。函式g_signal_new用來建立乙個新的訊號,它的詳細使用方法可以在gobject的api文件中找到。訊號建立成功後,返回乙個訊號的標識id,如此就可以用發射訊號函式g_signal_emit向指定義物件的例項發射訊號,從而執行相應的功能。

本例中每建立乙個新的boy物件,就會發射一次boy_born訊號,也就會執行一次我們定義的boy_born函式,也就輸出一行"message : a boy was born ."資訊。

物件例項所有的屬性和方法一般都定義在物件的例項結構中,屬性定義為變數或變數指標,而方法則定義為函式指標,如此,我們一定要定義函式為static型別,當為函式指標賦值時,才能有效。

以下為繼承自boy物件的man物件的實現,man物件在boy物件的基礎上又增加了乙個屬性job和乙個方法bye。

#ifndef __man_h__

#define __man_h__

#include "boy.h"
#define man_type  ( man_get_type() )

#define man(obj) ( g_type_check_instance_cast ( (obj), man_type, man ) )

typedef struct _man man;

typedef struct _manclass manclass;

struct _man ;
struct _manclass ;
gtype man_get_type ( void );
man*  man_new ( void );
gchar* man_get_job ( man *man );
void  man_set_job ( man *man, gchar *job );
man*  man_new_with_name_age_and_job ( gchar *name, gint age, gchar *job );
void man_info ( man *man );
#endif //__man_h__
/* man.c */
#include "man.h"
static void man_bye ( void );

static void man_init ( man *man );

static void man_class_init ( man *man );

gtype man_get_type ( void )

; man_type = g_type_register_static ( boy_type, "man", &man_info, 0);

} return man_type;

}

static void man_init ( man *man )

static void man_class_init ( man *man )

man*  man_new ( void )

gchar* man_get_gob ( man *man )

void  man_set_job ( man *man, gchar *job )

man*  man_new_with_name_age_and_job ( gchar *name, gint age, gchar *job )

static void man_bye(void)

void man_info(man *man)

關鍵在於定義物件時將父物件例項定義為boy,父類設定為boyclass,在註冊此物件時將其父物件型別設為boy_type,
在設定物件屬性時如用到父物件的屬性要強制轉換下,如取得物件的name屬性,就必須用boy(obj)->name,因為man本身沒有name屬性,
而其父物件boy有,所以用boy巨集將其強制為boy型別的物件。
#include #include "boy.h"

#include "man.h"

int main ( int argc, char *argv )

makefile檔案如下:

cc = gcc

all:

$(cc) -c boy.c `pkg-config --cflags glib-2.0 gobject-2.0`

$(cc) -c man.c `pkg-config --cflags glib-2.0 gobject-2.0`

$(cc) -c main.c `pkg-config --cflags glib-2.0 gobject-2.0`

$(cc) -o ****** boy.o man.o main.o `pkg-config --libs glib-2.0 gobject-2.0`

執行make命令編譯,編譯結束後,執行./******執行此測試程式,輸出結果如下:
message : a boy was born .
the boy is crying ......
the boy name is tom
the boy age is 0
message : a boy was born .
the boy is crying ......
the boy name is peter
the boy age is 10
goodbye everyone !
the man name is green
the man age is 28
the man job is doctor
goodbye everyone !
the man name is brown
the man age is 30
the man job is teacher
makefile中用到`pkg-config -cflags -libs gobject-2.0`,在glib中將執行緒(gthread),外掛程式(gmoudle)和物件系統(gobject)

這三個子系統區別對待,編譯時要注意加入相應的引數。

如:列舉和標識型別(enumeration and flags types);gboxed,是gtype系統中註冊一種封裝為不透明的c語言結構型別的機制;

許多物件用到的引數物件都是c結構型別,使用者不必了解其結構的內部定義,即不透明,gboxed即是實現這一功能的機制;

標準的引數和變數型別的定義(standard parameter and value types)等,它們都以c語言來開發,是深入了解和掌握gobject的關鍵。

透過以上**實現,我們還可以看出,以glib為基礎的gtk+/gnome開發環境所具有的獨特的程式設計風格和獨到的開發思想。

這一點在長期的程式設計實踐中會體驗得更深刻。

有了gobject系統這一基礎,gtk+通過它將x視窗環境中的控制項(widget)巧妙的封裝起來,這使開發linux平台上的gui應用程式

更方便,更快捷。

以上**在redhat 8.0 linux平台,glib2.2.1環境下編譯通過。

thomas hunger寫的文章: gobject tutorial

中國 linux 論壇的網友 hoyt 的網頁 http://gtkvb.cosoft.org.cn/上的文章 

與本文相關的另一篇文章 《**glib》

宋國偉,鄉村小學英語教師,他是《gtk+2.0程式設計範例》(清華大學出版社出版)一書的作者,業餘時間致力於用gtk+開發linux gui應用程式,可以通過電子郵件位址 [email protected]與他聯絡。

GObject物件系統

簡單的說,gobject物件系統是乙個建立在glib基礎上的,用c語言完成的,具有跨平台特色的 靈活的 可擴充套件的 非常容易對映到其它語言的物件導向的框架。如果你是乙個c語言的執著的追隨者,你沒有理由不研究一下它。前言 大多數現代的計算機語言都帶有自己的型別和物件系統,並附帶演算法結構。正象gli...

gobject物件不宜作為動態載入的外掛程式

前段時間對 syncmanager進行重構,為了減少不必要的開銷,我決定在需要時才加syncsource外掛程式,不需要時就解除安裝它們。在測試時發現第一次執行時正 常,第二次執行時建立dbpersistance物件時失敗了。仔細看了下除錯資訊,裡面告訴我說註冊dbpersistance型別失敗,因...

如何定義和實現新的GObject之物件構造和析構

1 物件構造 在嘗試構建自己的gobjects時人們常常會感到困惑,因為它們有很多不同的方法來實現物件的構造過程 很難確定哪個是正確的方法。表4中,g object new 顯示了在物件例項化過程中呼叫的使用者提供的函式以及它們被呼叫的順序。instance init函式相當於c 中的建構函式。在所...