2013-05-15 45 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; 
}