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.
Un TreView non é son un widget simple, senón que contén uns máis pequenos:
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.
Primeiro creamos un ListStore como faríamos con calquera widget. Logo chamamos ao seu método set_column_types, e pasámoslle un array dos tipos de datos GObject. (Podemos poñerlle todos os tipos nunha liña, pero teremos que partila para facela máis doado de ler.)
Os tipos de datos GObject que pode usar son:
Neste caso, crearemos unha ListStore para catro columnas, cada unha delas contén valores en cadeas.
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.
#!/usr/bin/gjs
imports.gi.versions.Gtk = '3.0';
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
class TreeViewExample {
// Create the application itself
constructor() {
this.application = new Gtk.Application({
application_id: 'org.example.jstreeviewsimpleliststore'
});
// Connect 'activate' and 'startup' signals to the callback functions
this.application.connect('activate', this._onActivate.bind(this));
this.application.connect('startup', this._onStartup.bind(this));
}
// Callback function for 'activate' signal presents window when active
_onActivate() {
this._window.present();
}
// Callback function for 'startup' signal builds the UI
_onStartup() {
this._buildUI();
}
// Build the application's UI
_buildUI() {
// Create the application window
this._window = new Gtk.ApplicationWindow({
application: this.application,
window_position: Gtk.WindowPosition.CENTER,
default_height: 250,
default_width: 100,
border_width: 20,
title: "My Phone Book"});
// Create the underlying liststore for the phonebook
this._listStore = new Gtk.ListStore ();
this._listStore.set_column_types ([
GObject.TYPE_STRING,
GObject.TYPE_STRING,
GObject.TYPE_STRING,
GObject.TYPE_STRING]);
// Data to go in the phonebook
let phonebook =
[{ name: "Jurg", surname: "Billeter", phone: "555-0123",
description: "A friendly person."},
{ name: "Johannes", surname: "Schmid", phone: "555-1234",
description: "Easy phone number to remember."},
{ name: "Julita", surname: "Inca", phone: "555-2345",
description: "Another friendly person."},
{ name: "Javier", surname: "Jardon", phone: "555-3456",
description: "Bring fish for his penguins."},
{ name: "Jason", surname: "Clinton", phone: "555-4567",
description: "His cake's not a lie."},
{ name: "Random J.", surname: "Hacker", phone: "555-5678",
description: "Very random!"}];
// Put the data in the phonebook
for (let i = 0; i < phonebook.length; i++ ) {
let contact = phonebook [i];
this._listStore.set (this._listStore.append(), [0, 1, 2, 3],
[contact.name, contact.surname, contact.phone, contact.description]);
}
// Create the treeview
this._treeView = new Gtk.TreeView ({
expand: true,
model: this._listStore });
// Create the columns for the address book
let firstName = new Gtk.TreeViewColumn ({ title: "First Name" });
let lastName = new Gtk.TreeViewColumn ({ title: "Last Name" });
let phone = new Gtk.TreeViewColumn ({ title: "Phone Number" });
// Create a cell renderer for when bold text is needed
let bold = new Gtk.CellRendererText ({
weight: Pango.Weight.BOLD });
// Create a cell renderer for normal text
let normal = new Gtk.CellRendererText ();
// Pack the cell renderers into the columns
firstName.pack_start (bold, true);
lastName.pack_start (normal, true);
phone.pack_start (normal, true);
// Set each column to pull text from the TreeView's model
firstName.add_attribute (bold, "text", 0);
lastName.add_attribute (normal, "text", 1);
phone.add_attribute (normal, "text", 2);
// Insert the columns into the treeview
this._treeView.insert_column (firstName, 0);
this._treeView.insert_column (lastName, 1);
this._treeView.insert_column (phone, 2);
// Create the label that shows details for the name you select
this._label = new Gtk.Label ({ label: "" });
// Get which item is selected
this.selection = this._treeView.get_selection();
// When something new is selected, call _on_changed
this.selection.connect ('changed', this._onSelectionChanged.bind(this));
// Create a grid to organize everything in
this._grid = new Gtk.Grid;
// Attach the treeview and label to the grid
this._grid.attach (this._treeView, 0, 0, 1, 1);
this._grid.attach (this._label, 0, 1, 1, 1);
// Add the grid to the window
this._window.add (this._grid);
// Show the window and all child widgets
this._window.show_all();
}
_onSelectionChanged() {
// Grab a treeiter pointing to the current selection
let [ isSelected, model, iter ] = this.selection.get_selected();
// Set the label to read off the values stored in the current selection
this._label.set_label ("\n" +
this._listStore.get_value (iter, 0) + " " +
this._listStore.get_value (iter, 1) + " " +
this._listStore.get_value (iter, 2) + "\n" +
this._listStore.get_value (iter, 3)
);
}
};
// Run the application
let app = new TreeViewExample ();
app.application.run (ARGV);
Neste exemplo empregaremos o seguinte:
Gtk.Application
Gtk.ApplicationWindow
Gtk.CellRendererText
Gtk.ListStore
Gtk.TreeIter
Gtk.TreeSelection
Gtk.TreeView
Gtk.TreeViewColumn