我尝试继承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函数中设置它的默认值。但是文档并没有说清楚这一点。
所以我的问题:这是一种有效的,有意的实现方式,还是有更好的解决方案?
到目前为止尝试过:
由于 斯蒂芬
答案 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;
}