Proxy model example code: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
[[Category:snippets]]<br />[[Category:HowTo]]<br />[[Category:Developing with Qt]] | |||
Related to "this FAQ entry&quot;:http://developer.qt.nokia.com/faq/answer/how_can_i_implement_my_own_proxy_model_that_is_more_advanced_than_just_sort. | |||
* | <code><br />#include <QtGui&gt; | ||
* | |||
* | QList&lt;QStandardItem *> list; | ||
class SortProxy : public QAbstractProxyModel<br />{<br /> Q_OBJECT | |||
public:<br /> SortProxy(QObject *parent = 0) : QAbstractProxyModel(parent), hideThem(false)<br /> {<br /> fixModel();<br /> } | |||
int rowCount(const QModelIndex &parent) const<br /> {<br /> QModelIndex sourceParent;<br /> if (parent.isValid())<br /> sourceParent = mapToSource(parent);<br /> int count = 0;<br /> QMapIterator&lt;QPersistentModelIndex, QPersistentModelIndex&gt; it(proxySourceParent);<br /> while (it.hasNext()) {<br /> it.next();<br /> if (it.value() == sourceParent)<br /> count++;<br /> }<br /> return count;<br /> } | |||
int columnCount(const QModelIndex &) const<br /> {<br /> return 1;<br /> } | |||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const<br /> {<br /> QModelIndex sourceParent;<br /> if (parent.isValid())<br /> sourceParent = mapToSource(parent);<br /> QMapIterator&lt;QPersistentModelIndex, QPersistentModelIndex&gt; it(proxySourceParent);<br /> while (it.hasNext()) {<br /> it.next();<br /> if (it.value() sourceParent &amp;&amp; it.key().row() row &&<br /> it.key().column() == column)<br /> return it.key();<br /> }<br /> return QModelIndex();<br /> } | |||
QModelIndex parent(const QModelIndex &child) const<br /> {<br /> QModelIndex mi = proxySourceParent.value(child);<br /> if (mi.isValid())<br /> return mapFromSource(mi);<br /> return QModelIndex();<br /> } | |||
QModelIndex mapToSource(const QModelIndex &proxyIndex) const<br /> {<br /> if (!proxyIndex.isValid())<br /> return QModelIndex();<br /> return mapping.key(proxyIndex);<br /> } | |||
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const<br /> {<br /> if (!sourceIndex.isValid())<br /> return QModelIndex();<br /> return mapping.value(sourceIndex);<br /> } | |||
public slots:<br /> void hideEverythingButA1AndChildren()<br /> {<br /> hideThem = !hideThem;<br /> // Now we set up the proxy <<s>> source mappings<br /> emit layoutAboutToBeChanged();<br /> fixModel();<br /> emit layoutChanged();<br /> } | |||
<br />private:<br /> void fixModel()<br /> {<br /> mapping.clear();<br /> proxySourceParent.clear();<br /> for (int i=0;i&lt;list.size();i+'') {<br /> QStandardItem *si = list.at(i);<br /> if (hideThem) {<br /> if (!si->text().startsWith("A&quot;) || !si->parent())<br /> continue;<br /> QModelIndex proxy = createIndex(si->row(), si->column(), si->index().internalPointer());<br /> mapping.insert(QPersistentModelIndex(si->index()), proxy);<br /> QModelIndex sourceParent;<br /> if (si->parent()<s>>parent())<br /> sourceParent = si</s>>parent()<s>>index();<br /> proxySourceParent.insert(proxy, sourceParent);<br /> } else {<br /> QModelIndex proxy = createIndex(si</s>>row(), si->column(), si->index().internalPointer());<br /> mapping.insert(QPersistentModelIndex(si->index()), proxy);<br /> QModelIndex sourceParent;<br /> if (si->parent())<br /> sourceParent = si->parent()<s>>index();<br /> proxySourceParent.insert(proxy, sourceParent);<br /> }<br /> }<br /> }<br /> QMap&lt;QPersistentModelIndex, QPersistentModelIndex&gt; mapping;<br /> QMap&lt;QPersistentModelIndex, QPersistentModelIndex&gt; proxySourceParent;<br /> bool hideThem;<br />}; | |||
<br />SortProxy *proxyModel = 0; | |||
<br />class Tree : public QTreeView<br />{<br /> Q_OBJECT | |||
<br />public:<br /> Tree(QWidget *parent = 0) : QTreeView(parent)<br /> {<br /> QStandardItemModel *sourceModel = new QStandardItemModel(this); | |||
<br /> QStandardItem *parentA = sourceModel</s>>invisibleRootItem();<br /> for (int i = 0; i < 2;i) {<br /> itemA = new QStandardItem(QString("A %0&quot;).arg(i));<br /> parentA->appendRow(itemA);<br /> parentA = itemA;<br /> list.append(itemA);<br /> }<br /> itemA = new QStandardItem(QString("A 2&quot;));<br /> parentA->appendRow(itemA);<br /> list.append(itemA);<br /> itemA3 = new QStandardItem(QString("A 3&quot;));<br /> list.append(itemA3);<br /> parentA->appendRow(itemA3);<br /> itemA4 = new QStandardItem(QString("A 4&quot;));<br /> list.append(itemA4);<br /> parentA->appendRow(itemA4);<br /> itemNonA = new QStandardItem(QString("Non A&quot;));<br /> list.append(itemNonA);<br /> parentA->appendRow(itemNonA); | |||
<br /> QStandardItem *parentB = sourceModel->invisibleRootItem();<br /> for (int i = 0; i < 3;i) {<br /> itemB = new QStandardItem(QString("B %0&quot;).arg(i));<br /> parentB->appendRow(itemB);<br /> parentB = itemB;<br /> list.append(itemB);<br /> } | |||
<br /> QStandardItem *parentC = sourceModel->invisibleRootItem();<br /> for (int i = 0; i < 3;i) {<br /> itemC = new QStandardItem(QString("C %0&quot;).arg(i));<br /> parentC->appendRow(itemC);<br /> parentC = itemC;<br /> list.append(itemC); | |||
<br /> } | |||
<br /> proxyModel = new SortProxy(this);<br /> proxyModel->setSourceModel(sourceModel);<br /> setModel(proxyModel);<br /> expandAll();<br /> }<br /> QStandardItem *itemA;<br /> QStandardItem *itemA3;<br /> QStandardItem *itemA4;<br /> QStandardItem *itemNonA;<br /> QStandardItem *itemB;<br /> QStandardItem '''itemC;<br />}; | |||
<br />#include "main.moc&quot; | |||
<br />int main(int argc, char'''*argv)<br />{<br /> QApplication app(argc, argv);<br /> QWidget widget;<br /> QPushButton *button = new QPushButton("Make only A1'' 'A' children visible&quot;, &widget);<br /> Tree *tree = new Tree(&widget);<br /> QVBoxLayout *lay = new QVBoxLayout(&widget);<br /> lay</s>>addWidget(button);<br /> QObject::connect(button, SIGNAL (clicked()), proxyModel, SLOT (hideEverythingButA1AndChildren()));<br /> lay->addWidget(tree);<br /> widget.show();<br /> return app.exec&amp;#40;&#41;;<br />}<br /></code> |
Revision as of 09:28, 24 February 2015
Related to "this FAQ entry":http://developer.qt.nokia.com/faq/answer/how_can_i_implement_my_own_proxy_model_that_is_more_advanced_than_just_sort.
<br />#include <QtGui&gt;
QList&lt;QStandardItem *> list;
class SortProxy : public QAbstractProxyModel<br />{<br /> Q_OBJECT
public:<br /> SortProxy(QObject *parent = 0) : QAbstractProxyModel(parent), hideThem(false)<br /> {<br /> fixModel();<br /> }
int rowCount(const QModelIndex &parent) const<br /> {<br /> QModelIndex sourceParent;<br /> if (parent.isValid())<br /> sourceParent = mapToSource(parent);<br /> int count = 0;<br /> QMapIterator&lt;QPersistentModelIndex, QPersistentModelIndex&gt; it(proxySourceParent);<br /> while (it.hasNext()) {<br /> it.next();<br /> if (it.value() == sourceParent)<br /> count++;<br /> }<br /> return count;<br /> }
int columnCount(const QModelIndex &) const<br /> {<br /> return 1;<br /> }
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const<br /> {<br /> QModelIndex sourceParent;<br /> if (parent.isValid())<br /> sourceParent = mapToSource(parent);<br /> QMapIterator&lt;QPersistentModelIndex, QPersistentModelIndex&gt; it(proxySourceParent);<br /> while (it.hasNext()) {<br /> it.next();<br /> if (it.value() sourceParent &amp;&amp; it.key().row() row &&<br /> it.key().column() == column)<br /> return it.key();<br /> }<br /> return QModelIndex();<br /> }
QModelIndex parent(const QModelIndex &child) const<br /> {<br /> QModelIndex mi = proxySourceParent.value(child);<br /> if (mi.isValid())<br /> return mapFromSource(mi);<br /> return QModelIndex();<br /> }
QModelIndex mapToSource(const QModelIndex &proxyIndex) const<br /> {<br /> if (!proxyIndex.isValid())<br /> return QModelIndex();<br /> return mapping.key(proxyIndex);<br /> }
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const<br /> {<br /> if (!sourceIndex.isValid())<br /> return QModelIndex();<br /> return mapping.value(sourceIndex);<br /> }
public slots:<br /> void hideEverythingButA1AndChildren()<br /> {<br /> hideThem = !hideThem;<br /> // Now we set up the proxy <<s>> source mappings<br /> emit layoutAboutToBeChanged();<br /> fixModel();<br /> emit layoutChanged();<br /> }
<br />private:<br /> void fixModel()<br /> {<br /> mapping.clear();<br /> proxySourceParent.clear();<br /> for (int i=0;i&lt;list.size();i+'') {<br /> QStandardItem *si = list.at(i);<br /> if (hideThem) {<br /> if (!si->text().startsWith("A&quot;) || !si->parent())<br /> continue;<br /> QModelIndex proxy = createIndex(si->row(), si->column(), si->index().internalPointer());<br /> mapping.insert(QPersistentModelIndex(si->index()), proxy);<br /> QModelIndex sourceParent;<br /> if (si->parent()<s>>parent())<br /> sourceParent = si</s>>parent()<s>>index();<br /> proxySourceParent.insert(proxy, sourceParent);<br /> } else {<br /> QModelIndex proxy = createIndex(si</s>>row(), si->column(), si->index().internalPointer());<br /> mapping.insert(QPersistentModelIndex(si->index()), proxy);<br /> QModelIndex sourceParent;<br /> if (si->parent())<br /> sourceParent = si->parent()<s>>index();<br /> proxySourceParent.insert(proxy, sourceParent);<br /> }<br /> }<br /> }<br /> QMap&lt;QPersistentModelIndex, QPersistentModelIndex&gt; mapping;<br /> QMap&lt;QPersistentModelIndex, QPersistentModelIndex&gt; proxySourceParent;<br /> bool hideThem;<br />};
<br />SortProxy *proxyModel = 0;
<br />class Tree : public QTreeView<br />{<br /> Q_OBJECT
<br />public:<br /> Tree(QWidget *parent = 0) : QTreeView(parent)<br /> {<br /> QStandardItemModel *sourceModel = new QStandardItemModel(this);
<br /> QStandardItem *parentA = sourceModel</s>>invisibleRootItem();<br /> for (int i = 0; i < 2;i) {<br /> itemA = new QStandardItem(QString("A %0&quot;).arg(i));<br /> parentA->appendRow(itemA);<br /> parentA = itemA;<br /> list.append(itemA);<br /> }<br /> itemA = new QStandardItem(QString("A 2&quot;));<br /> parentA->appendRow(itemA);<br /> list.append(itemA);<br /> itemA3 = new QStandardItem(QString("A 3&quot;));<br /> list.append(itemA3);<br /> parentA->appendRow(itemA3);<br /> itemA4 = new QStandardItem(QString("A 4&quot;));<br /> list.append(itemA4);<br /> parentA->appendRow(itemA4);<br /> itemNonA = new QStandardItem(QString("Non A&quot;));<br /> list.append(itemNonA);<br /> parentA->appendRow(itemNonA);
<br /> QStandardItem *parentB = sourceModel->invisibleRootItem();<br /> for (int i = 0; i < 3;i) {<br /> itemB = new QStandardItem(QString("B %0&quot;).arg(i));<br /> parentB->appendRow(itemB);<br /> parentB = itemB;<br /> list.append(itemB);<br /> }
<br /> QStandardItem *parentC = sourceModel->invisibleRootItem();<br /> for (int i = 0; i < 3;i) {<br /> itemC = new QStandardItem(QString("C %0&quot;).arg(i));<br /> parentC->appendRow(itemC);<br /> parentC = itemC;<br /> list.append(itemC);
<br /> }
<br /> proxyModel = new SortProxy(this);<br /> proxyModel->setSourceModel(sourceModel);<br /> setModel(proxyModel);<br /> expandAll();<br /> }<br /> QStandardItem *itemA;<br /> QStandardItem *itemA3;<br /> QStandardItem *itemA4;<br /> QStandardItem *itemNonA;<br /> QStandardItem *itemB;<br /> QStandardItem '''itemC;<br />};
<br />#include "main.moc&quot;
<br />int main(int argc, char'''*argv)<br />{<br /> QApplication app(argc, argv);<br /> QWidget widget;<br /> QPushButton *button = new QPushButton("Make only A1'' 'A' children visible&quot;, &widget);<br /> Tree *tree = new Tree(&widget);<br /> QVBoxLayout *lay = new QVBoxLayout(&widget);<br /> lay</s>>addWidget(button);<br /> QObject::connect(button, SIGNAL (clicked()), proxyModel, SLOT (hideEverythingButA1AndChildren()));<br /> lay->addWidget(tree);<br /> widget.show();<br /> return app.exec&amp;#40;&#41;;<br />}<br />