C - GTK 4 - 能够从列表存储中删除行但无法将行附加到列表存储

C - GTK 4 - Able to remove row from liststore but unable to append row to liststore

我正在尝试用 C 编写一个程序,并为 Linux 启用 GTK 4.0,我正在尝试更新列表存储中的所有行并向列表存储中添加一些行。我可以使用 gtk_list_store_remove 但是当我尝试使用 gtk_list_store_append 时程序崩溃了:

Gtk:ERROR:../gtk/gtk/gtktreerbtree.c:475:gtk_tree_rbtree_insert_after: assertion failed: (gtk_tree_rbtree_is_nil (tree->root))
Bail out! Gtk:ERROR:../gtk/gtk/gtktreerbtree.c:475:gtk_tree_rbtree_insert_after: assertion failed: (gtk_tree_rbtree_is_nil (tree->root))

最后一部分在 Arch Linux 和 Ubuntu 上有所不同。

Arch Linux:

[1]    [PID] IOT instruction (core dumped) [executable]

Ubuntu:

Aborted (core dumped)

我曾尝试使用 gtk_list_store_insert 创建新行,但结果相同。下面是我在发生崩溃的地方的代码片段。 GitHub 上提供了所有代码。 GitHub 上的代码现在略有不同,但仍然存在相同的问题。

gboolean valid;
GtkTreeIter iter;
GtkTreeIter curr_iter;
GtkListStore *store = GTK_LIST_STORE(model);

valid = gtk_tree_model_get_iter_first(model, &iter);
// Add or Remove rows so that the total number of rows is equal to rowsWanted
while (valid){
    valid = gtk_tree_model_iter_next(model, &iter);
    if (valid == false && rowsWanted > gtk_tree_model_iter_n_children(model, NULL)){
        // The error occurs here
        gtk_list_store_append(store, &iter);
        gtk_tree_model_row_inserted(model, gtk_tree_model_get_path(model, &iter), &iter);
        //valid = gtk_tree_model_iter_next(model, &iter);
        valid = true;
    }
    else if (valid == true && rowsWanted < gtk_tree_model_iter_n_children(model, NULL)){
       gtk_list_store_remove(store, &iter);
       gtk_tree_model_row_deleted(model, gtk_tree_model_get_path(model, &iter));
    }
}

有谁知道为什么会这样?谢谢。

编辑: 运行 通过终端而不是通过我的 IDE 执行可执行文件后,我看到“IOT 指令(核心转储)”。我是 运行 Arch Linux x86_64.

编辑 2: 在 Ubuntu 21.10 VM 上,我没有收到 IOT 指令,而是收到“已中止(核心已转储)”(更有意义,因为断言失败)。 GTK 错误仍然相同。

虽然我无法重现这一点(在 flatpak 环境中),但调用 gtk_tree_model_row_inserted()gtk_tree_model_row_deleted() 对我来说似乎非常可疑。

据我所知,GtkTreeView 使用内部 RBTree 实现,它使用这些信号来了解何时更新。 gtk_list_store_append() and gtk_list_store_remove() 已经调用了这些信号,因此为同一元素发出两次 row-inserted 信号是错误的。

在我这边,当我手动将您的代码插入 GitHub 时,我收到如下消息:

(taskmonitor:19172): Gtk-CRITICAL **: 00:00:00.000: ../gtk/gtktreeview.c:4960 (gtk_tree_view_bin_snapshot): assertion `has_next' failed.
There is a disparity between the internal view of the GtkTreeView,
and the GtkTreeModel.  This generally means that the model has changed
without letting the view know.  Any display from now on is likely to
be incorrect.

因此,请尝试删除分别调用 gtk_tree_model_row_inserted()gtk_tree_model_row_deleted() 的这两行。