通过继承更改G_PARAM_CONSTRUCT_ONLY属性

时间:2013-05-15 06:01:49

标签: gtk gobject

我尝试继承gobject,除其他外,想要更改G_PARAM_CONSTRUCT_ONLY属性的值,以便下一个子类不必关心。

这是一个描述这个的例子:GtkComboBox有一个名为“has-entry”的构造属性,默认值为FALSE。在A类中,我想将此值更改为TRUE,因此B类无需关心。

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

第一个天真的方法是在A的instance_init函数中使用g_object_set(),但无济于事。

下一个想法是使用g_object_class_find_property()获取GParamSpec,并使用A的class_init函数中的g_param_value_set_default()更改默认值。但我想这是为了更改所有GtkComboBoxClass派生对象的默认值。

我能想到的最好的想法:如果g_object_class_override_property()创建一个新的GParamSpec,我可以找到它并在A的class_init函数中设置它的默认值。但是文档并没有说清楚这一点。

所以我的问题:这是一种有效的,有意的实现方式,还是有更好的解决方案?

到目前为止尝试过:

    实例init()中的
  • g_object_set():
    • 启动时没有警告
    • 没效果
  • GObjectClass-&gt;构造函数()中的
  • g_object_set():
    • 启动时没有警告
    • 没效果
    • 退出时出现
    • 警告:从GtkCellCiew到GtkEntry的无效演员
  • GObjectClass-&gt; construct()中的
  • g_object_set():
    • 启动时警告:施工后无法设置

由于 斯蒂芬

2 个答案:

答案 0 :(得分:3)

如果要在子类中设置属性,并且该属性仅为构造,则应使用constructed虚函数调用g_object_set()而不是init虚拟。

标记为仅构造的属性将在构造期间使用其默认值应用,除非在构造函数本身上指定 - 即使用g_object_new()。这意味着在init()内设置仅构造属性是不够的,因为该值将在调用init()后设置。另一方面,constructed()虚函数在应用构造函数属性后调用,因此可以覆盖那里的默认值。

答案 1 :(得分:1)

为自己回答:

查看gobject源代码显示,给予constructor()的属性列表包含所有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;
}