我一起破解了一个例子。它用图像填充顶级应用程序窗口的背景。
作为背景图片,我选择了一颗小星星(1)。编译示例调用gcc
像
gcc `pkg-config --libs --cflags glib-2.0 gtk+-3.0` <source> -o <executable>
在我的机器上,结果看起来像
1:http: //upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Featured_Star_green.svg/32px-Featured_Star_green.svg.png
#include <gtk/gtk.h>
#include <glib-2.0/glib.h>
typedef struct Texture_
{
gint root_width, root_height;
cairo_surface_t *bg_image;
} Texture;
typedef struct Ui_
{
GtkWidget *window;
GtkWidget *grid;
GtkWidget *button;
Texture *texture;
gulong window_draw_cb_handler_id;
} Ui;
gboolean window_draw_cb (GtkWidget *, cairo_t *, Ui *);
void
button_clicked_cb (GtkWidget * widget, Ui * ui)
{
gboolean ret;
ret =
g_signal_handler_is_connected (ui->window,
ui->window_draw_cb_handler_id);
if (ret) {
g_signal_handler_disconnect (ui->window, ui->window_draw_cb_handler_id);
}
else {
ui->window_draw_cb_handler_id =
g_signal_connect (ui->window, "draw", G_CALLBACK (window_draw_cb),
ui);
}
gtk_widget_queue_draw (ui->window);
}
void
destroy_cb (GtkWidget * widget, gpointer data)
{
gtk_main_quit ();
}
gboolean
window_draw_cb (GtkWidget * widget, cairo_t * cr, Ui * ui)
{
cairo_set_source_surface (cr, ui->texture->bg_image, 0, 0);
cairo_rectangle (cr, 0, 0,
ui->texture->root_width, ui->texture->root_height);
cairo_fill (cr);
/* draw all widgets attached to `grid` to the
* cairo context of the mainwindow */
gtk_widget_draw (ui->grid, cr);
cairo_fill (cr);
return TRUE;
}
void
ui_texture_init (Ui * ui)
{
gint root_width, root_height, width, height;
guint n_x, n_y, i, k;
cairo_format_t format;
cairo_surface_t *bg_image, *target;
cairo_status_t ret;
GdkWindow *root;
cairo_t *cr;
ui->texture = g_new (Texture, 1);
bg_image =
cairo_image_surface_create_from_png ("./Featured_Star_green.svg.png");
ret = cairo_surface_status (bg_image);
g_assert (ret == 0);
format = cairo_image_surface_get_format (bg_image);
width = cairo_image_surface_get_width (bg_image);
height = cairo_image_surface_get_height (bg_image);
root = gdk_get_default_root_window ();
gdk_window_get_geometry (root, NULL, NULL, &root_width, &root_height);
target = cairo_image_surface_create (format, root_width, root_height);
cr = cairo_create (target);
n_x = root_width / width;
n_y = root_height / height;
for (i = 0; i <= n_x; i++) {
for (k = 0; k <= n_y; k++) {
cairo_set_source_surface (cr, bg_image, i * width, k * height);
cairo_rectangle (cr, i * width, k * height, width, height);
cairo_fill (cr);
}
}
ui->texture->root_width = root_width;
ui->texture->root_height = root_height;
ui->texture->bg_image = target;
}
void
forall_container (GtkWidget * widget, gpointer data)
{
gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
}
Ui *
ui_init ()
{
Ui *ui;
GtkWidget *label, *entry;
PangoAttrList *attributes;
ui = g_new (Ui, 1);
ui_texture_init (ui);
ui->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
ui->grid = gtk_grid_new ();
gtk_grid_set_column_homogeneous (GTK_GRID (ui->grid), TRUE);
gtk_grid_set_row_homogeneous (GTK_GRID (ui->grid), TRUE);
gtk_grid_set_row_spacing (GTK_GRID (ui->grid), 10);
label = gtk_label_new ("Label:");
attributes = pango_attr_list_new ();
pango_attr_list_insert (attributes, pango_attr_size_new_absolute (30000));
gtk_label_set_attributes (GTK_LABEL (label), attributes);
entry = gtk_entry_new ();
ui->button = gtk_button_new_with_label ("Toggle background image");
gtk_grid_attach (GTK_GRID (ui->grid), label, 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (ui->grid), entry, 1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (ui->grid), ui->button, 0, 1, 2, 1);
gtk_container_foreach (GTK_CONTAINER (ui->grid), &forall_container, NULL);
gtk_container_add (GTK_CONTAINER (ui->window), ui->grid);
return ui;
}
int
main (int argc, char *argv[])
{
Ui *ui;
gtk_init (&argc, &argv);
ui = ui_init ();
g_signal_connect (ui->window, "destroy", G_CALLBACK (destroy_cb), ui);
ui->window_draw_cb_handler_id =
g_signal_connect (ui->window, "draw", G_CALLBACK (window_draw_cb), ui);
g_signal_connect (ui->button, "clicked", G_CALLBACK (button_clicked_cb),
ui);
gtk_widget_show_all (ui->window);
gtk_main ();
}