Qt 4.6: Item View Convenience Classes

|  | Home · All Classes · Overviews |

[Previous: Delegate Classes] [Contents] [Next: Using Drag and Drop with Item Views]

# Item View Convenience Classes

- Overview
- List Widgets
- Tree Widgets
- Table Widgets
- Common Features

- Hidden Items
- Selections
- Searching

## Overview

Alongside the model/view classes, Qt 4 also includes standard widgets to provide classic item-based container widgets. These behave in a similar way to the item view classes in Qt 3, but have been rewritten to use the underlying model/view framework for performance and maintainability. The old item view classes are still available in the compatibility library (see the Porting Guide for more information).

The item-based widgets have been given names which reflect their uses: `QListWidget` provides a list of items, `QTreeWidget` displays a multi-level tree structure, and `QTableWidget` provides a table of cell items. Each class inherits the behavior of the `QAbstractItemView` class which implements common behavior for item selection and header management.

## List Widgets

Single level lists of items are typically displayed using a `QListWidget` and a number of `QListWidgetItem`s. A list widget is constructed in the same way as any other widget:

         QListWidget *listWidget = new QListWidget(this);

List items can be added directly to the list widget when they are constructed:

         new QListWidgetItem(tr("Sycamore"), listWidget);
         new QListWidgetItem(tr("Chestnut"), listWidget);
         new QListWidgetItem(tr("Mahogany"), listWidget);

They can also be constructed without a parent list widget and added to a list at some later time:

         QListWidgetItem *newItem = new QListWidgetItem;
         newItem->setText(itemText);
         listWidget->insertItem(row, newItem);

Each item in a list can display a text label and an icon. The colors and font used to render the text can be changed to provide a customized appearance for items. Tooltips, status tips, and "What's This?" help are all easily configured to ensure that the list is properly integrated into the application.

         newItem->setToolTip(toolTipText);
         newItem->setStatusTip(toolTipText);
         newItem->setWhatsThis(whatsThisText);

By default, items in a list are presented in the order of their creation. Lists of items can be sorted according to the criteria given in Qt::SortOrder to produce a list of items that is sorted in forward or reverse alphabetical order:

         listWidget->sortItems(Qt::AscendingOrder);
         listWidget->sortItems(Qt::DescendingOrder);

## Tree Widgets

Trees or hierarchical lists of items are provided by the `QTreeWidget` and `QTreeWidgetItem` classes. Each item in the tree widget can have child items of its own, and can display a number of columns of information. Tree widgets are created just like any other widget:

         QTreeWidget *treeWidget = new QTreeWidget(this);

Before items can be added to the tree widget, the number of columns must be set. For example, we could define two columns, and create a header to provide labels at the top of each column:

         treeWidget->setColumnCount(2);
         QStringList headers;
         headers << tr("Subject") << tr("Default");
         treeWidget->setHeaderLabels(headers);

The easiest way to set up the labels for each section is to supply a string list. For more sophisticated headers, you can construct a tree item, decorate it as you wish, and use that as the tree widget's header.

Top-level items in the tree widget are constructed with the tree widget as their parent widget. They can be inserted in an arbitrary order, or you can ensure that they are listed in a particular order by specifying the previous item when constructing each item:

         QTreeWidgetItem *cities = new QTreeWidgetItem(treeWidget);
         cities->setText(0, tr("Cities"));
         QTreeWidgetItem *osloItem = new QTreeWidgetItem(cities);
         osloItem->setText(0, tr("Oslo"));
         osloItem->setText(1, tr("Yes"));

         QTreeWidgetItem *planets = new QTreeWidgetItem(treeWidget, cities);

Tree widgets deal with top-level items slightly differently to other items from deeper within the tree. Items can be removed from the top level of the tree by calling the tree widget's takeTopLevelItem() function, but items from lower levels are removed by calling their parent item's takeChild() function. Items are inserted in the top level of the tree with the insertTopLevelItem() function. At lower levels in the tree, the parent item's insertChild() function is used.

It is easy to move items around between the top level and lower levels in the tree. We just need to check whether the items are top-level items or not, and this information is supplied by each item's `parent()` function. For example, we can remove the current item in the tree widget regardless of its location:

         QTreeWidgetItem *parent = currentItem->parent();
         int index;

         if (parent) {
             index = parent->indexOfChild(treeWidget->currentItem());
             delete parent->takeChild(index);
         } else {
             index = treeWidget->indexOfTopLevelItem(treeWidget->currentItem());
             delete treeWidget->takeTopLevelItem(index);
         }

Inserting the item somewhere else in the tree widget follows the same pattern:

         QTreeWidgetItem *parent = currentItem->parent();
         QTreeWidgetItem *newItem;
         if (parent)
             newItem = new QTreeWidgetItem(parent, treeWidget->currentItem());
         else
             newItem = new QTreeWidgetItem(treeWidget, treeWidget->currentItem());

## Table Widgets

Tables of items similar to those found in spreadsheet applications are constructed with the `QTableWidget` and `QTableWidgetItem`. These provide a scrolling table widget with headers and items to use within it.

Tables can be created with a set number of rows and columns, or these can be added to an unsized table as they are needed.

         QTableWidget *tableWidget;
         tableWidget = new QTableWidget(12, 3, this);

Items are constructed outside the table before being added to the table at the required location:

         QTableWidgetItem *newItem = new QTableWidgetItem(tr("%1").arg(
             pow(row, column+1)));
         tableWidget->setItem(row, column, newItem);

Horizontal and vertical headers can be added to the table by constructing items outside the table and using them as headers:

         QTableWidgetItem *valuesHeaderItem = new QTableWidgetItem(tr("Values"));
         tableWidget->setHorizontalHeaderItem(0, valuesHeaderItem);

Note that the rows and columns in the table begin at zero.

## Common Features

There are a number of item-based features common to each of the convenience classes that are available through the same interfaces in each class. We present these in the following sections with some examples for different widgets. Look at the list of Model/View Classes for each of the widgets for more details about the use of each function used.

### Hidden Items

It is sometimes useful to be able to hide items in an item view widget rather than remove them. Items for all of the above widgets can be hidden and later shown again. You can determine whether an item is hidden by calling the isItemHidden() function, and items can be hidden with `setItemHidden()`.

Since this operation is item-based, the same function is available for all three convenience classes.

### Selections

The way items are selected is controlled by the widget's selection mode (QAbstractItemView::SelectionMode). This property controls whether the user can select one or many items and, in many-item selections, whether the selection must be a continuous range of items. The selection mode works in the same way for all of the above widgets.

| Single item selections: Where the user needs to choose a single item from a widget, the default `SingleSelection` mode is most suitable. In this mode, the current item and the selected item are the same.
| Multi-item selections: In this mode, the user can toggle the selection state of any item in the widget without changing the existing selection, much like the way non-exclusive checkboxes can be toggled independently.

Extended selections: Widgets that often require many adjacent items to be selected, such as those found in spreadsheets, require the `ExtendedSelection` mode. In this mode, continuous ranges of items in the widget can be selected with both the mouse and the keyboard. Complex selections, involving many items that are not adjacent to other selected items in the widget, can also be created if modifier keys are used.

If the user selects an item without using a modifier key, the existing selection is cleared.

The selected items in a widget are read using the `selectedItems()` function, providing a list of relevant items that can be iterated over. For example, we can find the sum of all the numeric values within a list of selected items with the following code:

         QList<QTableWidgetItem *> selected = tableWidget->selectedItems();
         QTableWidgetItem *item;
         int number = 0;
         double total = 0;

         foreach (item, selected) {
             bool ok;
             double value = item->text().toDouble(&ok);

             if (ok && !item->text().isEmpty()) {
                 total += value;
                 number++;
             }
         }

Note that for the single selection mode, the current item will be in the selection. In the multi-selection and extended selection modes, the current item may not lie within the selection, depending on the way the user formed the selection.

### Searching

It is often useful to be able to find items within an item view widget, either as a developer or as a service to present to users. All three item view convenience classes provide a common `findItems()` function to make this as consistent and simple as possible.

Items are searched for by the text that they contain according to criteria specified by a selection of values from Qt::MatchFlags. We can obtain a list of matching items with the `findItems()` function:

         QTreeWidgetItem *item;
         QList<QTreeWidgetItem *> found = treeWidget->findItems(
             itemText, Qt::MatchWildcard);

         foreach (item, found) {
             treeWidget->setItemSelected(item, true);
             // Show the item->text(0) for each item.
         }

The above code causes items in a tree widget to be selected if they contain the text given in the search string. This pattern can also be used in the list and table widgets.

[Previous: Delegate Classes] [Contents] [Next: Using Drag and Drop with Item Views]