Qt Essentials - Model View Module
Qt Essentials - Training Course
Produced by Nokia, Qt Development Frameworks
Material based on Qt 4.7, created on December 15, 2010
http://qt.nokia.com
1/35
Module: Model/View
Model/View Concept Showing Simple Data Proxy Models Custom Models
Model/View
2/35
Overview
Using Model/View
Introducing to the concepts of model-view Showing Data using standard item models Understand the limitations of standard item models How to interface your model with a data backend Understand what are proxy models and hot to use them
Custom Models
Writing a simple read-only custom model.
Model/View
3/35
Module: Model/View
Model/View Concept Showing Simple Data Proxy Models Custom Models
Model/View
Model/View Concept
4/35
Why Model/View?
Isolated domain-logic From input and presentation Makes Components Independent For Development For Testing For Maintenance Foster Component Reuse Reuse of Presentation Logic Reuse of Domain Model
Model/View
Model/View Concept
5/35
Model/View-Components
Model View Components View
Displays data structure Delegate Renders single data Supports editing data Model Unied adapter to data
Delegate View
Rendering Rendering
Model
Editing
Model View Infrastructure Item
Imaginary unit of data in model Index Used to locate item in model Lets see how simple it can be
Demo modelview/ex-simple
Data
Model/View
Model/View Concept
6/35
Model Structures
List - One-Dimensional Rows Table - Two-Dimensional Rows Columns Tree - Three-Dimensional Rows Columns Parent/Child
Model/View
Model/View Concept
7/35
Display the Structure - View Classes
QAbstractItemView Abstract base class for all views QListView List or icon view QTreeView Items of data in hierarchical list QTableView Item based row/column view
QAbstractItemView QListView QTableView QTreeView
Other Views
QHeaderView - Header for item views QColumnView - A cascading list
See View Classes Documentation Model/View Model/View Concept 8/35
Adapts the Data - Model Classes
QAbstractItemModel Abstract interface of models Abstract Item Models Implement to use Ready-Made Models Convenient to use Proxy Models Reorder/lter/sort your items
See Model Classes Documentation
QAbstractItemModel QAbstractListModel QStringListModel QAbstractTableModel QAbstractProxyModel QSortFilterProxyModel QFileSystemModel QStandardItemModel
Model/View
Model/View Concept
9/35
Data - Model - View Relationships
Item Widgets
All combined Model is your data
View Model Data
Standard Item Model Data+Model combined View is separated Model is your data Custom Item Models Model is adapter to data View is separated
Model Data
View
Data
Model
View
Model/View
Model/View Concept
10/35
Adressing Data - QModelIndex
Refers to item in model Contains all information to specify location Located in given row and column May have a parent index QModelIndex API row() - row index refers to column() - column index refers to parent() - parent of index
or QModelIndex() if no parent isValid() Valid index belongs to a model Valid index has non-negative row and column numbers model() - the model index refers to data( role ) - data for given role
Model/View
Model/View Concept
11/35
QModelIndex in Table/Tree Structures
Rows and columns Item location in table model Item has no parent (parent.isValid() == false)
indexA = model->index(0, 0, QModelIndex()); indexB = model->index(1, 1, QModelIndex()); indexC = model->index(2, 1, QModelIndex());
Parents, rows, and columns Item location in tree model
indexA = model->index(0, indexC = model->index(2, // asking for index with indexB = model->index(1,
See Model Indexes Documentation
0, QModelIndex()); 1, QModelIndex()); given row, column and parent 0, indexA);
Model/View
Model/View Concept
12/35
Item and Item Roles
Item performs various roles for other components (delegate, view, ...) Supplies different data for different situations Example: Qt::DisplayRole used displayed string in view Asking for data
QVariant value = model->data(index, role); // Asking for display text QString text = model->data(index, Qt::DisplayRole).toString()
Standard roles Dened by Qt::ItemDataRole
See enum Qt::ItemDataRole Documentation
Model/View
Model/View Concept
13/35
Recap of Model/View Concept
Model Structures List, Table and Tree Components Model - Adapter to Data View - Displays Structure Delegate - Paints Item Index - Location in Model Views
QListView QTableView QTreeView
Models
QAbstractItemModel
Other Abstract Models Ready-Made Models Proxy Models
Index
row(),column(),parent() data( role ) model()
Item Role
Qt::DisplayRole Standard Roles in Qt::ItemDataRoles
Model/View
Model/View Concept
14/35
Things you may want to customize
Models - QAbstractItemModel If model is your data
QStandardItemModel or Item Widgets
Otherwise Adapt own data by subclassing a model
Delegate - QAbstractItemDelegate
Standard Delegate sufcient Custom Delgate To control display/edit of data
Views - QAbstractItemView
Almost always be used as-is Exceptional to add new view
Model/View
Model/View Concept
15/35
Module: Model/View
Model/View Concept Showing Simple Data Proxy Models Custom Models
Model/View
Showing Simple Data
16/35
QStandardItemModel - Convenient Model
QStandardItemModel Classic item-based approach Only practical for small sets of data
model = new QStandardItemModel(parent); item = new QStandardItem("A (0,0)"); model->appendRow(item); model->setItem(0, 1, new QStandardItem("B (0,1)")); item->appendRow(new QStandardItem("C (0,0)"));
"C (0,0)" - Not visible. (table view is only 2-dimensional) React on click
connect(m_view, SIGNAL(clicked(QModelIndex)) ...
In slot ...
QStandardItem *item = model->itemFromIndex(index);
See QStandardItemModel Documentation
Model/View
Showing Simple Data
17/35
Sharing Models and Selection
// create a model model = ... // with some items // and several views list = ...; table = ...; tree = ...; // You can share model with views list->setModel(model); table->setModel(model); tree->setModel(model); // Even can share selection list->setSelectionModel(tree->selectionModel()); table->setSelectionModel(tree->selectionModel());
Model/View
Showing Simple Data
18/35
Finishing Touch
Customizing view headers
// set horizontal headers model->setHorizontalHeaderItem(0, new QStandardItem("Column 1"); model->setHorizontalHeaderItem(1, new QStandardItem("Column 2"); // hide vertical headers on table table->verticalHeader().hide();
Customizing Items
item->setEditable(false); // disable edit item->setCheckable(true); // checkbox on item
Customize selection
// allow only to select single rows on table table->setSelectionBehavior(QAbstractItemView::SelectRows); table->setSelectionMode(QAbstractItemView::SingleSelection);
Demo modelview/ex-showdata
Model/View
Showing Simple Data
19/35
Selections - QItemSelectionModel
Keeps track of selected items in view Not a QAbstractItemModel, just QObject QItemSelectionModel API
currentIndex() signal currentChanged(current, previous) QItemSelection selection() List of selection ranges select( ... ) signal selectionChanged(selected, deselected)
// selecting a range selection = new QItemSelection(topLeft, bottomRight); view->selectionModel()->select(selection);
Model/View
Showing Simple Data
20/35
Meet the City Engine
Our Demo Model 62 most populous cities of the world Data in CSV le Data Columns City | Country | Population | Area | Flag Implemented as data backend Internal implementation is hidden Code in CityEngine class
Model/View
Showing Simple Data
21/35
Our Backend CityEngine API
public CityEngine : public QObject { // returns all city names QStringList cities() const; // returns country by given city name QString country(const QString &cityName) const; // returns population by given city name int population(const QString &cityName) const; // returns city area by given city name qreal area(const QString &cityName) const; // returns country flag by given country name QIcon flag(const QString &countryName) const; // returns all countries QStringList countries() const; // returns city names filtered by country QStringList citiesByCountry(const QString& countryName) const; };
Demo /modelview/ex-standarditemmodel
Model/View
Showing Simple Data
22/35
Lab: Tree Model for CityEngine
Implement createTreeModel() in mainwindow.cpp Display cities grouped by countries Optional Provide a nd for country eld. Found countries shall be selected
Lab modelview/lab-treecityengine
Model/View
Showing Simple Data
23/35
Module: Model/View
Model/View Concept Showing Simple Data Proxy Models Custom Models
Model/View
Proxy Models
24/35
Proxy Model - QSortFilterProxyModel
QSortFilterProxyModel Transforms structure of source model Maps indexes to new indexes
view = new QListView(parent); // insert proxy model between model and view proxy = new QSortFilterProxyModel(parent); proxy->setSourceModel(model); view->setModel(proxy);
Note: Need to load all data to sort or lter
Model/View
Proxy Models
25/35
Sorting/Filtering - QSortFilterProxyModel
Filter with Proxy Model
// filter column 1 by "India" proxy->setFilterWildcard("India"); proxy->setFilterKeyColumn(1);
Sorting with Proxy Model
// sort column 0 ascending view->setSortingEnabled(true); proxy->sort(0, Qt::AscendingOrder);
Filter via QLineEdit signal
connect(m_edit, SIGNAL(textChanged(QString)), proxy, SLOT(setFilterWildcard(QString)));
Demo modelview/ex-sortltertableview
Model/View
Proxy Models
26/35
Module: Model/View
Model/View Concept Showing Simple Data Proxy Models Custom Models
Model/View
Custom Models
27/35
Implementing a Model
Variety of classes to choose from QAbstractListModel
One dimensional list QAbstractTableModel Two-dimensional tables QAbstractItemModel Generic model class QStringListModel One-dimensional model Works on string list QStandardItemModel Model that stores the data
Notice: Need to subclass abstract models
Model/View
Custom Models
28/35
Step 1: Read Only List Model
class MyModel: public QAbstractListModel { public: // return row count for given parent int rowCount( const QModelIndex &parent) const; // return data, based on current index and requested role QVariant data( const QModelIndex &index, int role = Qt::DisplayRole) const; };
Demo modelview/ex-stringlistmodel
Model/View
Custom Models
29/35
Step 2: Suppling Header Information
QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const { // return column or row header based on orientation }
Demo modelview/ex-stringlistmodel-2
Model/View
Custom Models
30/35
Step 3: Enabling Editing
// should contain Qt::ItemIsEditable Qt::ItemFlags MyModel::flags(const QModelIndex &index) const { return QAbstractListModel::flags() | Qt::ItemIsEditable; } // set role data for item at index to value bool MyModel::setData( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) { ... = value; // set data to your backend emit dataChanged(topLeft, bottomRight); // if successful }
Demo modelview/ex-stringlistmodel-3
Model/View
Custom Models
31/35
Step 4: Row Manipulation
// insert count rows into model before row bool MyModel::insertRows(int row, int count, parent) { beginInsertRows(parent, first, last); // insert data into your backend endInsertRows(); } // removes count rows from parent starting with row bool MyModel::removeRows(int row, int count, parent) { beginRemoveRows(parent, first, last); // remove data from your backend endRemoveRows(); }
Demo modelview/ex-stringlistmodel-4
Model/View
Custom Models
32/35
A Table Model
2-dimensional model (rows x columns) int columnCount(parent) Enabling columns
int MyModel::columnCount ( parent ) const { // return number of columns for parent } QVariant MyModel::data( index, role ) const { // adapt to react on requested column from index }
Demo modelview/ex-tablemodel
Model/View
Custom Models
33/35
Lab: City Table Model
Please implement a City Table Model Given: The data in CityEngine A main test function Your Task: Adapt the data to a table model Optional Make the model editable Enable adding/removing cities
Lab modelview/lab-citymodel
Model/View
Custom Models
34/35
c 2010 Nokia Corporation and its Subsidiary(-ies).
The enclosed Qt Training Materials are provided under the Creative Commons Attribution ShareAlike 2.5 License Agreement.
The full license text is available here:
http://creativecommons.org/licenses/by-sa/2.5/legalcode
Nokia, Qt and the Nokia and Qt logos are the registered trademarks of Nokia Corporation in Finland and other countries worldwide.
Model/View
Legal
35/35