在Gtk3 DrawingArea中绘制PNG失败求助:代码无报错但窗口空白
问题描述
- 使用libgtk-3-0和libcairo2在GtkDrawingArea中绘制PNG图片,编译运行无报错,但生成的窗口为空白,未显示图片。
- 编译运行步骤:
- 将代码保存为
draw_png.c; - 修改代码中的图片路径为本地可访问路径;
- 使用命令
gcc -g3 draw_png.c -o draw_png \pkg-config gtk+-3.0 --cflags --libs`` 编译; - 运行可执行文件
draw_png。
- 将代码保存为
问题原因
- GtkDrawingArea未设置尺寸:默认创建的GtkDrawingArea没有指定大小,窗口显示时其尺寸为0,导致绘制内容无法被看到。
- Cairo绘制逻辑错误:调用
cairo_set_source_surface后直接使用cairo_fill,但此时Cairo上下文没有任何路径,cairo_fill不会执行任何绘制操作,需使用cairo_paint()绘制整个源表面。 - 未检查图片加载状态:没有判断
cairo_image_surface_create_from_png的返回值,若图片路径错误或加载失败,无法及时发现问题。 - 预处理宏使用错误:
#ifndef CAIRO_HAS_PNG_FUNCTIONS后直接写printf属于全局作用域的非法代码,正确做法是在函数内通过预处理指令判断并输出提示。
可运行示例代码
/*compile with gcc -g3 draw_png.c -o draw_png `pkg-config gtk+-3.0 --cflags --libs`*/ #include <gtk/gtk.h> #include <stdio.h> /*---------------------------------------------------------------------*/ // 绘制图片回调函数 gboolean draw_image(GtkWidget *drawing_area, cairo_t *cr, gpointer data) { const char *filename = "/home/mattor/Images/GTKIcon.png"; // 修改为你的本地图片路径 cairo_surface_t *image_surface = cairo_image_surface_create_from_png(filename); // 检查图片是否加载成功 if (cairo_surface_status(image_surface) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Failed to load image: %s\n", cairo_status_to_string(cairo_surface_status(image_surface))); return FALSE; } // 设置绘制源并绘制整个表面 cairo_set_source_surface(cr, image_surface, 0, 0); cairo_paint(cr); // 释放资源 cairo_surface_destroy(image_surface); printf("Cairo status after drawing: %s\n", cairo_status_to_string(cairo_status(cr))); return FALSE; } /*---------------------------------------------------------------------*/ int main(int argc, char *argv[]) { GtkWidget *window, *drawing_area; gtk_init(&argc, &argv); // 检查Cairo是否支持PNG #ifndef CAIRO_HAS_PNG_FUNCTIONS fprintf(stderr, "WARNING: Cairo has no PNG support functions\n"); #endif // 创建窗口 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "PNG Viewer"); gtk_window_set_default_size(GTK_WINDOW(window), 400, 300); // 设置窗口默认大小 g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); // 创建DrawingArea并设置大小 drawing_area = gtk_drawing_area_new(); gtk_widget_set_size_request(drawing_area, 400, 300); // 设置DrawingArea的最小尺寸 gtk_container_add(GTK_CONTAINER(window), drawing_area); g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(draw_image), NULL); // 显示所有控件 gtk_widget_show_all(window); gtk_main(); return 0; }
内容的提问来源于stack exchange,提问作者Nathan
相关产品推荐
相关产品推荐

