2013-01-16 22 views

回答

0

我終於設法實現了這一點。以下是想要推導出gtkbin widget的人的方法。

1)理解小部件的層次結構很重要。

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

如果GtkcontainerGtkBin不重寫contumize功能GtkWidgetClass->draw,例如自定義部件類直接從GtkBin派生將使用默認繪製GtkWidgetClass功能。

2)約gtkbin信息:

下載的gtk和開放gtkwidget.cgtkcontainer.cgtkwindow.c的源代碼,並期待在class_init功能所有這些文件。

GtkWidgetClass

  • 1)我們必須看到的是,部件類沒有實現 「畫圖」 功能:

    GtkWidgetClass->draw 
    
  • 2)我們必須看到, ,執行GtkWidgetClass->get_preferred_widthGtkWidgetClass_preferred_width_height總是返回「0」,這是不正確的。

  • 我們還看到,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不擁有一個窗口(gdkwindow),但它會通過調用一個繼承從其父控件

gtk_widget_set_has_window(GTK_WIDGET(this_instance),FALSE);

總結...