利用控件的expose-event事件,在回调函数里使用gdk_draw_pixbuf进行背景绘制。
static gboolean on_widget_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
GdkPixbuf *bg = gdk_pixbuf_new_from_file("assets/fmbg.png", NULL);
if (bg) {
gint width,height;
gdk_drawable_get_size(GDK_DRAWABLE(widget->window), &width, &height);
//调整图片大小到适合控件
GdkPixbuf *scaled_bg = gdk_pixbuf_scale_simple(bg,width,height, GDK_INTERP_BILINEAR);
//绘制背景
gdk_draw_pixbuf(
widget->window,
NULL,
scaled_bg,
0, 0, 0, 0,
-1, -1, // -1 表示自动使用图片宽高
GDK_RGB_DITHER_NONE,
0, 0
);
//释放资源
g_object_unref(scaled_bg);
g_object_unref(bg);
}
return FALSE; // 继续传递事件
}对控件进行信号连接
之后该控件就有背景了。
如果不用gdkpixbuf,还可以用gtk支持的cairo库绘图
static gboolean on_page_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
// 1. 尝试加载图片
cairo_surface_t *image = cairo_image_surface_create_from_png("assets/fmbg.png");
// 2. 检查图片是否加载成功
if (cairo_surface_status(image) == CAIRO_STATUS_SUCCESS) {
// 3. 获取控件尺寸
gdk_drawable_get_size(GDK_DRAWABLE(widget->window), &width, &height);
// 4. 计算缩放比例(不保持宽高比)
double scale_x = (double)width / cairo_image_surface_get_width(image);
double scale_y = (double)height / cairo_image_surface_get_height(image);
// 5. 应用缩放并绘制
cairo_save(cr);
cairo_scale(cr, scale_x, scale_y);
cairo_set_source_surface(cr, image, 0, 0);
cairo_paint(cr);
cairo_restore(cr);
}
// 6. 释放资源
cairo_surface_destroy(image);
cairo_destroy(cr);
return FALSE; // 继续传递事件
}对于获取控件绘制区域,使用下面的办法我测试获取的区域偏小,绘制的区域不完整
只有使用下面的办法获得的是控件完整区域