我有一些问题,在这一刻我尝试用gtkbin在gtk中创建一个自定义小部件,所以我想知道是否可以继承gtkbin以及如何做到这一点... 谢谢你的帮助。
答案 0 :(得分:0)
我终于成功实现了这一点。以下是想要派生gtkbin widget
的人的方法。
1)了解小部件的层次结构非常重要。
>Hierarchy of widgets:
GtkWidget <- GtkContainer <- GtkBin
如果Gtkcontainer
和GtkBin
没有为GtkWidgetClass->draw
重写一个contumize函数,例如自定义窗口小部件类,它直接从{{1}派生将使用GtkBin
的默认绘制函数。
2)关于gtkbin的信息:
下载GtkWidgetClass
的源代码并打开gtk
,gtkwidget.c
,gtkcontainer.c
并查看所有这些文件中的gtkwindow.c
函数。
在class_init
:
1)我们必须看到,widget类没有实现“draw”功能:
GtkWidgetClass
2)我们必须看到, GtkWidgetClass->draw
和GtkWidgetClass->get_preferred_width
始终的实现会返回“0”,这是不正确的。
我们还看到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);
结论......