GtkDrawingArea - 如何让它成为可绘制的?

dwj*_*ton 4 gtk cairo

我有点想到这里.

我正在尝试使用cairo在我的GTK表单上绘制一些简单的图形.

#include <stdio.h>
#include <gtk/gtk.h>
#include <cairo.h>

GtkWidget* window;
GtkWidget* darea; 


int main(int argc, char **argv)
{
    gtk_init(&argc, &argv);     
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(window), 390, 240);

    darea = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(window), darea); 

    cairo_t *cr; 
    cr = gdk_cairo_create(darea->window);
    cairo_rectangle(cr, 0, 0, 100, 100); 
    cairo_fill(cr);


    gtk_widget_show_all(window);

    gtk_main(); 

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这编译,但给了我

Gdk-CRITICAL**:IA__gdk_cairo_create:断言`GDK_IS_DRAWABLE(drawable)'失败

然后是段错误.

我一直在看这个教程

所以我按如下方式更改了代码,使得cairo调用发生在expose事件中.

    #include <stdio.h>
    #include <gtk/gtk.h>
    #include <cairo.h>

    GtkWidget* window;
    GtkWidget* darea; 

    static gboolean
    on_expose_event(GtkWidget *widget,
        GdkEventExpose *event,
        gpointer data)
    {
        cairo_t *cr; 
        cr = gdk_cairo_create(darea->window);
        cairo_rectangle(cr, 0, 0, 100, 100); 
        cairo_fill(cr);

    }    

    int main(int argc, char **argv)
    {
        gtk_init(&argc, &argv);     
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        gtk_window_set_default_size(GTK_WINDOW(window), 390, 240);

        darea = gtk_drawing_area_new();
        gtk_container_add(GTK_CONTAINER(window), darea); 

        g_signal_connect(darea, "expose-event",
          G_CALLBACK(on_expose_event), NULL);


        gtk_widget_show_all(window);

        gtk_main(); 

        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

为什么要修复它?我的理解是:暴露是:

g_signal_connect(darea, "expose-event", G_GCALLBACK(on_expose_event), NULL); 
Run Code Online (Sandbox Code Playgroud)

告诉程序'当暴露事件发生在darea时,然后调用on_expose_event'.null是您可以传入指向要使用的函数的附加信息的结构的指针的位置.

    static gboolean
    on_expose_event(GtkWidget *widget,
        GdkEventExpose *event,
        gpointer data)
    {
Run Code Online (Sandbox Code Playgroud)

表示on_expose_event传递指向事件发生的窗口小部件的指针,在这种情况下,因为它是一个公开事件,一个指向包含有关公开事件的信息的结构的指针,以及一个指向结构的指针,你可能会喜欢任何其他信息加上.

pto*_*ato 9

使用Cairo绘制小部件适用于公开事件.这是因为开罗不像矢量绘图程序,其中线条和形状是被记住并可被操纵的对象; 开罗只是将形状描绘到绘图区域并忘记它们.

因此,当您最小化并恢复窗口,或在其上方移动另一个窗口时,形状将消失.生成一个公开事件,让您知道形状已消失,并且需要重新绘制窗口小部件.所以你在expose事件处理程序中使用Cairo进行重绘.