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

GTK3结合Glade读取SQLite3数据动态切换图片仅显示最后一张如何解决

问题根因

GTK采用单线程事件驱动的主循环机制,你的回调函数add_image_cb是在主循环线程中执行的,在函数执行完成前,GTK不会处理任何UI重绘请求,所以你在while循环里快速切换图片的操作都被积压了,等函数执行完只留下最后一次添加的图片生效。哪怕你取消注释sleep(1)也没用,sleep只会阻塞整个主循环,UI完全卡住不会更新。

同时你的原代码还存在SQLite资源泄漏问题:sqlite3_prepare_v2创建的语句对象没有调用sqlite3_finalize释放,也没有关闭数据库连接。


修复方案

你需要把轮播逻辑拆成两步:首先一次性从SQLite读取所有文件名存到列表里,再用GTK的定时器g_timeout_add定时切换图片,不阻塞主循环。

步骤1:先定义全局/静态变量存储轮播所需数据

// 可根据需求调整存储方式,全局变量方便跨回调调用
static GList *image_path_list = NULL; // 存储所有图片路径
static guint timer_id = 0; // 定时器ID
static gint current_index = 0; // 当前展示的图片索引
static GtkWidget *current_image = NULL; // 当前展示的图片控件

步骤2:修改按钮回调函数,仅做数据读取和定时器注册

G_MODULE_EXPORT void add_image_cb(GtkButton *button)
{
    sqlite3 * db;
    char * sql;
    sqlite3_stmt * stmt;
    int s;
    char jpeg[] = ".jpg";
    char name[30];

    // 先清理之前的轮播残留资源
    if (timer_id > 0) {
        g_source_remove(timer_id);
        timer_id = 0;
    }
    if (image_path_list) {
        g_list_free_full(image_path_list, g_free);
        image_path_list = NULL;
    }
    current_index = 0;

    // 读取所有文件名存入列表
    sqlite3_open("list.db", &db);
    sql = "SELECT name FROM name_list";
    sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL);

    while((s = sqlite3_step(stmt)) == SQLITE_ROW) {
        const unsigned char * text = sqlite3_column_text(stmt, 0);
        strcpy(name, text);
        strcat(name, jpeg);
        image_path_list = g_list_append(image_path_list, g_strdup(name));
    }

    // 释放SQLite资源
    sqlite3_finalize(stmt);
    sqlite3_close(db);

    if (g_list_length(image_path_list) == 0) return;

    // 注册定时器,每1000ms(1秒)切换一次图片,单位可自行调整
    timer_id = g_timeout_add(1000, (GSourceFunc)switch_image, NULL);
}

步骤3:实现定时器回调函数,单独处理图片切换逻辑

gboolean switch_image(gpointer user_data)
{
    gint total = g_list_length(image_path_list);
    if (total == 0) return G_SOURCE_REMOVE;

    // 移除之前的图片控件
    if (current_image) {
        gtk_container_remove(GTK_CONTAINER(fixed1), current_image);
        current_image = NULL;
    }

    // 加载当前索引对应的图片
    gchar *path = g_list_nth_data(image_path_list, current_index);
    current_image = gtk_image_new_from_file(path);
    gtk_widget_show(current_image);
    gtk_container_add(GTK_CONTAINER(fixed1), current_image);

    // 索引自增,到末尾自动循环
    current_index = (current_index + 1) % total;

    return G_SOURCE_CONTINUE; // 保持定时器持续执行
}

编译命令保持不变

gcc `pkg-config --cflags gtk+-3.0` -rdynamic -o test2 test2.c `pkg-config --libs gtk+-3.0` -lsqlite3 -std=c99

内容的提问来源于stack exchange,提问作者NACHANON AIMSRICHAROEN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:27:02