4

我正在尝试在绘图区域上绘制图像,但没有运气。我看到了几个 python 示例,但我无法将它们实现到我正在使用的 c 中(例如,将图像绘制到 gtk.DrawingArea?

我已经创建了一个 Pixbuf 变量来存储我想在绘图区域上绘制的图像,但是没有像 gtk_drawing_area_draw_pixbuf 之类的函数或与之相关的东西。感谢任何建议。

4

2 回答 2

10

You need to make use of expose-event callback (assuming you are working with Gtk+ 2.0) to draw the pixbuf onto drawing area. There is no gtk_drawing_area_draw_pixbuf instead you have gdk_draw_pixbuf. This has been deprecated in favour of gdk_cairo_set_source_pixbuf from version 2.22 onwards. You can call these function in your expose event callback something on these lines (please use them as reference only):
If your Gtk version is < 2.22

static gboolean
da_expose (GtkWidget *da, GdkEvent *event, gpointer data)
{
    (void)event; (void)data;
    GdkPixbuf *pix;
    GError *err = NULL;
    /* Create pixbuf */
    pix = gdk_pixbuf_new_from_file("/usr/share/icons/cab_view.png", &err);
    if(err)
    {
        printf("Error : %s\n", err->message);
        g_error_free(err);
        return FALSE;
    }
    GdkDrawable *draw = gtk_widget_get_window(da);
    /* Draw pixbuf */
    gdk_draw_pixbuf(draw, NULL, pix, 0, 0, 0, 0, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
    return FALSE;
}

Version 2.22 onwards you will have to make use of cairo something on these lines:

static gboolean
da_expose (GtkWidget *da, GdkEvent *event, gpointer data)
{
    (void)event; (void)data;
    GdkPixbuf *pix;
    GError *err = NULL;
    /* Create pixbuf */
    pix = gdk_pixbuf_new_from_file("/usr/share/icons/cab_view.png", &err);
    if(err)
    {
        printf("Error : %s\n", err->message);
        g_error_free(err);
        return FALSE;
    }
    cairo_t *cr;
    cr = gdk_cairo_create (da->window);
    gdk_cairo_set_source_pixbuf(cr, pix, 0, 0);
    cairo_paint(cr);
    cairo_fill (cr);
    cairo_destroy (cr);
    return FALSE;
}

Of course you would have connected to the callback using g_signal_connect (say g_signal_connect (da, "expose-event", G_CALLBACK (da_expose), NULL);). If you are using Gtk+ 3.0 then you will be making use of draw instead of expose-event. You can always refer to gtk-demo/gtk3-demo application which are available to see the samples along with the code. This should be available in the package repository of your distro or you can always get it from source.
Hope this helps!
PS: This link might provide you with some pointers

于 2012-04-20T19:07:59.053 回答
8

现在 GTK 版本是 GTK+3.0。如果您使用的是 GTK+3.0,请按如下方式使用。

// gcc expose.c -o expose `pkg-config gtk+-3.0 --cflags --libs`
#include <gtk/gtk.h>
#include <stdlib.h>

static gboolean
on_window_draw (GtkWidget *da, GdkEvent *event, gpointer data)
{
    (void)event; (void)data;
    GdkPixbuf *pix;
    GError *err = NULL;
    /* Create pixbuf */
    pix = gdk_pixbuf_new_from_file("/usr/share/icons/cab_view.png", &err);
    if(err)
    {
        printf("Error : %s\n", err->message);
        g_error_free(err);
        return FALSE;
    }
    cairo_t *cr;
    cr = gdk_cairo_create (gtk_widget_get_window(da));
    //    cr = gdk_cairo_create (da->window);
    gdk_cairo_set_source_pixbuf(cr, pix, 0, 0);
    cairo_paint(cr);
    //    cairo_fill (cr);
    cairo_destroy (cr);
    //    return FALSE;
}

int main ( int argc, char **argv) {
    GtkWidget *window;
    GtkWidget *canvas;
    gtk_init (&argc , &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request (window,
        50, 50);

    g_signal_connect (window, "destroy",
        G_CALLBACK (gtk_main_quit) , NULL);
    canvas = gtk_drawing_area_new ();
    gtk_container_add (GTK_CONTAINER (window), canvas);
    g_signal_connect (canvas, "draw", (GCallback) on_window_draw, NULL);

    gtk_widget_set_app_paintable(canvas, TRUE);
    gtk_widget_show_all (window);
    gtk_main ();
    return 0;
}
于 2015-09-24T11:03:44.247 回答