2011-09-11 141 views
3

我在gtk + -3.0.12中使用C語言(截至2011年9月10日的最新穩定版本) 如何在頂部窗口上創建png背景圖像並仍然放置其他小部件窗戶上的按鈕?我嘗試了以下內容,但是圖像是通過按鈕繪製的。Gtk3窗口背景圖像

/* 
* Compile with: 
* gcc -Wextra -o cairo6 `pkg-config --cflags --libs gtk+-3.0` cairo6.c 
*/ 

#include <gtk/gtk.h> 
static cairo_surface_t *surface = NULL; 
cairo_surface_t *image; 

static gboolean 
on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) 
{ 
    cairo_t *cr; 
    surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget), 
          CAIRO_CONTENT_COLOR, 
          gtk_widget_get_allocated_width (widget), 
          gtk_widget_get_allocated_height (widget)); 

cr = gdk_cairo_create (gtk_widget_get_window (GTK_WIDGET(widget))); 
cairo_set_source_surface (cr, image, 0, 0); 
cairo_paint (cr); 
cairo_destroy (cr); 

return TRUE; 
} 

int main(int argc, char *argv[]) 
{ 
GtkWidget *window; 
gtk_init(&argc, &argv); 

window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 
image = cairo_image_surface_create_from_png("bdrop.png"); //Supply your own image here 
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); 
gtk_widget_set_app_paintable(window, FALSE); 
gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER); 
gtk_window_set_default_size (GTK_WINDOW(window), 800, 480); 

GtkWidget *ebox = gtk_event_box_new(); 
GtkWidget *button; 
button = gtk_button_new_with_label("QUIT"); 
gtk_widget_set_halign (GTK_WIDGET(button),GTK_ALIGN_CENTER); 
gtk_widget_set_valign (GTK_WIDGET(button),GTK_ALIGN_CENTER); 
gtk_container_add (GTK_CONTAINER(ebox), button); 
g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL); 

gtk_container_add (GTK_CONTAINER(window), ebox); 
g_signal_connect(ebox,"draw", G_CALLBACK (on_expose_event),NULL); 

gtk_widget_show_all (window); 

gtk_main(); 
cairo_surface_destroy (image); 
return 0; 
} 

回答

6

檢查下面的代碼會爲你工作:

#include <gtk/gtk.h> 

int main(int argc, char *argv[]) 
{ 
    GtkWidget *window; 
    GtkWidget *layout; 
    GtkWidget *image; 
    GtkWidget *button; 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    gtk_window_set_default_size(GTK_WINDOW(window), 290, 200); 
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 

    layout = gtk_layout_new(NULL, NULL); 
    gtk_container_add(GTK_CONTAINER (window), layout); 
    gtk_widget_show(layout); 

    image = gtk_image_new_from_file("/home/my_background_image.jpg"); 
    gtk_layout_put(GTK_LAYOUT(layout), image, 0, 0); 

    button = gtk_button_new_with_label("Button"); 
    gtk_layout_put(GTK_LAYOUT(layout), button, 150, 50); 
    gtk_widget_set_size_request(button, 80, 35); 

    g_signal_connect_swapped(G_OBJECT(window), "destroy", 
    G_CALLBACK(gtk_main_quit), NULL); 

    gtk_widget_show_all(window); 

    gtk_main(); 

    return 0; 
} 
+0

謝謝你,我只是想出了另一種方法,但我使它更加複雜,它需要的是通過使用回調和開羅。在Glade中,我嘗試在佈局容器中放置一個圖像,但它不會讓我添加一個按鈕,所以我不知道我可以做到這一點。謝謝。 – mike

0
/* 
* #include<string.h> for the strlen() function... 
*/ 
void set_window_background(gchar *__imgPath__) 
{ 
/* 
* Malloc a buffer to store the css data and fill it with css code 
*/ 
gchar *css=(gchar *)malloc((strlen(__imgPath__)+55)*sizeof(gchar)); 
sprintf(css,"GtkWindow{\nbackground-image: url('%s');\n}\n",__imgPath__); 
/* 
* Create a css provider and add pass css data to it 
*/ 
GtkCssProvider *provider = gtk_css_provider_new(); 
gtk_css_provider_load_from_data(provider,css, -1, NULL); 
/* 
* Bind the css provider for the current display 
*/ 
GdkDisplay *display = gdk_display_get_default(); 
GdkScreen *screen = gdk_display_get_default_screen (display); 
gtk_style_context_add_provider_for_screen(screen, 
             GTK_STYLE_PROVIDER (provider), 
             GTK_STYLE_PROVIDER_PRIORITY_APPLICATION 
            ); 
/* 
* Free the used memory... 
*/ 
g_object_unref(provider); 
g_free(css); 
} 
+0

P.S.用上面的代碼發佈任何問題...如果sprintf與css有問題,然後添加'css [0] ='\ 0';'在sprintf之前... – user3745626

+0

如果我使用background-color屬性,它可以正常工作。但我用戶背景圖像不起作用。 – vicky