C gtk自定义小部件-在Glade中显示,但在构建时不显示

C gtk自定义小部件-在Glade中显示,但在构建时不显示,c,widget,gtk,glade,C,Widget,Gtk,Glade,我已经用C为GTK+3制作了一个简单的自定义小部件,名为AwLed,并将其添加到自定义Glade目录中。在Glade内部或使用aw_led_new()函数创建时,它可以按预期工作。 但是,当我编写一个简单的程序来加载Glade文件并显示其小部件(在主窗口小部件上调用show_all())时,自定义小部件不会显示自己。 我添加了一些printfflush进行调试,发现函数实现、分配甚至没有被调用。似乎整个共享库都没有加载 现在,Glade除了用GtkBuilder加载小部件之外还做什么?为什么这些

我已经用C为GTK+3制作了一个简单的自定义小部件,名为AwLed,并将其添加到自定义Glade目录中。在Glade内部或使用aw_led_new()函数创建时,它可以按预期工作。 但是,当我编写一个简单的程序来加载Glade文件并显示其小部件(在主窗口小部件上调用show_all())时,自定义小部件不会显示自己。 我添加了一些printfflush进行调试,发现函数实现、分配甚至没有被调用。似乎整个共享库都没有加载

现在,Glade除了用GtkBuilder加载小部件之外还做什么?为什么这些小部件被忽略?我是否应该编写一些样板来实现GtkBuildable接口

非常感谢您的帮助

awled.c

#include <gtk/gtk.h>
#include "awled.h"

enum {
  PROP_0,
  PROP_ACTIVE,
};

static void      aw_led_set_property          (GObject        *object,
                                               guint           prop_id,
                                               const GValue   *value,
                                               GParamSpec     *pspec);
static void      aw_led_get_property          (GObject        *object,
                                               guint           prop_id,
                                               GValue         *value,
                                               GParamSpec     *pspec);
static void      aw_led_realize               (GtkWidget      *widget);
static void      aw_led_unrealize             (GtkWidget      *widget);
static void      aw_led_map                   (GtkWidget      *widget);
static void      aw_led_unmap                 (GtkWidget      *widget);
static void      aw_led_size_allocate         (GtkWidget      *widget,
                                               GtkAllocation  *allocation);
static void      aw_led_get_preferred_width (GtkWidget *widget,
                                              gint      *minimal_width,
                                              gint      *natural_width);
static void      aw_led_get_preferred_height (GtkWidget *widget,
                                              gint      *minimal_height,
                                              gint      *natural_height);
static gboolean  aw_led_draw                (GtkWidget      *widget,
                                             cairo_t *cr);

G_DEFINE_TYPE (AwLed, aw_led, GTK_TYPE_WIDGET)

#define parent_class aw_led_parent_class

static void
aw_led_class_init (AwLedClass *klass)
{
  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  object_class->set_property         = aw_led_set_property;
  object_class->get_property         = aw_led_get_property;

  widget_class->realize              = aw_led_realize;
  widget_class->unrealize            = aw_led_unrealize;
  widget_class->map                  = aw_led_map;
  widget_class->unmap                = aw_led_unmap;
  widget_class->size_allocate        = aw_led_size_allocate;
  widget_class->get_preferred_width  = aw_led_get_preferred_width;
  widget_class->get_preferred_height = aw_led_get_preferred_height;
  widget_class->draw                 = aw_led_draw;

  GParamSpec* param_spec;
  param_spec = g_param_spec_boolean ("active", "Active", "LED State",
                                     FALSE, G_PARAM_READWRITE);
  g_object_class_install_property (object_class, PROP_ACTIVE, param_spec);
}


static void
aw_led_init (AwLed *led)
{
  gtk_widget_set_has_window (GTK_WIDGET (led), FALSE);

  led->state           = FALSE;
  led->color_on.red    = 0.0;
  led->color_on.green  = 0.6;
  led->color_on.blue   = 0.0;
  led->color_on.alpha  = 1.0;
  led->color_off.red   = 0.6;
  led->color_off.green = 0.0;
  led->color_off.blue  = 0.0;
  led->color_off.alpha = 1.0;
  /*priv->backing_store       = NULL; //what?? needed?
  priv->backing_store_valid = FALSE;
  priv->pos_redraw_idle_id   = 0;*/ 
}


static void
aw_led_set_property (GObject      *object,
                     guint         prop_id,
                     const GValue *value,
                     GParamSpec   *pspec)
{
  AwLed *led = AW_LED (object);

  switch (prop_id)
  {
    case PROP_ACTIVE:
      led->state = g_value_get_boolean (value);
      gtk_widget_queue_resize (GTK_WIDGET (led));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}


static void
aw_led_get_property (GObject    *object,
                     guint       prop_id,
                     GValue     *value,
                     GParamSpec *pspec)
{
 AwLed *led = AW_LED (object);

  switch (prop_id)
    {
    case PROP_ACTIVE:
      g_value_set_boolean (value, led->state);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}


GtkWidget *
aw_led_new ()
{
  return g_object_new (AW_TYPE_LED,
                       "active", FALSE,
                       NULL);
}


static void
aw_led_realize (GtkWidget *widget)
{
  AwLed         *led = AW_LED (widget);
  GtkAllocation allocation;
  GdkWindowAttr attributes;
  gint          attributes_mask;

  GTK_WIDGET_CLASS (aw_led_parent_class)->realize (widget);

  gtk_widget_get_allocation (widget, &allocation);

  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.x           = allocation.x;
  attributes.y           = allocation.y;
  attributes.width       = allocation.width;
  attributes.height      = allocation.height;
  attributes.wclass      = GDK_INPUT_ONLY;
  attributes.event_mask  = (gtk_widget_get_events (widget) | 
                            GDK_EXPOSURE_MASK);

  attributes_mask = GDK_WA_X | GDK_WA_Y;

  led->input_window = gdk_window_new (gtk_widget_get_window (widget),
                                       &attributes, attributes_mask);
  gdk_window_set_user_data (led->input_window, led);

}


static void
aw_led_unrealize (GtkWidget *widget)
{
  AwLed *led = AW_LED (widget);

  if (led->input_window) {
      gdk_window_destroy (led->input_window);
      led->input_window = NULL;
  }

  GTK_WIDGET_CLASS (aw_led_parent_class)->unrealize (widget);
}


static void
aw_led_map (GtkWidget *widget)
{
  AwLed *led = AW_LED (widget);

  GTK_WIDGET_CLASS (parent_class)->map (widget);

  if (led->input_window)
    gdk_window_show (led->input_window);

}


static void
aw_led_unmap (GtkWidget *widget)
{
  AwLed *led = AW_LED (widget);
  if (led->input_window)
    gdk_window_hide (led->input_window);

  GTK_WIDGET_CLASS (parent_class)->unmap (widget);
}


static void
aw_led_size_allocate (GtkWidget     *widget,
                      GtkAllocation *allocation)
{
  AwLed *led = AW_LED (widget);

  gtk_widget_set_allocation (widget, allocation);

  if (gtk_widget_get_realized (widget)) {
      gdk_window_move_resize (led->input_window,
                              allocation->x, allocation->y,
                              allocation->width, allocation->height);
  }
}


static void
aw_led_get_preferred_width (GtkWidget *widget,
                            gint      *minimal_width,
                            gint      *natural_width)
{
  *minimal_width = 20;
  *natural_width = 35;
}


static void
aw_led_get_preferred_height (GtkWidget *widget,
                             gint      *minimal_height,
                             gint      *natural_height)
{
  *minimal_height = 20;
  *natural_height = 35;
}


static gboolean
aw_led_draw (GtkWidget *widget,
             cairo_t   *cr)
{
  gint width, height;
  AwLed* led = AW_LED(widget);

  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  GdkRGBA color = (led->state) ? led->color_on : led->color_off;

  cairo_arc (cr, width / 2.0, height / 2.0,
             MIN (width, height) / 2.0, 0, 2 * G_PI);

  gdk_cairo_set_source_rgba (cr, &color);

  cairo_fill (cr);

  return TRUE;
}
#include <gtk/gtk.h>
#include <awled.h>

int main(int argc, char* argv[]) {
    GtkBuilder* builder;
    GtkWidget *window, *led, *led2, *box;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "interface.ui", NULL);

    window = (GtkWidget*) gtk_builder_get_object(builder, "window1");
    led = (GtkWidget*) gtk_builder_get_object(builder, "led1");
    box = (GtkWidget*) gtk_builder_get_object(builder, "box1");

    //weird... if I create only one this way, all of them show themselves!
    //led2 = aw_led_new();
    //gtk_box_pack_end(GTK_BOX(box), led2, 0, 0, 0);

    gtk_widget_show_all(window);

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);    

    gtk_main();
}
#包括
#包括“awled.h”
枚举{
第0号提案,
道具激活,
};
静态void aw_led_set_属性(GObject*对象,
金特道具id,
常量GValue*值,
GParamSpec*pspec);
静态void aw_led_get_属性(GObject*对象,
金特道具id,
GValue*值,
GParamSpec*pspec);
静态无效aw_led_实现(GtkWidget*小部件);
静态无效aw_led_未实现(GtkWidget*小部件);
静态无效aw_led_映射(GtkWidget*小部件);
静态无效aw_led_取消映射(GtkWidget*小部件);
静态无效aw_led_大小_分配(GtkWidget*小部件,
地理位置*分配);
静态无效aw_led_get_首选_宽度(GtkWidget*小部件,
gint*最小宽度,
基特*自然宽度);
静态无效aw_led_get_首选_高度(GtkWidget*小部件,
gint*最小高度,
基特*自然高度);
静态gboolean aw_led_绘图(GtkWidget*小部件,
开罗;
G_定义_类型(AwLed、aw_led、GTK_类型小部件)
#定义父类aw\U led\U父类
静态空隙
aw_-led_-class_-init(AwLedClass*klass)
{
GObjectClass*对象类=G对象类(klass);
GtkWidgetClass*小部件类=GTK小部件类(klass);
对象\类->设置\属性=aw\ led\设置\属性;
object\u class->get\u property=aw\u led\u get\u property;
widget\u class->realize=aw\u led\u realize;
widget\u class->unrealize=aw\u led\u unrealize;
widget\u class->map=aw\u led\u map;
小部件\u类->取消映射=aw\u led\u取消映射;
widget\u class->size\u allocate=aw\u led\u size\u allocate;
widget\u class->get\u preferred\u width=aw\u led\u get\u preferred\u width;
widget\u class->get\u preferred\u height=aw\u led\u get\u preferred\u height;
widget\u class->draw=aw\u led\u draw;
GParamSpec*参数规格;
参数规格=g参数规格布尔值(“活动”、“活动”、“LED状态”,
FALSE,G_PARAM_READWRITE);
g_对象类安装属性(对象类、属性活动、参数规范);
}
静态空隙
aw_led_init(AwLed*led)
{
gtk_小部件_设置_有_窗口(gtk_小部件(led),错误);
led->状态=假;
led->彩色显示,红色=0.0;
led->彩色显示,绿色=0.6;
led->color_on.blue=0.0;
led->color_on.alpha=1.0;
led->颜色关闭。红色=0.6;
led->颜色\关闭。绿色=0.0;
led->颜色\关闭。蓝色=0.0;
led->颜色关闭。alpha=1.0;
/*priv->backing_store=NULL;//需要什么?
priv->backing\u store\u valid=FALSE;
priv->pos\u redraw\u idle\u id=0;*/
}
静态空隙
aw_led_集合_属性(GObject*对象,
金特道具id,
常量GValue*值,
GParamSpec*pspec)
{
AwLed*led=AW_led(对象);
开关(道具id)
{
案例道具激活:
led->状态=g_值\u获取\u布尔值(值);
gtk_小部件_队列_大小调整(gtk_小部件(led));
打破
违约:
G_OBJECT_WARN_INVALID_PROPERTY_ID(OBJECT,prop_ID,pspec);
打破
}
}
静态空隙
aw_led_get_属性(GObject*对象,
金特道具id,
GValue*值,
GParamSpec*pspec)
{
AwLed*led=AW_led(对象);
开关(道具id)
{
案例道具激活:
g_值\u设置\u布尔值(值,led->状态);
打破
违约:
G_OBJECT_WARN_INVALID_PROPERTY_ID(OBJECT,prop_ID,pspec);
打破
}
}
GtkWidget*
aw_led_new()
{
返回新对象(AW类型发光二极管,
“主动”,假,
无效);
}
静态空隙
aw_led_实现(GtkWidget*小部件)
{
AwLed*led=AW_led(小部件);
地理位置分配;
GdkWindowAttr属性;
金特面具;
GTK_小部件类(aw_led_父类)->实现(小部件);
gtk_小部件_获取_分配(小部件和分配);
attributes.window\u type=GDK\u window\u CHILD;
attributes.x=allocation.x;
attributes.y=allocation.y;
attributes.width=allocation.width;
attributes.height=allocation.height;
attributes.wclass=GDK_INPUT_ONLY;
attributes.event_mask=(gtk_小部件_获取_事件(小部件)|
GDK_曝光_掩模);
属性掩码=GDK_WA_X | GDK_WA_Y;
led->input_window=gdk_window_new(gtk_widget_get_window(widget)),
&属性,属性(U掩码);
gdk_窗口_设置_用户_数据(led->输入_窗口,led);
}
静态空隙
aw_led_未实现(Gt
#include <gtk/gtk.h>
#include <awled.h>

int main(int argc, char* argv[]) {
    GtkBuilder* builder;
    GtkWidget *window, *led, *led2, *box;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "interface.ui", NULL);

    window = (GtkWidget*) gtk_builder_get_object(builder, "window1");
    led = (GtkWidget*) gtk_builder_get_object(builder, "led1");
    box = (GtkWidget*) gtk_builder_get_object(builder, "box1");

    //weird... if I create only one this way, all of them show themselves!
    //led2 = aw_led_new();
    //gtk_box_pack_end(GTK_BOX(box), led2, 0, 0, 0);

    gtk_widget_show_all(window);

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);    

    gtk_main();
}