有没有一种好的方法来复制一个Gtk小部件? [英] Is there a good way to copy a Gtk widget?
问题描述
GtkButton * a = g_object_new(GTK_TYPE_BUTTON,label,o_0,NULL);
GtkButton * b = g_memdup(a,sizeof * a);
gtk_box_pack_start_defaults(GTK_BOX(vbox),GTK_WIDGET(b));
周围的代码创建一个vbox并将其打包在一个窗口中并运行gtk_main()。这会导致这些难以理解的错误信息:
(main:6044):Gtk-CRITICAL **:gtk_widget_hide:assertion `GTK_IS_WIDGET(widget)'失败
(main:6044):Gtk-CRITICAL **:gtk_widget_realize:assertion`GTK_WIDGET_ANCHORED(widget)|| GTK_IS_INVISIBLE(widget)'失败
**
Gtk:ERROR:/build/buildd/gtk+2.0-2.18.3/gtk/gtkwidget.c:8431:gtk_widget_real_map:断言失败:(GTK_WIDGET_REALIZED(widget ))
沿着同样的路线,如果我要写我自己的GObject(不一定是一个Gtk小部件),是否有写好拷贝构造函数的好方法。我认为它应该是一个可选钩子的接口,主要基于属性,以某种方式处理类的层次结构。
我想这样做: p>
GtkButton * b = copyable_copy(COPYABLE(a));
如果GtkButton可以使用理论上可复制的界面。
GObject * $ b $ b g_object_clone(GObject * src)
{
GObject * dst;
GParameter * params;
GParamSpec **规格;
guint n,n_specs,n_params;
specs = g_object_class_list_properties(G_OBJECT_GET_CLASS(src),& n_specs);
params = g_new0(GParameter,n_specs);
n_params = 0; (n = 0; n if(strcmp(specs [n] - > name,parent)&& $ b的
$ b(specs [n] - > flags& G_PARAM_READWRITE)== G_PARAM_READWRITE){
params [n_params] .name = g_intern_string(specs [n] - > name);
g_value_init(& params [n_params] .value,specs [n] - > value_type);
g_object_get_property(src,specs [n] - > name,& params [n_params] .value);
++ n_params;
}
dst = g_object_newv(G_TYPE_FROM_INSTANCE(src),n_params,params);
g_free(specs);
g_free(params);
return dst;
}
虽然克隆小部件并不是那么简单,但上述方法可用于大多数情况下(肯定是在 GtkButton
中)。
我不关心那些未暴露的状态属性(所有适当的小部件都应该完全由可用于 GtkBuilder
的属性定义),但是很多角落案例会使得强大的克隆非常困难(界面和容器是第一个那些出现在我脑海中的)。
Is there a way, using the Gtk library in C, to clone a Gtk button (for instance), and pack it somewhere else in the app. I know you can't pack the same widget twice. And that this code obviously wouldn't work, but shows what happens when I attempt a shallow copy of the button:
GtkButton *a = g_object_new(GTK_TYPE_BUTTON, "label", "o_0", NULL);
GtkButton *b = g_memdup(a, sizeof *a);
gtk_box_pack_start_defaults(GTK_BOX(vbox), GTK_WIDGET(b));
There is surrounding code which creates a vbox and packs it in a window and runs gtk_main(). This will result in these hard to understand error messages:
(main:6044): Gtk-CRITICAL **: gtk_widget_hide: assertion `GTK_IS_WIDGET (widget)' failed
(main:6044): Gtk-CRITICAL **: gtk_widget_realize: assertion `GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed
**
Gtk:ERROR:/build/buildd/gtk+2.0-2.18.3/gtk/gtkwidget.c:8431:gtk_widget_real_map: assertion failed: (GTK_WIDGET_REALIZED (widget))
Along the same lines, if I were to write my own GObject (not necessarily a Gtk widget), is there a good way to write a copy constructor. Im thinking it should be an interface with optional hooks and based mostly on the properties, handling the class's hierarchy in some way.
I'd want to do this:
GtkButton *b = copyable_copy(COPYABLE(a));
If GtkButton could use a theoretical copyable interface.
A clone throught properties is a viable solution:
GObject *
g_object_clone(GObject *src)
{
GObject *dst;
GParameter *params;
GParamSpec **specs;
guint n, n_specs, n_params;
specs = g_object_class_list_properties(G_OBJECT_GET_CLASS(src), &n_specs);
params = g_new0(GParameter, n_specs);
n_params = 0;
for (n = 0; n < n_specs; ++n)
if (strcmp(specs[n]->name, "parent") &&
(specs[n]->flags & G_PARAM_READWRITE) == G_PARAM_READWRITE) {
params[n_params].name = g_intern_string(specs[n]->name);
g_value_init(¶ms[n_params].value, specs[n]->value_type);
g_object_get_property(src, specs[n]->name, ¶ms[n_params].value);
++ n_params;
}
dst = g_object_newv(G_TYPE_FROM_INSTANCE(src), n_params, params);
g_free(specs);
g_free(params);
return dst;
}
Cloning a widget is not that trivial though, but the above approach is usable in most cases (on a GtkButton
for sure).
I'd not care that much of states not exposed with properties (all proper widgets should be fully defined by properties to be usable with GtkBuilder
) but a lot of corner cases will make a robust cloning quite difficult (interfaces and containers being the first ones that come to my mind).
这篇关于有没有一种好的方法来复制一个Gtk小部件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!