c - 如何在 GTK+3 的 gtk 窗口中创建 cairo 对象

标签 c gtk cairo

我正在尝试使用 cairo 绘制一些弧线,但 gcc 警告我 gdk_cairo_create() is deprecated. Use gdk_window_begin_draw_frame() and gdk_drawing_context_get_cairo_context() instead .

为了解决这个问题,我做了一些研究,发现对于 gdk_window_begin_draw_frame() 我需要“GdkWindow”。我一直在我的窗口中使用 GtkWidget,所以我需要将“GtkWidget”转换为“GdkWindow”,但是 gtk_widget_get_window() 返回NULL 并导致段错误。

#include <gtk/gtk.h>
#include <cairo.h>
void main(int argc , char **argv){
    gtk_init(&argc , &argv);
    GtkWidget *win;
    GdkWindow *gdkwin;
    GdkDrawingContext *dc;

    cairo_region_t *region;

    cairo_t *cr;


    win = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    region = cairo_region_create();

    gdkwin = gtk_widget_get_window(GTK_WIDGET(win));

    //Here gdkwin should contain a GdkWindow but it's NULL.

    gc = gdk_window_begin_draw_frame(gdkwin , (const cairo_region_t*)&region);
    ...
    ...

这是运行时错误:
(a.out:6852): Gdk-CRITICAL **: 23:53:06.042: gdk_window_begin_draw_frame: assertion 'GDK_IS_WINDOW (window)' failed

(a.out:6852): Gdk-CRITICAL **: 23:53:06.042: gdk_drawing_context_get_cairo_context: assertion 'GDK_IS_DRAWING_CONTEXT (context)' failed
Segmentation fault

我想获得一个 cairo 对象并将其用于 cairo_arc()。

谢谢。最好的问候。

最佳答案

下面是让 Cairo 在 GTK 3 下工作的完整源代码。它应该可以按原样编译。

正如其他人已经指出的那样,您必须使用绘制信号才能使事情正常进行。

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

    // ------------------------------------------------------------

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

        // "convert" the G*t*kWidget to G*d*kWindow (no, it's not a GtkWindow!)
        GdkWindow* window = gtk_widget_get_window(widget);  

        cairo_region_t * cairoRegion = cairo_region_create();

        GdkDrawingContext * drawingContext;
        drawingContext = gdk_window_begin_draw_frame (window,cairoRegion);

        { 
            // say: "I want to start drawing"
            cairo_t * cr = gdk_drawing_context_get_cairo_context (drawingContext);

            { // do your drawing
                cairo_move_to(cr, 30, 30);
                cairo_set_font_size(cr,15);
                cairo_show_text(cr, "hello world");
            }

            // say: "I'm finished drawing
            gdk_window_end_draw_frame(window,drawingContext);
        }

        // cleanup
        cairo_region_destroy(cairoRegion);

        return FALSE;
    }

    // ------------------------------------------------------------

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

        GtkWindow * window; 
        { // window setup
            window = (GtkWindow*)gtk_window_new(GTK_WINDOW_TOPLEVEL);
            gtk_window_set_default_size (window, 200, 200);
            gtk_window_set_position     (window, GTK_WIN_POS_CENTER);
            gtk_window_set_title        (window, "Drawing");

            g_signal_connect(window, "destroy", gtk_main_quit, NULL);
        }  

        // create the are we can draw in
        GtkDrawingArea* drawingArea;
        {
            drawingArea = (GtkDrawingArea*) gtk_drawing_area_new();
            gtk_container_add(GTK_CONTAINER(window), (GtkWidget*)drawingArea);

            g_signal_connect((GtkWidget*)drawingArea, "draw", G_CALLBACK(on_draw), NULL);    
        }  


        gtk_widget_show_all ((GtkWidget*)window);
        gtk_main();

        return 0;
    }



    // ------------------------------------------------------------

关于c - 如何在 GTK+3 的 gtk 窗口中创建 cairo 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57699050/

相关文章:

c - 哈希表打印有点乱

linux - 为什么 gtkmm 有时会自动创建第二个线程?

user-interface - Julia 构建错误没有意义

python-3.x - 如何在 Linux 上的 Anaconda 中安装 PyGObject?

gtk - 使用 CMake 的问题 : gtk module

开罗分割图像

python - Cairo 剪辑会产生不需要的边缘

显示父子进程的C程序只显示子进程而不显示父进程

c - 如何修复无法从 esp8266 响应读取serial.find ("OK")

c++ - 我究竟做错了什么? (多线程)