GtkDrawingArea - 如何使其可绘制? [英] GtkDrawingArea - how to make it drawable?

查看:153
本文介绍了GtkDrawingArea - 如何使其可绘制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里想到了一点。

我想用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();

返回0;
}

这个编译,但给了我


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 *小部件,
GdkEventExpose *事件,
gpointer数据)
{
cairo_t * cr;
cr = gdk_cairo_create(darea-> window);
cairo_rectangle(cr,0,0,100,100);
cairo_fill(cr);


$ b 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();

返回0;
}

这为什么修复它?
我的理解重申:揭露是:


$ $ $ $ $ $ $ g_signal_connect(darea,expose-event ,G_GCALLBACK(on_expose_event),NULL);

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



  static gboolean 
on_expose_event(GtkWidget * widget,
GdkEventExpose * event,
gpointer data)
{

意味着on_expose_event传递了一个指向事件发生的小部件的指针,在这种情况下,因为它是一个公开事件,指向包含有关公开事件信息的结构的指针以及指向结构的指针,以指向任何其他信息喜欢添加。

解决方案

仅在开发事件中使用Cairo 这是因为开罗不像一个矢量绘图程序,其中线条和形状是被记住并可以被操纵的对象;所以当你最小化和恢复你的窗口,或者移动另一个窗口到顶部时,形状消失。会生成一个公开事件,让您知道形状已消失,并且需要重新绘制小部件。所以你在开发事件处理程序中使用Cairo进行重绘。


I'm going out of my mind a bit here.

I'm trying to draw some simple graphics on my GTK form using cairo.

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

This compiles, but gives me

Gdk-CRITICAL **: IA__gdk_cairo_create: assertion `GDK_IS_DRAWABLE (drawable)' failed

followed by a segfault.

I've been looking at the tutorial here

So I changed my code as follows, made the cairo calls occur inside the expose event.

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

Why does this fix it? My understanding re: the expose is: the

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

tells the program, 'when an expose event happens to darea, then call on_expose_event'. The null is where you can pass in a pointer to a struct of additional information for the function to use.

and

    static gboolean
    on_expose_event(GtkWidget *widget,
        GdkEventExpose *event,
        gpointer data)
    {

means that on_expose_event is passed a pointer to the widget that the event happened to, andin this case because it's an expose event, a pointer to a struct containing information about the expose event, and a pointer to a struct to any other information you might like to add.

解决方案

Drawing on a widget with Cairo only works in an expose event. That is because Cairo is not like a vector drawing program where the lines and shapes are objects that are remembered and can be manipulated; Cairo just paints the shapes onto the drawing area and forgets about them.

So when you minimize and restore your window, or move another window over top of it, the shapes disappear. An expose event is generated to let you know that the shapes are gone and the widget needs to be redrawn. So you do your redrawing with Cairo in the expose event handler.

这篇关于GtkDrawingArea - 如何使其可绘制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆