gtkbin似乎没有从我的gtkwindow toplevel小部件获取事件

时间:2013-01-16 15:51:23

标签: gtk

我有一些问题,在这一刻我尝试用gtkbin在gtk中创建一个自定义小部件,所以我想知道是否可以继承gtkbin以及如何做到这一点... 谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

我终于成功实现了这一点。以下是想要派生gtkbin widget的人的方法。

1)了解小部件的层次结构非常重要。

>Hierarchy of widgets:  
GtkWidget <- GtkContainer <- GtkBin 

如果GtkcontainerGtkBin没有为GtkWidgetClass->draw重写一个contumize函数,例如自定义窗口小部件类,它直接从{{1}派生将使用GtkBin默认绘制函数。

2)关于gtkbin的信息:

下载GtkWidgetClass的源代码并打开gtkgtkwidget.cgtkcontainer.c并查看所有这些文件中的gtkwindow.c函数。

class_init

  • 1)我们必须看到,widget类没有实现“draw”功能:

    GtkWidgetClass
  • 2)我们必须看到, GtkWidgetClass->draw GtkWidgetClass->get_preferred_width 始终的实现会返回“0”,这是不正确的。

    < / LI>
  • 我们还看到GtkWidgetClass_preferred_width_height仅为您要派生的窗口小部件分配大小,它不会计算自定义窗口小部件的子项。

您必须将这四个功能重写为一切才能正常工作。

由于GtkWidgetClass->size_allocate是一个直接从GtkWindow派生的小部件,我们可以通过查看GtkBin文件中的相应实现来实现我们的功能并进行一些更改。

这是我的实施:

GtkWindow.c

widget_class->get_preferred_width = item_list_get_preferred_width; widget_class->get_preferred_height = item_list_get_preferred_height; widget_class->draw = dsn_itemlist_draw; widget_class->size_allocate = item_list_size_allocate; void item_list_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GtkAllocation child_allocation; GtkWidget *child; guint border_width; gtk_widget_set_allocation (widget, allocation); child = gtk_bin_get_child (GTK_BIN(widget)); if (child && gtk_widget_get_visible (child)) { border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); child_allocation.x = border_width; child_allocation.y = border_width; child_allocation.width = MAX (1, allocation->width - border_width * 2); child_allocation.height = MAX (1, allocation->height - border_width * 2); gtk_widget_size_allocate (child, &child_allocation); } } gboolean dsn_itemlist_draw( GtkWidget *widget, cairo_t *cr) { GtkWidget *child; GtkBin *bin = GTK_BIN(widget); GtkContainer *container = GTK_CONTAINER(widget); child = gtk_bin_get_child(bin); gtk_container_propagate_draw(container, child, cr); printf("bonnnnnnn\n"); return TRUE; } void item_list_get_preferred_width(GtkWidget *widget, gint *minimum_size, gint *natural_size) { //GtkWindow *window; GtkWidget *child; guint border_width; //window = GTK_WINDOW (widget); child = gtk_bin_get_child (GTK_BIN (widget)/*(window)*/); border_width = 0;//gtk_container_get_border_width (GTK_CONTAINER (window)); *minimum_size = border_width * 2; *natural_size = border_width * 2; if (child && gtk_widget_get_visible (child)) { gint child_min, child_nat; gtk_widget_get_preferred_width (child, &child_min, &child_nat); *minimum_size += child_min; *natural_size += child_nat; } } void item_list_get_preferred_height(GtkWidget *widget, gint *minimum_size, gint *natural_size) { //GtkWindow *window; GtkWidget *child; guint border_width; //window = GTK_WINDOW (widget); child = gtk_bin_get_child (GTK_BIN (widget)/*(window)*/); border_width = 0;//gtk_container_get_border_width (GTK_CONTAINER (window)); *minimum_size = border_width * 2; *natural_size = border_width * 2; if (child && gtk_widget_get_visible (child)) { gint child_min, child_nat; gtk_widget_get_preferred_height (child, &child_min, &child_nat); *minimum_size += child_min; *natural_size += child_nat; } } Note:函数中,我们必须告诉init我们的gtk没有窗口(widget)但是它继承了一个来自其父窗口小部件,通过调用

gtk_widget_set_has_window(GTK_WIDGET(this_instance),FALSE);

结论......