c - 单列 gtktreeview 行为正确,但多列给出段错误

标签 c gtk segmentation-fault

我对 GtkTreeView 有以下问题。

当我尝试附加列表时出现问题。这是我创建的函数:

  static GtkWidget *setup_list_archive(GtkWidget **widget)
  {
    GtkWidget *sc_win;
    GtkListStore *store;
    GtkCellRenderer *cell;
    GtkTreeViewColumn *column;

    sc_win = gtk_scrolled_window_new(NULL, NULL);
    gtk_widget_set_usize(sc_win, 250, 150);
    store = gtk_list_store_new(COL, G_TYPE_STRING, G_TYPE_STRING);
    *widget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));

    cell = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes("Klucz", cell, "text", ID, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(*widget), column);

    cell = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes("Data", cell, "text", DATA, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(*widget), column);

    cell = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes("Godzina", cell, "text", CZAS, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(*widget), column);

    // scrolls behavior
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    gtk_container_add(GTK_CONTAINER(sc_win), *widget);

    // free the objects
    g_object_unref(G_OBJECT(store));
    return sc_win;
  }

这是我附加列表的函数。

  static void list_add_archive(GtkWidget* widget, gpointer data)
  {
    arch *rekord = (arch*) data;
    printf("key: %s; pas: %s; dat: %s;\n", rekord->id, rekord->czas, rekord->data);
    GtkListStore *store;
    GtkTreeIter iter;
    store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget)));

    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, rekord->id, DATA, rekord->czas, CZAS, rekord->data, -1);
  }

问题出现在多列类型的列表中。如果我用一列创建列表,它工作正常。

这是我的回溯。

  key: 1; pas: 14; dat: 2013-06-22 12:24:58;

  Breakpoint 1, list_add_archive (widget=0x80e0c40, data=0xbfffe704)
at admin.c:512
  512       gtk_list_store_append(store, &iter);
  (gdb) step
  513       gtk_list_store_set(store, &iter, ID, "a", DATA, "b", CZAS, "c", -1);
  (gdb) step

  Program received signal SIGSEGV, Segmentation fault.
  0xb76b8ff5 in g_type_value_table_peek ()
     from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  (gdb) step
  Single stepping until exit from function g_type_value_table_peek,
  which has no line number information.

  Program terminated with signal SIGSEGV, Segmentation fault.
  The program no longer exists.
  (gdb) step
  The program is not being run.

g_type_value_table_peek,没有行号信息 让我觉得也许定义列号的枚举不正确,我试着只写整数而不是枚举值。它没有帮助。

正如您在我的调试器结果的开头看到的那样,屏幕上打印了 printf 的内容,因此数据结构 record 中的值存在并且是正确的。无论如何,我尝试将 const chars 放入参数中,但它没有任何改变。

如果我传递 null 作为列表的参数,它只显示一个警告,比如 invalid cast 等等,当然它也不起作用 :) 它是奇怪的是没有像段错误这样的严重错误。

最佳答案

我不确定,因为您没有显示常量的值,但是您创建了一个包含 2 列的存储,假设 COL 等于 2:

gtk_list_store_new(COL, G_TYPE_STRING, G_TYPE_STRING);

但是你存储了 3 个值,这是不可能的,因为后一列不存在:

gtk_list_store_set(store, &iter, ID, rekord->id, DATA, rekord->czas, CZAS, rekord->data, -1);

我的猜测是您有一个类似于以下的枚举:

enum { ID, DATA, CZAS, COL };

如果是这种情况,COL 等于 3,而不是 2,因此存储的最后一列将获得未定义的类型。一个非常糟糕的情况。要解决它,只需在商店创建中添加缺少的字段:

gtk_list_store_new(COL, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);

如果 COL 确实等于 2,那么您应该将其更改为 3,并添加 3 种类型。

关于c - 单列 gtktreeview 行为正确,但多列给出段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17251094/

相关文章:

c - 在不复制实例的情况下多次执行程序

linux - 当窗口不可见时计算 GtkFrame 的边框大小

c++ - 在 C++ 中多次处理段错误

c - sem_post 的段错误

c - C 中处理错误的风格?

c - 以下C代码有什么问题

python - 当窗口/对话框为 "presented"时发出 gtk+ 信号

c++ - 连接到 Gtk::Window signal_delete_event

c float 和 int 长度问题(段错误)

c - 在 C 中动态地从 3D 数组到 2D 数组