GTK2.0设置控件背景

⌚Time: 2025-06-15 22:53:00

👨‍💻Author: Jack Ge

利用控件的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; // 继续传递事件
}

对控件进行信号连接

g_signal_connect(table, "expose-event", G_CALLBACK(on_page_expose), NULL);

之后该控件就有背景了。

如果不用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; // 继续传递事件
}

对于获取控件绘制区域,使用下面的办法我测试获取的区域偏小,绘制的区域不完整

gint width = widget->allocation.width;
gint height = widget->allocation.height;
        

只有使用下面的办法获得的是控件完整区域

gdk_drawable_get_size(GDK_DRAWABLE(widget->window), &width, &height);