由於廢棄/刪除,Pixbuf方法不再適用於GTK3 +。我想在GtkFixed或GtkBox的gdk部分放置背景圖片。我相信我需要開羅圖形庫來做到這一點。如何製作帶背景圖像的GTK3 +窗口
能愉快的靈魂引導我朝着正確的方向嗎?
由於廢棄/刪除,Pixbuf方法不再適用於GTK3 +。我想在GtkFixed或GtkBox的gdk部分放置背景圖片。我相信我需要開羅圖形庫來做到這一點。如何製作帶背景圖像的GTK3 +窗口
能愉快的靈魂引導我朝着正確的方向嗎?
我一起砍了一個例子。它用圖像填充頂層應用程序窗口的背景。
作爲背景圖片,我選擇了一顆小星星(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();
}
這個答案適用於它自己,但是當我將它實現到我的程序中時從未正常工作。我強烈建議[this](http://stackoverflow.com/questions/7375624/gtk3-window-background-image?rq=1)回答,因爲它實現起來更容易。 – whotheman
您也可以使用CSS主題化它。 – ptomato
查看我的帖子在http://stackoverflow.com/questions/7375624/gtk3-window-background-image/ – user3745626