Basically, all you need to do is to write a new GObject that implements the GtkTreeModel interface, GtkTreeModelIface. Intimate knowledge about the GLib GObject system is not a requirement - you just need to copy some boilerplate code and modify it a bit. The core of your custom tree model is your own implementation of a couple of gtk_tree_model_foo functions that reveal the structure of your data, ie. how many rows there are, how many children a row has, how many columns there are and what type of data they contain. Furthermore, you need to provide functions that convert a tree path to a tree iter and a tree iter to a tree path. Additionally, you should provide some functions to add and remove rows to your custom model, but those are only ever used by yourself anyway, so they do not fall within the scope of the tree model interface.
The functions you need to implement are:
get_flags - tells the outside that your model has certain special characterstics, like persistent iters.
get_n_columns - how many data fields per row are visible to the outside that uses gtk_tree_model_get, e.g. cell renderer attributes
get_column_type - what type of data is stored in a data field (model column) that is visible to the outside
get_iter - take a tree path and fill an iter structure so that you know which row it refers to
get_path - take an iter and convert it into a tree path, ie. the 'physical' position within the model
get_value - retrieve data from a row
iter_next - take an iter structure and make it point to the next row
iter_children - tell whether the row represented by a given iter has any children or not
iter_n_children - tell how many children a row represented by a given iter has
iter_nth_child - set a given iter structure to the n-th child of a given parent iter
iter_parent - set a given iter structure to the parent of a given child iter
It is up to you to decide which of your data you make 'visible' to the outside in form of model columns and which not. You can always implement functions specific to your custom model that will return any data in any form you desire. You only need to make data 'visble' to the outside via the GType and GValue system if you want the tree view components to access it (e.g. when setting cell renderer attributes).