2013-05-15 80 views
1

我嘗試繼承gobject,並且除其他外,希望更改G_PARAM_CONSTRUCT_ONLY屬性的值,以便下一個子類不必關心。通過繼承來更改G_PARAM_CONSTRUCT_ONLY屬性

下面是一個例子來描述這個:GtkComboBox有一個構造唯一屬性,名爲「has-entry」,默認值爲FALSE。在A類中,我想將此值更改爲TRUE,以便B類不需要關心。

  GtkComboBoxClass <-- AClass <-- BClass 
"has-entry"  FALSE   TRUE 

第一個幼稚的做法是使用g_object_set()在A的INSTANCE_INIT功能,但無濟於事。

下一個想法是使用g_object_class_find_property()獲取GParamSpec,並在A的class_init函數中使用g_param_value_set_default()更改默認值。但我想這是爲了更改所有GtkComboBoxClass派生對象的默認值。

我可以想出最好的想法:如果g_object_class_override_property()創建一個新的GParamSpec,我可以找到它並在A的class_init函數中設置其默認值。但是文檔對此沒有任何評論。

所以我的問題:這是一個工作,並打算,完成此方式,或者有更好的解決方案?

試過至今:

  • g_object_set()的實例的init():在GObjectClass-
    • 在啓動任何警告
    • 沒有影響
  • g_object_set()>構造函數():
    • 開始時沒有警告
    • 沒有影響
    • 警告退出:從GtkCellCiew無效轉換到在GtkEntry中GObjectClass-
  • g_object_set()>構造():在啓動
    • 警告:不能施工
    • 後設置

感謝 斯特凡

回答

3

如果你想在一個子類中設置一個屬性,並且該屬性是隻構造的,那麼你應該使用虛擬函數constructed來調用g_object_set()而不是虛擬的init

標記爲構造專用的屬性將在構造過程中使用它們的默認值應用,除非在構造函數本身上指定 - 即使用g_object_new()。這意味着在init()中設置只構造屬性是不夠的,因爲在調用init()之後將會設置該值。另一方面,在應用構造函數屬性後調用虛函數,因此可以在其中覆蓋默認值。

+0

嘗試使用glib-2.28.8。獲取:GLib-GObject-WARNING **:g_object_set_valist:對象TestComboBox的構造屬性「has-entry」在構造後不能設置 – user2011659

1

回答這個我自己:

走進一看GObject的來源表明,給構造函數()屬性列表中包含了所有G_PARAM_CONSTRUCT和G_PARAM_CONSTRUCT_ONLY屬性及其默認或給定的值。

修改這些值沒有記錄(或至少我找不到它),但它的工作原理。 構建時間屬性值必須在鏈接到父項構造函數之前在此列表中進行修改,之後必須設置非構造屬性。示例代碼如下所示:

static GObject *constructor(GType gtype, guint n_properties, GObjectConstructParam *properties) { 
    GObject *object; 
    guint i; 
    gchar const *name; 
    GObjectConstructParam *property; 

    for (i = 0, property = properties; i < n_properties; ++i, ++property) { 
     name = g_param_spec_get_name(property->pspec); 
     if (!strcmp(name, "has-entry")) // is G_PARAM_CONSTRUCT_ONLY 
      g_value_set_boolean(property->value, TRUE); 
    } 

    object = G_OBJECT_CLASS(parent_class)->constructor(gtype, n_properties, properties); 

    g_object_set(object, "entry-text-column", TEXT_COLUMN, NULL); 

    return object; 
}