You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Gtk3 DrawingArea中绘制PNG失败求助:代码无报错但窗口空白

问题描述

  • 使用libgtk-3-0和libcairo2在GtkDrawingArea中绘制PNG图片,编译运行无报错,但生成的窗口为空白,未显示图片。
  • 编译运行步骤:
    1. 将代码保存为draw_png.c;
    2. 修改代码中的图片路径为本地可访问路径;
    3. 使用命令 gcc -g3 draw_png.c -o draw_png \pkg-config gtk+-3.0 --cflags --libs`` 编译;
    4. 运行可执行文件draw_png。

问题原因

  1. GtkDrawingArea未设置尺寸:默认创建的GtkDrawingArea没有指定大小,窗口显示时其尺寸为0,导致绘制内容无法被看到。
  2. Cairo绘制逻辑错误:调用cairo_set_source_surface后直接使用cairo_fill,但此时Cairo上下文没有任何路径,cairo_fill不会执行任何绘制操作,需使用cairo_paint()绘制整个源表面。
  3. 未检查图片加载状态:没有判断cairo_image_surface_create_from_png的返回值,若图片路径错误或加载失败,无法及时发现问题。
  4. 预处理宏使用错误:#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.10 09:03:10