【问题标题】:Gtk3 window background imageGtk3窗口背景图片
【发布时间】:2011-09-11 00:47:03
【问题描述】:

我在 gtk+-3.0.12 中使用 C 语言(截至 2011 年 9 月 10 日的最新稳定版本) 如何在顶部窗口上创建 png 背景图像并仍然在窗口上放置其他小部件(如按钮)?我尝试了以下操作,但图像被绘制在按钮上。

/*
* 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;
}

【问题讨论】:

    标签: c gtk


    【解决方案1】:

    检查以下代码是否适合您:

    #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;
    }
    

    【讨论】:

    • 谢谢,我刚刚想出了另一种方法,但我通过使用回调和 cairo 使它变得更加复杂。在 Glade 中,我尝试将图像放置在布局容器中,但它不允许我添加按钮,所以我不知道我能做到这一点。谢谢。
    【解决方案2】:
    /*
    * #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);
    }
    

    【讨论】:

    • P.S.发布上述代码的任何问题...如果 sprintf 到 css 有问题,请在 sprintf 之前添加 css[0]='\0';...
    • 如果我使用 background-color 属性,它可以正常工作。但我使用背景图像不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 2016-02-18
    • 2023-04-02
    相关资源
    最近更新 更多