class Gtk::ListStore

Overview

A list-like data structure that can be used with the Gtk::TreeView.

The Gtk::ListStore object is a list model for use with a Gtk::TreeView widget. It implements the Gtk::TreeModel interface, and consequentialy, can use all of the methods available there. It also implements the Gtk::TreeSortable interface so it can be sorted by the view. Finally, it also implements the tree drag and drop interfaces.

The Gtk::ListStore can accept most GTypes as a column type, though it can’t accept all custom types. Internally, it will keep a copy of data passed in (such as a string or a boxed pointer). Columns that accept GObjects are handled a little differently. The Gtk::ListStore will keep a reference to the object instead of copying the value. As a result, if the object is modified, it is up to the application writer to call Gtk::TreeModel#row_changed to emit the Gtk::TreeModel::#row_changed signal. This most commonly affects lists with Gdk::Textures stored.

An example for creating a simple list store:

WARNING ⚠️ The following code is in c ⚠️

enum {
  COLUMN_STRING,
  COLUMN_INT,
  COLUMN_BOOLEAN,
  N_COLUMNS
};

{
  Gtk::ListStore *list_store;
  Gtk::TreePath *path;
  Gtk::TreeIter iter;
  int i;

  list_store = gtk_list_store_new (N_COLUMNS,
                                   G_TYPE_STRING,
                                   G_TYPE_INT,
                                   G_TYPE_BOOLEAN);

  for (i = 0; i < 10; i++)
    {
      char *some_data;

      some_data = get_some_data (i);

      // Add a new row to the model
      gtk_list_store_append (list_store, &iter);
      gtk_list_store_set (list_store, &iter,
                          COLUMN_STRING, some_data,
                          COLUMN_INT, i,
                          COLUMN_BOOLEAN,  FALSE,
                          -1);

      // As the store will keep a copy of the string internally,
      // we free some_data.
      g_free (some_data);
    }

  // Modify a particular row
  path = gtk_tree_path_new_from_string ("4");
  gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store),
                           &iter,
                           path);
  gtk_tree_path_free (path);
  gtk_list_store_set (list_store, &iter,
                      COLUMN_BOOLEAN, TRUE,
                      -1);
}

Performance Considerations

Internally, the Gtk::ListStore was originally implemented with a linked list with a tail pointer. As a result, it was fast at data insertion and deletion, and not fast at random data access. The Gtk::ListStore sets the GTK_TREE_MODEL_ITERS_PERSIST flag, which means that Gtk::TreeIters can be cached while the row exists. Thus, if access to a particular row is needed often and your code is expected to run on older versions of GTK, it is worth keeping the iter around.

Atomic Operations

It is important to note that only the methods gtk_list_store_insert_with_values() and gtk_list_store_insert_with_valuesv() are atomic, in the sense that the row is being appended to the store and the values filled in in a single operation with regard to Gtk::TreeModel signaling. In contrast, using e.g. gtk_list_store_append() and then gtk_list_store_set() will first create a row, which triggers the Gtk::TreeModel::row-inserted signal on Gtk::ListStore. The row, however, is still empty, and any signal handler connecting to Gtk::TreeModel::row-inserted on this particular store should be prepared for the situation that the row might be empty. This is especially important if you are wrapping the Gtk::ListStore inside a Gtk::TreeModelFilter and are using a Gtk::TreeModelFilterVisibleFunc. Using any of the non-atomic operations to append rows to the Gtk::ListStore will cause the Gtk::TreeModelFilterVisibleFunc to be visited with an empty row first; the function must be prepared for that.

Gtk::ListStore as Gtk::Buildable

The Gtk::ListStore implementation of the Gtk::Buildable interface allows to specify the model columns with a <columns> element that may contain multiple <column> elements, each specifying one model column. The “type” attribute specifies the data type for the column.

Additionally, it is possible to specify content for the list store in the UI definition, with the <data> element. It can contain multiple <row> elements, each specifying to content for one row of the list model. Inside a <row>, the <col> elements specify the content for individual cells.

Note that it is probably more common to define your models in the code, and one might consider it a layering violation to specify the content of a list store in a UI definition, data, not presentation, and common wisdom is to separate the two, as far as possible.

An example of a UI Definition fragment for a list store:

WARNING ⚠️ The following code is in xml ⚠️

<object class="Gtk::ListStore">
  <columns>
    <column type="gchararray"/>
    <column type="gchararray"/>
    <column type="gint"/>
  </columns>
  <data>
    <row>
      <col id="0">John</col>
      <col id="1">Doe</col>
      <col id="2">25</col>
    </row>
    <row>
      <col id="0">Johan</col>
      <col id="1">Dahlin</col>
      <col id="2">50</col>
    </row>
  </data>
</object>

Included Modules

Defined in:

lib/gi-crystal/src/auto/gtk-4.0/list_store.cr
lib/gtk4/src/bindings/gtk/list_store.cr

Constructors

Class Method Summary

Instance Method Summary

Instance methods inherited from module Gtk::TreeSortable

default_sort_func=(sort_func : Gtk::TreeIterCompareFunc) : Nil default_sort_func=, has_default_sort_func : Bool has_default_sort_func, set_sort_column_id(sort_column_id : Int32, order : Gtk::SortType) : Nil set_sort_column_id, set_sort_func(sort_column_id : Int32, sort_func : Gtk::TreeIterCompareFunc) : Nil set_sort_func, sort_column_changed : Nil sort_column_changed, sort_column_changed_signal sort_column_changed_signal, sort_column_id(sort_column_id : Int32, order : Gtk::SortType) : Bool sort_column_id, to_unsafe to_unsafe

Class methods inherited from module Gtk::TreeSortable

g_type : UInt64 g_type

Instance methods inherited from module Gtk::TreeModel

column_type(index_ : Int32) : UInt64 column_type, filter_new(root : Gtk::TreePath?) : Gtk::TreeModel filter_new, flags : Gtk::TreeModelFlags flags, foreach(func : Gtk::TreeModelForeachFunc, user_data : Pointer(Void)?) : Nil foreach, iter(path : Gtk::TreePath) : Gtk::TreeIter iter, iter_children(parent : Gtk::TreeIter?) : Gtk::TreeIter iter_children, iter_first : Gtk::TreeIter iter_first, iter_from_string(path_string : String) : Gtk::TreeIter iter_from_string, iter_has_child(iter : Gtk::TreeIter) : Bool iter_has_child, iter_n_children(iter : Gtk::TreeIter?) : Int32 iter_n_children, iter_next(iter : Gtk::TreeIter) : Bool iter_next, iter_nth_child(parent : Gtk::TreeIter?, n : Int32) : Gtk::TreeIter iter_nth_child, iter_parent(child : Gtk::TreeIter) : Gtk::TreeIter iter_parent, iter_previous(iter : Gtk::TreeIter) : Bool iter_previous, n_columns : Int32 n_columns, path(iter : Gtk::TreeIter) : Gtk::TreePath path, ref_node(iter : Gtk::TreeIter) : Nil ref_node, row_changed(path : Gtk::TreePath, iter : Gtk::TreeIter) : Nil row_changed, row_changed_signal row_changed_signal, row_deleted(path : Gtk::TreePath) : Nil row_deleted, row_deleted_signal row_deleted_signal, row_has_child_toggled(path : Gtk::TreePath, iter : Gtk::TreeIter) : Nil row_has_child_toggled, row_has_child_toggled_signal row_has_child_toggled_signal, row_inserted(path : Gtk::TreePath, iter : Gtk::TreeIter) : Nil row_inserted, row_inserted_signal row_inserted_signal, rows_reordered(path : Gtk::TreePath, iter : Gtk::TreeIter?, new_order : Enumerable(Int32)) : Nil rows_reordered, string_from_iter(iter : Gtk::TreeIter) : String? string_from_iter, to_unsafe to_unsafe, unref_node(iter : Gtk::TreeIter) : Nil unref_node, value(iter : Gtk::TreeIter, column : Int32) : GObject::Value value

Class methods inherited from module Gtk::TreeModel

g_type : UInt64 g_type

Instance methods inherited from module Gtk::TreeDragSource

drag_data_delete(path : Gtk::TreePath) : Bool drag_data_delete, drag_data_get(path : Gtk::TreePath) : Gdk::ContentProvider? drag_data_get, row_draggable(path : Gtk::TreePath) : Bool row_draggable, to_unsafe to_unsafe

Class methods inherited from module Gtk::TreeDragSource

g_type : UInt64 g_type

Instance methods inherited from module Gtk::TreeDragDest

drag_data_received(dest : Gtk::TreePath, value : _) : Bool drag_data_received, row_drop_possible(dest_path : Gtk::TreePath, value : _) : Bool row_drop_possible, to_unsafe to_unsafe

Class methods inherited from module Gtk::TreeDragDest

g_type : UInt64 g_type

Instance methods inherited from module Gtk::Buildable

buildable_id : String? buildable_id, to_unsafe to_unsafe

Class methods inherited from module Gtk::Buildable

g_type : UInt64 g_type

Instance methods inherited from class GObject::Object

bind_property(source_property : String, target : GObject::Object, target_property : String, flags : GObject::BindingFlags) : GObject::Binding bind_property, bind_property_full(source_property : String, target : GObject::Object, target_property : String, flags : GObject::BindingFlags, transform_to : GObject::Closure, transform_from : GObject::Closure) : GObject::Binding bind_property_full, data(key : String) : Pointer(Void)? data, finalize finalize, freeze_notify : Nil freeze_notify, getv(names : Enumerable(String), values : Enumerable(_)) : Nil getv, notify(property_name : String) : Nil notify, notify_by_pspec(pspec : GObject::ParamSpec) : Nil notify_by_pspec, notify_signal notify_signal, property(property_name : String, value : _) : Nil property, qdata(quark : UInt32) : Pointer(Void)? qdata, ref_count : UInt32 ref_count, run_dispose : Nil run_dispose, set_data(key : String, data : Pointer(Void)?) : Nil set_data, set_property(property_name : String, value : _) : Nil set_property, steal_data(key : String) : Pointer(Void)? steal_data, steal_qdata(quark : UInt32) : Pointer(Void)? steal_qdata, thaw_notify : Nil thaw_notify, to_unsafe : Pointer(Void) to_unsafe, watch_closure(closure : GObject::Closure) : Nil watch_closure

Constructor methods inherited from class GObject::Object

cast(obj : GObject::Object) : self cast, cast?(obj : GObject::Object) : self? cast?, new(pointer : Pointer(Void), transfer : GICrystal::Transfer)
new
new
, newv(object_type : UInt64, parameters : Enumerable(GObject::Parameter)) : self newv

Class methods inherited from class GObject::Object

compat_control(what : UInt64, data : Pointer(Void)?) : UInt64 compat_control, g_type : UInt64 g_type, interface_find_property(g_iface : GObject::TypeInterface, property_name : String) : GObject::ParamSpec interface_find_property, interface_list_properties(g_iface : GObject::TypeInterface) : Enumerable(GObject::ParamSpec) interface_list_properties

Constructor Detail

def self.new(types : Enumerable(UInt64)) : self #

Creates a new list store as with @n_columns columns each of the types passed in. Note that only types derived from standard GObject fundamental types are supported.

As an example, gtk_list_store_new (3, G_TYPE_INT, G_TYPE_STRING, GDK_TYPE_TEXTURE); will create a new Gtk::ListStore with three columns, of type int, string and Gdk::Texture, respectively.


def self.new #

Initialize a new ListStore.


def self.new(*types : UInt64) #

Class Method Detail

def self.g_type : UInt64 #

Returns the type id (GType) registered in GLib type system.


Instance Method Detail

def append : Gtk::TreeIter #

Appends a new row to @list_store. @iter will be changed to point to this new row. The row will be empty after this function is called. To fill in values, you need to call gtk_list_store_set() or gtk_list_store_set_value().


def clear : Nil #

Removes all rows from the list store.


def column_types=(types : Enumerable(UInt64)) : Nil #

This function is meant primarily for GObjects that inherit from Gtk::ListStore, and should only be used when constructing a new Gtk::ListStore. It will not function after a row has been added, or a method on the Gtk::TreeModel interface is called.


def insert(position : Int32) : Gtk::TreeIter #

Creates a new row at @position. @iter will be changed to point to this new row. If @position is -1 or is larger than the number of rows on the list, then the new row will be appended to the list. The row will be empty after this function is called. To fill in values, you need to call gtk_list_store_set() or gtk_list_store_set_value().


def insert_after(sibling : Gtk::TreeIter?) : Gtk::TreeIter #

Inserts a new row after @sibling. If @sibling is nil, then the row will be prepended to the beginning of the list. @iter will be changed to point to this new row. The row will be empty after this function is called. To fill in values, you need to call gtk_list_store_set() or gtk_list_store_set_value().


def insert_before(sibling : Gtk::TreeIter?) : Gtk::TreeIter #

Inserts a new row before @sibling. If @sibling is nil, then the row will be appended to the end of the list. @iter will be changed to point to this new row. The row will be empty after this function is called. To fill in values, you need to call gtk_list_store_set() or gtk_list_store_set_value().


def insert_with_values(position : Int32, columns : Enumerable(Int32), values : Enumerable(_)) : Gtk::TreeIter #

Creates a new row at @position. @iter will be changed to point to this new row. If @position is -1, or larger than the number of rows in the list, then the new row will be appended to the list. The row will be filled with the values given to this function.

Calling gtk_list_store_insert_with_values (list_store, iter, position...) has the same effect as calling:

|[ static void insert_value (Gtk::ListStore *list_store, Gtk::TreeIter *iter, int position) { gtk_list_store_insert (list_store, iter, position); gtk_list_store_set (list_store, iter // ... ); } ]|

with the difference that the former will only emit Gtk::TreeModel::row-inserted once, while the latter will emit Gtk::TreeModel::row-inserted, Gtk::TreeModel::row-changed and, if the list store is sorted, Gtk::TreeModel::rows-reordered for every inserted value.

Since emitting the Gtk::TreeModel::rows-reordered signal repeatedly can affect the performance of the program, gtk_list_store_insert_with_values() should generally be preferred when inserting rows in a sorted list store.


def iter_is_valid(iter : Gtk::TreeIter) : Bool #

Checks if the given iter is a valid iter for this Gtk::ListStore.

This function is slow. Only use it for debugging and/or testing purposes.


def move_after(iter : Gtk::TreeIter, position : Gtk::TreeIter?) : Nil #

Moves @iter in @store to the position after @position. Note that this function only works with unsorted stores. If @position is nil, @iter will be moved to the start of the list.


def move_before(iter : Gtk::TreeIter, position : Gtk::TreeIter?) : Nil #

Moves @iter in @store to the position before @position. Note that this function only works with unsorted stores. If @position is nil, @iter will be moved to the end of the list.


def prepend : Gtk::TreeIter #

Prepends a new row to @list_store. @iter will be changed to point to this new row. The row will be empty after this function is called. To fill in values, you need to call gtk_list_store_set() or gtk_list_store_set_value().


def remove(iter : Gtk::TreeIter) : Bool #

Removes the given row from the list store. After being removed, @iter is set to be the next valid row, or invalidated if it pointed to the last row in @list_store.


def reorder(new_order : Enumerable(Int32)) : Nil #

Reorders @store to follow the order indicated by @new_order. Note that this function only works with unsorted stores.


def reorder(*new_order : Int32) #

def set(iter : Gtk::TreeIter, columns : Enumerable(Int32), values : Enumerable(_)) : Nil #

Sets the value of one or more cells in the row referenced by @iter. The variable argument list should contain integer column numbers, each column number followed by the value to be set. The list is terminated by a -1. For example, to set column 0 with type %G_TYPE_STRING to “Foo”, you would write gtk_list_store_set (store, iter, 0, "Foo", -1).

The value will be referenced by the store if it is a %G_TYPE_OBJECT, and it will be copied if it is a %G_TYPE_STRING or %G_TYPE_BOXED.


def set_value(iter : Gtk::TreeIter, column : Int32, value : _) : Nil #

Sets the data in the cell specified by @iter and @column. The type of @value must be convertible to the type of the column.


def swap(a : Gtk::TreeIter, b : Gtk::TreeIter) : Nil #

Swaps @a and @b in @store. Note that this function only works with unsorted stores.