C gtk自定义小部件-在Glade中显示,但在构建时不显示
我已经用C为GTK+3制作了一个简单的自定义小部件,名为AwLed,并将其添加到自定义Glade目录中。在Glade内部或使用aw_led_new()函数创建时,它可以按预期工作。 但是,当我编写一个简单的程序来加载Glade文件并显示其小部件(在主窗口小部件上调用show_all())时,自定义小部件不会显示自己。 我添加了一些printfflush进行调试,发现函数实现、分配甚至没有被调用。似乎整个共享库都没有加载 现在,Glade除了用GtkBuilder加载小部件之外还做什么?为什么这些小部件被忽略?我是否应该编写一些样板来实现GtkBuildable接口 非常感谢您的帮助 awled.cC 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加载小部件之外还做什么?为什么这些
#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();
}