How to change data of a GtkTreeModel (within “edited” callback)

 ̄綄美尐妖づ 提交于 2020-01-05 05:44:28

问题


I'm catching the "edited" signal of my GtkCellRenderer:

GtkTreeModel * sortmodel; // contains a sorted model of GtkListStore

// ...

GtkCellRenderer * renderer;

// ...

g_object_set(renderer, "editable", TRUE, NULL);    
g_signal_connect(renderer, "edited",
                G_CALLBACK(onEdited_name), sortmodel);

I'd now like to change the content of the cell accordingly, but I don't find any function, that would change the content of a cell of a GtkTreeModel.

void onEdited_name(GtkCellRendererText *cell,
                        gchar * path_string,
                        gchar * new_text,
                        gpointer treemodel)
{
  GtkTreeModel * model = GTK_TREE_MODEL(treemodel);

  GtkTreeIter iter;
  gtk_tree_model_get_iter_from_string(model, &iter, path_string);  

  // TODO: set the value according to iter.
  // gtk_list_store_set will not work of course, because
  //  we're operating on a GtkTreeModel   
}  

This question is related to: Changing the content of a GTK Tree View


回答1:


Your first code snippet is correct.

  1. You cannot change a value on a GtkTreeModel.
  2. You can only change a value on the "raw" model (the base model like GtkListStore or GtkTreeStore).

Theory - Good to know

Gtk hierarchy

The following picture shows the GtkTreeModel hierarchy and what (important) functions they offer

As you can see, if you want to change the values of cells, you need to differentiate what kind of model you're actually working on.

GtkCellRenderer and the "edited" signal / callback

One Renderer should only be "assigned" to one column. Otherwise you don't know which column the user tried to change.

Change value of a GtkTreeModelSort of a GtkTreeStore

See the example below for GtkListStore, and replace GtkListStore with GtkTreeStore. That should hopefully do the trick.

Change value of a GtkTreeModelSort of a GtkListStore

void 
onEdited_name (GtkCellRendererText * cell,
               gchar               * path_string,
               gchar               * new_text,
               gpointer              p_model_sorted)
{       
    // we need to convert to GtkListStore, because GtkTreeModel does not
    //  provide an interface for cell content changing.


    // convert raw data to the actual type
    GtkTreeModelSort * model_sorted = GTK_TREE_MODEL_SORT(p_model_sorted);

    // get the iterator within the sorted model
    GtkTreeIter iter_sortedModel;
    gtk_tree_model_get_iter_from_string((GtkTreeModel*)model_sorted,
                  &iter_sortedModel, path_string);          

    // convert sorted model to raw model
    GtkListStore * model_raw;       
    model_raw = GTK_LIST_STORE(gtk_tree_model_sort_get_model(model_sorted));

    // convert the iterator to one of the raw model.
    // (Otherwise the wrong cell will change)
    GtkTreeIter iter_rawModel;
    gtk_tree_model_sort_convert_iter_to_child_iter(model_sorted, &iter_rawModel, &iter_sortedModel);


    gtk_list_store_set(model_raw, &iter_rawModel,
                                LIST_COL_NAME, new_text, -1);
} 

Change value of a GtkListStore OR GtkTreeModelSort of GtkListStore

Imagine you have two GtkTreeViews shown based on the same model. One is sorted, the other one not. This function will show you how to manage those.

Note, that we now pass a GtkTreeView as gpointer, instead of GtkTreeModel.

void onEdited_name(GtkCellRendererText *cell,
                        gchar * path_string,
                        gchar * new_text,
                        gpointer _treeview) // <--- GtkTreeView now!!!!
{
    // we HAVE TO use GtkTreeView within gpointer!
    //  otherwise we could not differntiate the model type!
    GtkTreeView * treeview = GTK_TREE_VIEW(_treeview);
    GtkTreeModel * treeModel = gtk_tree_view_get_model(treeview);

    // we need to use GtkListStore, because GtkTreeModel does not
    //  provide an interface for cell changing.
    GtkListStore * model;   
    GtkTreeIter iter_rawModel;

    // check if we're working on the raw model or on a sorted version
    //  of it
    if(GTK_IS_LIST_STORE(treeModel)){
        // just use the model as is    
        model = GTK_LIST_STORE(treeModel);

        // retrieve the iterator for the cell, that should be changed
        gtk_tree_model_get_iter_from_string((GtkTreeModel*)model,
                                            &iter_rawModel, path_string);

    } else { // we're working on a sorted model   
        // We need to change to a usual model.
        GtkTreeModelSort * sortedModel = GTK_TREE_MODEL_SORT(treeModel);
        model = GTK_LIST_STORE(gtk_tree_model_sort_get_model(sortedModel));

        // get the iterator within the sorted model
        GtkTreeIter iter_sortedModel;
        gtk_tree_model_get_iter_from_string((GtkTreeModel*)sortedModel,
                              &iter_sortedModel, path_string);  

        // convert the iterator to one of the raw model.
        // (Otherwise the wrong cell will change)
        gtk_tree_model_sort_convert_iter_to_child_iter(sortedModel, &iter_rawModel, &iter_sortedModel);
    }


    gtk_list_store_set(GTK_LIST_STORE(model), &iter_rawModel,
                LIST_COL_NAME, new_text, -1);

}   


来源:https://stackoverflow.com/questions/59158325/how-to-change-data-of-a-gtktreemodel-within-edited-callback

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!