我需要能够以编程方式探索GTK GUI的结构。我有GtkWidget,我想找到那个小部件的任何孩子。现在我知道GtkContainer有一个查找子项的功能,而GtkContainer是从GtkWidget派生的。
无论如何,我可以检查一个小部件是否是GtkContainer,然后执行演员表?如果没有,有没有其他方式我可以发现GtkWidget是我的孩子?
答案 0 :(得分:14)
是的,每种GObject类型都有宏来检查对象是否属于该类型:
if(GTK_IS_CONTAINER(widget)) {
GList *children = gtk_container_get_children(GTK_CONTAINER(widget));
...
}
如果窗口小部件是GtkBin
,则它只有一个子节点。在这种情况下,以下内容比处理GList
:
if(GTK_IS_BIN(widget)) {
GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget));
...
}
答案 1 :(得分:5)
在下面的代码中,我实现了find_child
函数,该函数按名称递归搜索小部件。想法建立在@ptomato和following PHP示例:
#include <gtk/gtk.h>
GtkWidget*
find_child(GtkWidget* parent, const gchar* name)
{
if (g_strcasecmp(gtk_widget_get_name((GtkWidget*)parent), (gchar*)name) == 0) {
return parent;
}
if (GTK_IS_BIN(parent)) {
GtkWidget *child = gtk_bin_get_child(GTK_BIN(parent));
return find_child(child, name);
}
if (GTK_IS_CONTAINER(parent)) {
GList *children = gtk_container_get_children(GTK_CONTAINER(parent));
while ((children = g_list_next(children)) != NULL) {
GtkWidget* widget = find_child(children->data, name);
if (widget != NULL) {
return widget;
}
}
}
return NULL;
}
int
main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *frame = gtk_frame_new(NULL);
GtkWidget *vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
GtkWidget *textView = gtk_text_view_new();
GtkWidget *hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
GtkWidget *button1 = gtk_button_new_with_label("button1");
gtk_widget_set_name(button1, "btn1");
GtkWidget *button2 = gtk_button_new_with_label("button2");
gtk_widget_set_name(button2, "btn2");
gtk_window_set_title(GTK_WINDOW(window), "Hello");
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
gtk_window_set_default_size(GTK_WINDOW(window), 450, 400);
gtk_container_add(GTK_CONTAINER(window), frame);
gtk_container_add(GTK_CONTAINER(frame), vbox1);
gtk_box_pack_start(GTK_BOX(vbox1), textView, 1, 1, 0);
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, 0, 1, 0);
gtk_box_pack_start(GTK_BOX(hbox1), button1, 0, 1, 0);
gtk_box_pack_start(GTK_BOX(hbox1), button2, 0, 1, 0);
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
GtkWidget* child = find_child(window, "btn2");
if (child == button2) {
g_print("found it!\n");
} else {
g_print("not found it!\n");
}
gtk_main();
return 0;
}