PRACTICAL MODEL VIEW
PROGRAMMING



CODE LESS. VIEW MORE.
Marius Bugge Monsen,
MSc (NTNU),
Software Developer
Contents

●   An Overview of the Qt Model View Architecture
●   An Introduction to the Item Model Interface
●   Customized...
The Model View Architecture
Item Selections



          User Input                     Item Selection State




                          User Input
...
Item Selections




View                     View




           Model
Item Based Views


Table Widget      T Widget
                   ree            List Widget
Item Based View




                  View
What do you get ?
●   Efficiency
●   Flexib ility
●   M aintainab ility
The Model Interface
400 000 000 000 000 cells
Model          Interface   View




Data Structure
0       0   1   2

0       0


1       1

2       2
#include <QtGui>

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

    int rows = 4;
    int columns =...
Model          Interface   View



                  hello

    ?             hello
                  hello
              ...
// we start with a 4x1 table
QStandardItemModel model(4, 1);

for (int r = 0; r < model.rowCount(); ++r) {
   QModelIndex ...
Model            Interface     View


                          world
                 hello

    ?            hello
     ...
Model



                 Model Interface


                 Custom API
Data Structure
#include <QtGui>

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

    for (int...
Model Index

● Row
● Column

● Internal Identifier
Model Index




              Qt4 Logo
Decoration Role          Typ e: Im age File
                         Size: 1 0.5 kB



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

for (int r = 0; r < model.rowCount(); ++r) {
   QModel...
QIcon icon(“images/qt4-logo.png”);
QTableWidget table(4, 1);

for (int i = 0; i < 4; ++i)
   table.setItem(i, 0, new QTabl...
T Model Interface
          he
●   A Generic Interface to Data Structures
●   M od els Are Interchangeab le
●   Views Are ...
Customized Item Filtering
Model
Model   Proxy   View
Model   Sorting   View
Model   Filtering   View
class CodeModel : public QStringListModel
{
public:
   CodeModel(const QString &fileName, QObject *parent = 0)
     : QStr...
CodeModel model(sourceFile);

QSortFilterProxyModel proxy;
proxy.setSourceModel(&model);

QTreeView view;
view.setModel(&p...
class ListModel : public QAbstractListModel
{
   Q_OBJECT
public:
   ListModel(QObject *parent = 0);
   ~ListModel();

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

ListModel::~ListModel() {}

int ListModel::rowCo...
QVariant ListModel::data(const QModelIndex &index,
                           int role) const
{
  if (role == Qt::DisplayR...
class ColorFilter : public QSortFilterProxyModel
{
   Q_OBJECT
public:
   ColorFilter(QObject *parent = 0);

  bool filter...
bool ColorFilter::filterAcceptsRow(int sourceRow,
                         const QModelIndex &sourceParent) const
{
  QMod...
...
ListModel model;
ColorFilter filter;
filter.setSourceModel(&model);
...
QSlider *redSlider = new QSlider(Qt::Horizonta...
Customized Item Painting
Item Selections




View                     Item Delegate




           Model
Qt4 Logo
                      Im age File
                      1 0.5 kB

Qt4 Logo



           Qt4 Logo
class HoverDelegate : public QItemDelegate
{
   Q_OBJECT
public:
   HoverDelegate(QObject *parent = 0) : QItemDelegate(par...
Movie Title
<?xml version="1.0" standalone="no"?>
<svg width="100" height="100" viewBox="0 0 100 100"
   xmlns="http://www.w3.org/2000...
class DemoDelegate : public QItemDelegate
{
public:
   DemoDelegate(QObject *parent = 0);

  void paint(QPainter *painter,...
void DemoDelegate::paint(QPainter *painter,
                 const QStyleOptionViewItem &option,
                 const QM...
More Models and Hierarchies
struct SimpleNode
{
   SimpleNode(SimpleNode *parent) : parentNode(parent) {
     if (parentNode)
         parentNode->chi...
Model          Interface   View




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

  QModelI...
int SimpleModel::rowCount(const QModelIndex &parent) const
{
   SimpleNode *parentNode = nodeForIndex(parent);
   return p...
SimpleModel::SimpleModel(QObject *parent)
  : QAbstractItemModel(parent)
{
  // Initialize the data structure
  root = new...
QVariant SimpleModel::data(const QModelIndex &index, int role) const
{
  if (index.isValid() && role == Qt::DisplayRole) {...
Model Index




              Qt4 Logo
QModelIndex SimpleModel::index(int row, int column,
                                  const QModelIndex &parent) const
{
 ...
QModelIndex SimpleModel::parent(const QModelIndex &child) const
{
  SimpleNode *childNode = nodeForIndex(child);
  SimpleN...
QModelIndex SimpleModel::indexForNode(SimpleNode *node) const
{
  if (node == root)
      return QModelIndex();
  int row ...
SimpleNode *SimpleModel::nodeForIndex(const QModelIndex &index) const
{
  if (index.isValid())
      return static_cast<Si...
int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   SimpleModel model;

    QTreeView view;
    view.se...
What we have covered

●   The Qt Model View Architecture
●   The Item Model Interface
●   Customized Item Filtering
●   Cu...
More Information

http://doc.trolltech.com/4.1/model-view-programming.html
http://doc.trolltech.com/4.1/model-view.html
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Upcoming SlideShare
Loading in...5
×

Practical Model View Programming (Roadshow Version)

3,918

Published on

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.

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,918
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
118
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Practical Model View Programming (Roadshow Version)

  1. 1. PRACTICAL MODEL VIEW PROGRAMMING CODE LESS. VIEW MORE.
  2. 2. Marius Bugge Monsen, MSc (NTNU), Software Developer
  3. 3. 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
  4. 4. The Model View Architecture
  5. 5. Item Selections User Input Item Selection State User Input View Item Delegate Change Notifications Data Changes Model
  6. 6. Item Selections View View Model
  7. 7. Item Based Views Table Widget T Widget ree List Widget
  8. 8. Item Based View View
  9. 9. What do you get ? ● Efficiency ● Flexib ility ● M aintainab ility
  10. 10. The Model Interface
  11. 11. 400 000 000 000 000 cells
  12. 12. Model Interface View Data Structure
  13. 13. 0 0 1 2 0 0 1 1 2 2
  14. 14. #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(); }
  15. 15. Model Interface View hello ? hello hello hello Data Structure
  16. 16. // 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”); }
  17. 17. Model Interface View world hello ? hello hello world world hello world Data Structure
  18. 18. Model Model Interface Custom API Data Structure
  19. 19. #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(); }
  20. 20. Model Index ● Row ● Column ● Internal Identifier
  21. 21. Model Index Qt4 Logo
  22. 22. Decoration Role Typ e: Im age File Size: 1 0.5 kB T ip Role oolT Qt4 Logo DisplayRole
  23. 23. 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); }
  24. 24. 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”));
  25. 25. T Model Interface he ● A Generic Interface to Data Structures ● M od els Are Interchangeab le ● Views Are Interchangeab le ● M od els and Selections Are Sharab le
  26. 26. Customized Item Filtering
  27. 27. Model
  28. 28. Model Proxy View
  29. 29. Model Sorting View
  30. 30. Model Filtering View
  31. 31. 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); } };
  32. 32. 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&)));
  33. 33. class ListModel : public QAbstractListModel { Q_OBJECT public: ListModel(QObject *parent = 0); ~ListModel(); int rowCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; };
  34. 34. ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) {} ListModel::~ListModel() {} int ListModel::rowCount(const QModelIndex &) const { return 10000; }
  35. 35. 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(); }
  36. 36. class ColorFilter : public QSortFilterProxyModel { Q_OBJECT public: 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; };
  37. 37. 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; }
  38. 38. ... 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)); ...
  39. 39. Customized Item Painting
  40. 40. Item Selections View Item Delegate Model
  41. 41. Qt4 Logo Im age File 1 0.5 kB Qt4 Logo Qt4 Logo
  42. 42. class HoverDelegate : public QItemDelegate { Q_OBJECT public: 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); ...
  43. 43. Movie Title
  44. 44. <?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>
  45. 45. 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; };
  46. 46. 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); }
  47. 47. More Models and Hierarchies
  48. 48. 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; };
  49. 49. Model Interface View Data Structure
  50. 50. 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; };
  51. 51. 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; }
  52. 52. 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; }
  53. 53. QVariant SimpleModel::data(const QModelIndex &index, int role) const { if (index.isValid() && role == Qt::DisplayRole) { SimpleNode *node = nodeForIndex(index); return node->data(); } return QVariant(); }
  54. 54. Model Index Qt4 Logo
  55. 55. 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(); }
  56. 56. QModelIndex SimpleModel::parent(const QModelIndex &child) const { SimpleNode *childNode = nodeForIndex(child); SimpleNode *parentNode = childNode->parentNode; if (parentNode == root) return QModelIndex(); return indexForNode(parentNode); }
  57. 57. QModelIndex SimpleModel::indexForNode(SimpleNode *node) const { if (node == root) return QModelIndex(); int row = rowForNode(node); int column = 0; return createIndex(row, column, node); }
  58. 58. 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); }
  59. 59. int main(int argc, char *argv[]) { QApplication app(argc, argv); SimpleModel model; QTreeView view; view.setModel(&model); view.show(); return app.exec(); }
  60. 60. What we have covered ● The Qt Model View Architecture ● The Item Model Interface ● Customized Item Filtering ● Customized Item Painting ● Hierarchical Models
  61. 61. More Information http://doc.trolltech.com/4.1/model-view-programming.html http://doc.trolltech.com/4.1/model-view.html
  1. ¿Le ha llamado la atención una diapositiva en particular?

    Recortar diapositivas es una manera útil de recopilar información importante para consultarla más tarde.

×