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

GTK3中TreeView无法显示指定目录归档文件的问题求助

解决GTK TreeView无法显示归档文件的问题

核心错误点

  • 重复创建TreeView实例:从Glade加载tree_view_lista_cadastro后,又调用gtk_tree_view_new_with_model创建新TreeView,但新实例从未添加到窗口布局,导致Glade原TreeView始终无内容。
  • ListStore数据插入错误:使用gtk_list_store_set前未通过gtk_list_store_append创建新行,且参数格式错误,无法正确插入数据。
  • 列定义与Store不匹配:ListStore仅定义1列(字符串类型),但创建列时试图绑定不存在的第1列(索引从0开始)作为背景色,引发无效绑定。
  • TreeView布局属性错误:Glade中TreeView的expand属性设为False,控件无法扩展显示空间,即便有内容也可能被隐藏。

修正后的C代码

void listar_cadastro()
{
    // GTK构造器变量
    GtkBuilder *construtor = NULL;
    GtkWidget *janela_lista_cadastro = NULL;
    GtkWidget *tree_view;
    GtkListStore *list_store;
    GtkTreeIter iter;
    GtkTreeViewColumn *coluna;

    // 创建ListStore,仅1列字符串类型
    list_store = gtk_list_store_new(1, G_TYPE_STRING);

    DIR *diretorio;
    struct dirent *lsdiretorio;
    const char ponto[10] = ".cadastro";

    construtor = gtk_builder_new_from_file("lista_cadastro.glade");
    if(construtor==NULL)
    {
        printf("ERRO! Nao foi possivel carregar o arquivo lista_cadastro.glade!!\n");
        return;
    }

    janela_lista_cadastro = GTK_WIDGET(gtk_builder_get_object(construtor, "janela_lista_cadastro"));
    if(janela_lista_cadastro==NULL)
    {
        printf("ERRO! Nao foi possivel criar o widget janela_lista_cadastro!\n");
        return;
    }

    tree_view = GTK_WIDGET(gtk_builder_get_object(construtor, "tree_view_lista_cadastro"));
    if(tree_view==NULL)
    {
        printf("ERRO! Nao foi possivel criar o widget tree_view!\n");
        return;
    }

    printf("Listando todos os cadastros...\n");

    // 打开目录
    if((diretorio = opendir("./Cadastros"))==NULL)
    {
        printf("Erro! Nao foi possivel abrir a pasta dos cadastros!\n");
        return;
    }

    // 遍历目录文件
    while ((lsdiretorio = readdir(diretorio)) != NULL)
    {
        if(strstr(lsdiretorio->d_name, ponto)!=NULL)
        {
            printf("----------------------------------------------------------\n");
            printf("%s\n", lsdiretorio->d_name);
            printf("----------------------------------------------------------\n");

            // 先添加新行到ListStore
            gtk_list_store_append(list_store, &iter);
            // 设置第0列的值为文件名
            gtk_list_store_set(list_store, &iter, 0, lsdiretorio->d_name, -1);
        }
    }

    // 给Glade中的TreeView设置模型
    gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(list_store));
    // 模型会被TreeView持有引用,无需手动unref

    // 创建列并绑定到第0列
    coluna = gtk_tree_view_column_new_with_attributes("Nome do Arquivo", 
                                                      gtk_cell_renderer_text_new(), 
                                                      "text", 0, 
                                                      NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), coluna);

    closedir(diretorio);
    gtk_widget_show_all(janela_lista_cadastro);

    g_object_unref(construtor); // 释放构造器引用
    return;
}

修正后的Glade XML代码

主要修改TreeView的expand属性为True,确保控件能扩展显示:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkWindow" id="janela_lista_cadastro">
    <property name="visible">True</property>
    <property name="can-focus">True</property>
    <property name="title" translatable="yes">Lista de Cadastros</property>
    <property name="default-width">400</property>
    <property name="default-height">400</property>
    <child>
      <object class="GtkBox" id="box1_lista_cadastro">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkLabel" id="label_lista_cadastro">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="label" translatable="yes">Lista de Cadastros</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkTreeView" id="tree_view_lista_cadastro">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <!-- 修改expand为True,让TreeView占满可用空间 -->
            <property name="expand">True</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection"/>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

关键修正说明

  1. 复用Glade的TreeView:直接对从Glade加载的tree_view调用gtk_tree_view_set_model,而非创建新实例。
  2. 正确插入数据:先调用gtk_list_store_append生成新行的iter,再用gtk_list_store_set设置对应列的值,参数格式为(store, &iter, 列索引, 值, -1)。
  3. 匹配列与Store:ListStore仅定义1列,所以列绑定只使用索引0,移除无效的background绑定。
  4. 调整布局属性:将TreeView的expand设为True,确保控件能充分显示内容。

内容的提问来源于stack exchange,提问作者gustavo moretto itikawa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:05:07