practical model view programming (roadshow version)

71
PRACTICAL MODEL VIEW PROGRAMMING CODE LESS. VIEW MORE.

Upload: marius-bugge-monsen

Post on 19-May-2015

3.825 views

Category:

Documents


3 download

DESCRIPTION

An overview of the Qt Model View architecture and practical examples of how to use this architecture for presenting large data sets in your application user interface.

TRANSCRIPT

Page 1: Practical Model View Programming (Roadshow Version)

PRACTICAL MODEL VIEWPROGRAMMING

CODE LESS. VIEW MORE.

Page 2: Practical Model View Programming (Roadshow Version)

Marius Bugge Monsen,MSc (NTNU),Software Developer

Page 3: Practical Model View Programming (Roadshow Version)

Contents

● An Overview of the Qt Model View Architecture● An Introduction to the Item Model Interface● Customized Item Filtering● Customized Item Painting● More Models and Hierarchies

Page 4: Practical Model View Programming (Roadshow Version)
Page 5: Practical Model View Programming (Roadshow Version)

The Model View Architecture

Page 6: Practical Model View Programming (Roadshow Version)

Model

View

Change Notifications

Item Selections

User Input

Item Delegate

Data Changes

User Input

Item Selection State

Page 7: Practical Model View Programming (Roadshow Version)

Item Selections

Model

View View

Page 8: Practical Model View Programming (Roadshow Version)

Tree WidgetTable Widget List Widget

Item Based Views

Page 9: Practical Model View Programming (Roadshow Version)

Item Based View

View

Page 10: Practical Model View Programming (Roadshow Version)
Page 11: Practical Model View Programming (Roadshow Version)

● Eff ic iency

● Flexib i l i t y

● M a in ta inab i l i t y

What do you get ?

Page 12: Practical Model View Programming (Roadshow Version)

The Model Interface

Page 13: Practical Model View Programming (Roadshow Version)

400 000 000 000 000 cells

Page 14: Practical Model View Programming (Roadshow Version)

InterfaceModel

Data Structure

View

Page 15: Practical Model View Programming (Roadshow Version)

0

0

1

2

0

1

2

0 1 2

Page 16: Practical Model View Programming (Roadshow Version)

#include <QtGui>

int main(int argc, char *argv[]){ QApplication app(argc, argv);

int rows = 4; int columns = 1; QStandardItemModel model(rows, columns); for (int r = 0; r < model.rowCount(); ++r) { QModelIndex index = model.index(r, 0); model.setData(index, "hello"); }

QTableView view; view.setModel(&model);

view.show(); return app.exec();}

Page 17: Practical Model View Programming (Roadshow Version)

InterfaceModel View

hellohellohello

hello

?Data Structure

Page 18: Practical Model View Programming (Roadshow Version)
Page 19: Practical Model View Programming (Roadshow Version)
Page 20: Practical Model View Programming (Roadshow Version)
Page 21: Practical Model View Programming (Roadshow Version)

// we start with a 4x1 table QStandardItemModel model(4, 1); for (int r = 0; r < model.rowCount(); ++r) { QModelIndex index = model.index(r, 0); model.setData(index, "hello"); // let's add a 1x1 sub-table QModelIndex parent = index model.insertRow(0, parent); model.insertColumn(0, parent); // then we can set the data in cell [0,0] QModelIndex child = mode.index(0, 0, parent); model.setData(child, “world”); }

Page 22: Practical Model View Programming (Roadshow Version)

InterfaceModel

Data Structure

View

hellohellohello

worldhelloworld

world

world

?

Page 23: Practical Model View Programming (Roadshow Version)

Model Interface

Custom API

Data Structure

Model

Page 24: Practical Model View Programming (Roadshow Version)

#include <QtGui>

int main(int argc, char *argv[]){ QApplication app(argc, argv); QTreeWidget widget;

for (int i = 0; i < 4; ++i) { QTreeWidgetItem *parent = new QTreeWidgetItem(&widget, QStringList("hello")); new QTreeWidgetItem(parent, QStringList("world")); }

widget.show(); app.exec();}

Page 25: Practical Model View Programming (Roadshow Version)

Model Index

● Row● Column● Internal Identifier

Page 26: Practical Model View Programming (Roadshow Version)

Qt4 Logo

Model Index

Page 27: Practical Model View Programming (Roadshow Version)

Decoration Role

Display Role

Qt4 Logo

Type: Im age Fi le

Size: 1 0.5 kB

ToolTip Role

Page 28: Practical Model View Programming (Roadshow Version)

QIcon icon(“images/qt4-logo.png”);QStandardItemModel model(4, 1); for (int r = 0; r < model.rowCount(); ++r) { QModelIndex index = model.index(r, 0); model.setData(index, "hello", Qt::DisplayRole); model.setData(index, icon, Qt::DecorationRole);}

Page 29: Practical Model View Programming (Roadshow Version)

QIcon icon(“images/qt4-logo.png”);QTableWidget table(4, 1);

for (int i = 0; i < 4; ++i) table.setItem(i, 0, new QTableWidgetItem(icon, “hello”));

Page 30: Practical Model View Programming (Roadshow Version)

● A Generic In terfa ce to Da ta St ruc tu res

● M odels Are In terchangeab le

● Views Are In terchangeab le

● M odels and Selec t ions Are Sha rab le

The Model Interface

Page 31: Practical Model View Programming (Roadshow Version)

Customized Item Filtering

Page 32: Practical Model View Programming (Roadshow Version)

Model

Page 33: Practical Model View Programming (Roadshow Version)

Model Proxy View

Page 34: Practical Model View Programming (Roadshow Version)

Model Sorting View

Page 35: Practical Model View Programming (Roadshow Version)

Model Filtering View

Page 36: Practical Model View Programming (Roadshow Version)

class CodeModel : public QStringListModel{public: CodeModel(const QString &fileName, QObject *parent = 0) : QStringListModel(parent) { QFile source(name); source.open(QIODevice::ReadOnly); QStringList strings = QString().split("\n", QString::SkipEmptyParts); setStringList(strings); } };

Page 37: Practical Model View Programming (Roadshow Version)

CodeModel model(sourceFile);

QSortFilterProxyModel proxy;proxy.setSourceModel(&model);

QTreeView view;view.setModel(&proxy);

QObject::connect(lineEdit, SIGNAL(textChanged(const QString&)), &proxy, SLOT(setFilterRegExp(const QString&)));

Page 38: Practical Model View Programming (Roadshow Version)

class ListModel : public QAbstractListModel{

Q_OBJECTpublic:

ListModel(QObject *parent = 0);~ListModel();

int rowCount(const QModelIndex &parent) const;QVariant data(const QModelIndex &index, int role) const;

};

Page 39: Practical Model View Programming (Roadshow Version)

ListModel::ListModel(QObject *parent): QAbstractListModel(parent) {}

ListModel::~ListModel() {}

int ListModel::rowCount(const QModelIndex &) const{

return 10000;}

Page 40: Practical Model View Programming (Roadshow Version)

QVariant ListModel::data(const QModelIndex &index, int role) const{

if (role == Qt::DisplayRole)return index.row();

if (role == Qt::DecorationRole)return QColor((index.row() << 4) & 0xFF,

(index.row() << 2) & 0xFF, (index.row() & 0xFF));

return QVariant();}

Page 41: Practical Model View Programming (Roadshow Version)
Page 42: Practical Model View Programming (Roadshow Version)

class ColorFilter : public QSortFilterProxyModel{ Q_OBJECTpublic: ColorFilter(QObject *parent = 0);

bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;public slots: void setRedFilter(int value); void setGreenFilter(int value); void setBlueFilter(int value);

private: int red, green, blue;};

Page 43: Practical Model View Programming (Roadshow Version)

bool ColorFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const{ QModelIndex sourceIndex = sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent); QVariant variant = sourceIndex.data(Qt::DecorationRole); if (variant.type() == QVariant::Color) { QColor c = variant.value<QColor>(); return (c.red() > red) && (c.green() > green) && (c.blue() > blue); } return true;}

Page 44: Practical Model View Programming (Roadshow Version)

...ListModel model;ColorFilter filter;filter.setSourceModel(&model);...QSlider *redSlider = new QSlider(Qt::Horizontal);redSlider->setRange(0, 255);QObject::connect(redSlider, SIGNAL(valueChanged(int)), &filter, SLOT(setRedFilter(int)));...QListView *view = new QListView;view->setModel(&filter);view->setItemDelegate(new ColorDelegate(view));...

Page 45: Practical Model View Programming (Roadshow Version)
Page 46: Practical Model View Programming (Roadshow Version)

Customized Item Painting

Page 47: Practical Model View Programming (Roadshow Version)

Model

View

Item Selections

Item Delegate

Page 48: Practical Model View Programming (Roadshow Version)

Qt4 Logo

Qt4 Logo Im age Fi le 1 0.5 kB

Qt4 Logo

Page 49: Practical Model View Programming (Roadshow Version)
Page 50: Practical Model View Programming (Roadshow Version)

class HoverDelegate : public QItemDelegate{ Q_OBJECTpublic: HoverDelegate(QObject *parent = 0) : QItemDelegate(parent) {} void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (option.state & QStyle::State_MouseOver) painter->fillRect(option.rect, Qt::lightGray); QItemDelegate::paint(painter, option, index); }};...view.viewport()->setAttribute(Qt::WA_Hover);...

Page 51: Practical Model View Programming (Roadshow Version)

Movie Title

Page 52: Practical Model View Programming (Roadshow Version)

<?xml version="1.0" standalone="no"?><svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" baseProfile="tiny" version="1.2"> <title>Play</title> <defs> <linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="0" y2="100"> <stop offset="0%" stop-color="#ddddff" /> <stop offset="50%" stop-color="#000000"/> </linearGradient> </defs> <rect x="20" y="0" width="93" height="130" rx="5" fill="none" stroke="#ffffff" stroke-width="3" /> <circle cx="50" cy="50" r="50" fill="url(#gradient)" stroke="#000000" stroke-width="2"/> <path d="M 30 75 L 30 25 L 80 50 z" fill="#dddddd" stroke="#000000" stroke-width="2" /></svg>

Page 53: Practical Model View Programming (Roadshow Version)

class DemoDelegate : public QItemDelegate{public: DemoDelegate(QObject *parent = 0);

void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

protected: void drawSvg(QPainter *painter, const QRect &rect) const;

private: mutable QSvgRenderer renderer;};

Page 54: Practical Model View Programming (Roadshow Version)

void DemoDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{ // draw the item as unselected and without focus rect QStyleOptionViewItem opt = option; opt.state &= ~QStyle::State_Selected; opt.state &= ~QStyle::State_HasFocus; QItemDelegate::paint(painter, opt, index); // draw svg over the current item if (option.state & QStyle::State_HasFocus) drawSvg(painter, option.rect);}

Page 55: Practical Model View Programming (Roadshow Version)
Page 56: Practical Model View Programming (Roadshow Version)

More Models and Hierarchies

Page 57: Practical Model View Programming (Roadshow Version)

struct SimpleNode{ SimpleNode(SimpleNode *parent) : parentNode(parent) { if (parentNode) parentNode->children.append(this); }

~SimpleNode() { foreach(SimpleNode *child, children) delete child; } QVariant data() const { return "node data"; }

SimpleNode *parentNode; QList<SimpleNode*> children;};

Page 58: Practical Model View Programming (Roadshow Version)

InterfaceModel

Data Structure

View

Page 59: Practical Model View Programming (Roadshow Version)
Page 60: Practical Model View Programming (Roadshow Version)

class SimpleModel : public QAbstractItemModel{public: SimpleModel(QObject *parent = 0); ~SimpleModel();

QModelIndex index(int row, int column, const QModelIndex &parent) const; QModelIndex parent(const QModelIndex &child) const; int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const;

protected: QModelIndex indexForNode(SimpleNode *node) const; SimpleNode *nodeForIndex(const QModelIndex &index) const; int rowForNode(SimpleNode *node) const;

private: SimpleNode *root;};

Page 61: Practical Model View Programming (Roadshow Version)

int SimpleModel::rowCount(const QModelIndex &parent) const{ SimpleNode *parentNode = nodeForIndex(parent); return parentNode->children.count();}

int SimpleModel::columnCount(const QModelIndex &parent) const{ Q_UNUSED(parent); return 1;}

Page 62: Practical Model View Programming (Roadshow Version)

SimpleModel::SimpleModel(QObject *parent) : QAbstractItemModel(parent){ // Initialize the data structure root = new SimpleNode(0); for (int i = 0; i < 10; ++i) { SimpleNode *topLevel = new SimpleNode(root); for (int j = 0; j < 5; ++j) { SimpleNode *secondLevel = new SimpleNode(topLevel); for (int k = 0; k < 3; ++k) { (void) new SimpleNode(secondLevel); } } }}

SimpleModel::~SimpleModel(){ delete root;}

Page 63: Practical Model View Programming (Roadshow Version)

QVariant SimpleModel::data(const QModelIndex &index, int role) const{ if (index.isValid() && role == Qt::DisplayRole) { SimpleNode *node = nodeForIndex(index); return node->data(); } return QVariant();}

Page 64: Practical Model View Programming (Roadshow Version)

Qt4 Logo

Model Index

Page 65: Practical Model View Programming (Roadshow Version)

QModelIndex SimpleModel::index(int row, int column, const QModelIndex &parent) const{ if (hasIndex(row, column, parent)) { SimpleNode *parentNode = nodeForIndex(parent); SimpleNode *childNode = parentNode->children.at(row); return indexForNode(childNode); } return QModelIndex();}

Page 66: Practical Model View Programming (Roadshow Version)

QModelIndex SimpleModel::parent(const QModelIndex &child) const{ SimpleNode *childNode = nodeForIndex(child); SimpleNode *parentNode = childNode->parentNode; if (parentNode == root) return QModelIndex(); return indexForNode(parentNode);}

Page 67: Practical Model View Programming (Roadshow Version)

QModelIndex SimpleModel::indexForNode(SimpleNode *node) const{ if (node == root) return QModelIndex(); int row = rowForNode(node); int column = 0; return createIndex(row, column, node);}

Page 68: Practical Model View Programming (Roadshow Version)

SimpleNode *SimpleModel::nodeForIndex(const QModelIndex &index) const{ if (index.isValid()) return static_cast<SimpleNode*>(index.internalPointer()); return root;}

int SimpleModel::rowForNode(SimpleNode *node) const{ return node->parentNode->children.indexOf(node);}

Page 69: Practical Model View Programming (Roadshow Version)

int main(int argc, char *argv[]){ QApplication app(argc, argv); SimpleModel model;

QTreeView view; view.setModel(&model); view.show();

return app.exec();}

Page 70: Practical Model View Programming (Roadshow Version)

What we have covered

● The Qt Model View Architecture● The Item Model Interface● Customized Item Filtering● Customized Item Painting● Hierarchical Models

Page 71: Practical Model View Programming (Roadshow Version)

More Information

http://doc.trolltech.com/4.1/model-view-programming.htmlhttp://doc.trolltech.com/4.1/model-view.html