gtkbin似乎无法从我的gtkwindow顶级小部件获取事件

gtkbin似乎无法从我的gtkwindow顶级小部件获取事件,gtk,Gtk,我有一些问题,在这一刻,我试图用gtkbin在gtk中创建一个自定义小部件,所以我想知道是否有可能将gtkbin子类化,以及如何做到这一点。。。 谢谢你的帮助。我终于自己实现了这一点。下面是希望派生gtkbin小部件的人的方法 1) 理解小部件的层次结构很重要 >Hierarchy of widgets: GtkWidget <- GtkContainer <- GtkBin 2) 我们必须看到,GtkWidgetClass->get_preferred_width和

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

我终于自己实现了这一点。下面是希望派生
gtkbin小部件
的人的方法

1) 理解小部件的层次结构很重要

>Hierarchy of widgets:  
GtkWidget <- GtkContainer <- GtkBin 
  • 2) 我们必须看到,
    GtkWidgetClass->get_preferred_width
    GtkWidgetClass_preferred_width_height
    的实现总是返回不正确的“0”

  • 我们还看到,
    GtkWidgetClass->size\u 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;
        }
    }
    
    注意:
    init
    函数中,我们必须告诉
    gtk
    我们的
    小部件
    没有窗口(
    gdkwindow
    ),但它通过调用

    gtk_widget_set_有_窗口(gtk_widget(此_实例),FALSE)

    这就结束了

       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;
        }
    }