A TreeView is like a window onto the contents of either a ListStore or a TreeStore. A ListStore is like a spreadsheet: a "flat", two-dimensional list of things broken up into rows and columns. A TreeStore, meanwhile, can branch out in different directions like a tree can. In this example, we create a TreeView that shows the contents of a ListStore with (fictitious) names and phone numbers in it, and set it so that the Label at the bottom of the window shows more information about whichever name you click on.
The TreeView is not just a single widget, but contains a number of smaller ones:
TreeViewColumn widgets show each (vertical) column of information from the ListStore. Each one has a title which can be shown at the top of the column, like in the screenshot.
CellRenderer widgets are "packed" into each TreeViewColumn, and contain the instructions for how to display each individual "cell", or item from the ListStore. There are multiple different types, including the CellRendererText used here and the CellRendererPixbuf, which displays a picture ("pixel buffer").
Finally, we're going to use an object called a TreeIter, which isn't a widget so much as an invisible cursor which points to a (horizontal) row in the ListStore. Whenever you click on a name in the phonebook, for instance, we create a TreeIter pointing to the row that's selected, and then use that to tell the ListStore which entry we want the Label to show more information about.
The TreeView is probably the most complicated Gtk widget, because of how many parts it has and how they all have to work together. Give yourself time to learn how it works and experiment with it, or try something easier first if you're having trouble.
These are the libraries we need to import for this application to run. Remember that the line which tells GNOME that we're using Gjs always needs to go at the start.
All the code for this sample goes in the TreeViewExample class. The above code creates a Gtk.Application for our widgets and window to go in.
The _buildUI function is where we put all the code to create the application's user interface. The first step is creating a new Gtk.ApplicationWindow to put all our widgets into.
We first create the ListStore like we would any widget. Then we call its set_column_types method, and pass it an array of GObject data types. (We could have put the types all on one line, but here we are breaking them up to make it easier to read.)
The GObject data types you can use include:
In this case, we're making a ListStore of four columns, each one containing string values.
You need to put the line
Here we have the information to go in the ListStore. It's an array of objects, each one corresponding to a single entry in our phone book.
Note that the TreeView in the screenshot doesn't actually show the data from the "description" properties. Instead, that information's shown in the Label beneath it, for whichever row that you click on. That's because the TreeView and ListStore are two separate things, and a TreeView can show all or part of a ListStore, and display what's in it in different ways. You can even have multiple widgets show things from the same ListStore, like the Label in our example or even a second TreeView.
This
A ListStore's
Here we create a basic TreeView widget, that expands both horizontally and vertically to use as much space as needed. We set it to use the ListStore we created as its "model", or the thing it'll show us stuff from.
Now we create each of the vertical TreeViewColumns we'll see in the TreeView. The title for each one goes at the top, as you can see in the screenshot.
Here we create the CellRenderers that we'll use to display the text from our ListStore, and pack them into the TreeViewColumns. Each CellRendererText is used for all the entries in that column. Our normal CellRendererText just creates plain text, while our bold one uses heavier-weight text. We put it into the first name column, and tell the other two to use copies of the normal one. The "true" used as the second parameter for the
Here is a list of other text properties you can use. In order to use these Pango constants, make sure to put the line
Now that we've put the CellRenderers into the TreeViewColumns, we use the
The first parameter is which CellRenderer we're going to use to render what we're pulling in.
The second parameter is what kind of information we're going to pull in. In this case, we're letting it know that we're rendering text.
The third parameter is which of the ListStore's columns we're pulling that information in from.
After we've set that up, we use the TreeView's
Normally, you might want to use a loop to initialize your TreeView, but in this example we're spelling things out step by step for the sake of making it easier to understand.
The TreeView's
After we get the TreeSelection that goes with our TreeView, we ask it to tell us when it changes which row it's pointing to. We do this by connecting its
After we've gotten that out of the way, we create a Grid to put everything in, then add it to our window and tell the window to show itself and its contents.
The line of code with the let statement is a little convoluted, but it's nonetheless the best way to get a TreeIter pointing to the same row as our TreeSelection. It has to create a couple of other object references, but
After we've done that, we call the Label's
Here, we want to get data from all four columns, including the "hidden" one that's not part of the TreeView. This way, we can use our Label to show strings that are too large to fit in the TreeView, and that we don't need to see at a glance.
Finally, we create a new instance of the finished TreeViewExample class, and set the application running.
In this sample we used the following:
Gtk.Application
Gtk.ApplicationWindow
Gtk.CellRendererText
Gtk.ListStore
Gtk.TreeIter
Gtk.TreeSelection
Gtk.TreeView
Gtk.TreeViewColumn