Difference between revisions of "Proxy model example code"

From Qt Wiki
Jump to: navigation, search
(Decode HTML entity names)
(Fixed broken-formatted source code to the version at https://tinyurl.com/ycfgrbek and updated it to compile for Qt 5)
 
Line 8: Line 8:
  
 
<code>
 
<code>
#include <QtGui>
+
#include <QTreeView>
 
+
#include <QPushButton>
 +
#include <QVBoxLayout>
 +
#include <QStandardItem>
 +
#include <QApplication>
 +
#include <QAbstractProxyModel>
 +
 
QList<QStandardItem *> list;
 
QList<QStandardItem *> list;
 
+
 
class SortProxy : public QAbstractProxyModel
 
class SortProxy : public QAbstractProxyModel
 
{
 
{
Q_OBJECT
+
    Q_OBJECT
 
+
 
public:
 
public:
SortProxy(QObject *parent = 0) : QAbstractProxyModel(parent), hideThem(false)
+
    SortProxy(QObject *parent = 0) : QAbstractProxyModel(parent), hideThem(false)
{
+
    {
fixModel();
+
        fixModel();
}
+
    }
 
+
int rowCount(const QModelIndex &parent) const
+
    int rowCount(const QModelIndex &parent) const
{
+
    {
QModelIndex sourceParent;
+
        QModelIndex sourceParent;
if (parent.isValid())
+
        if (parent.isValid())
sourceParent = mapToSource(parent);
+
            sourceParent = mapToSource(parent);
int count = 0;
+
        int count = 0;
QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(proxySourceParent);
+
        QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(proxySourceParent);
while (it.hasNext()) {
+
        while (it.hasNext()) {
it.next();
+
            it.next();
if (it.value() == sourceParent)
+
            if (it.value() == sourceParent)
count++;
+
                count++;
}
+
        }
return count;
+
        return count;
}
+
    }
 
+
int columnCount(const QModelIndex &) const
+
    int columnCount(const QModelIndex &) const
{
+
    {
return 1;
+
        return 1;
}
+
    }
 
+
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
+
    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
{
+
    {
QModelIndex sourceParent;
+
        QModelIndex sourceParent;
if (parent.isValid())
+
        if (parent.isValid())
sourceParent = mapToSource(parent);
+
            sourceParent = mapToSource(parent);
QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(proxySourceParent);
+
        QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(proxySourceParent);
while (it.hasNext()) {
+
        while (it.hasNext()) {
it.next();
+
            it.next();
if (it.value() sourceParent && it.key().row() row &&
+
            if (it.value() == sourceParent && it.key().row() == row &&
it.key().column() == column)
+
                it.key().column() == column)
return it.key();
+
                return it.key();
}
+
        }
return QModelIndex();
+
        return QModelIndex();
}
+
    }
 
+
QModelIndex parent(const QModelIndex &child) const
+
    QModelIndex parent(const QModelIndex &child) const
{
+
    {
QModelIndex mi = proxySourceParent.value(child);
+
        QModelIndex mi = proxySourceParent.value(child);
if (mi.isValid())
+
        if (mi.isValid())
return mapFromSource(mi);
+
            return mapFromSource(mi);
return QModelIndex();
+
        return QModelIndex();
}
+
    }
 
+
QModelIndex mapToSource(const QModelIndex &proxyIndex) const
+
    QModelIndex mapToSource(const QModelIndex &proxyIndex) const
{
+
    {
if (!proxyIndex.isValid())
+
        if (!proxyIndex.isValid())
return QModelIndex();
+
            return QModelIndex();
return mapping.key(proxyIndex);
+
        return mapping.key(proxyIndex);
}
+
    }
 
+
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
+
    QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
{
+
    {
if (!sourceIndex.isValid())
+
        if (!sourceIndex.isValid())
return QModelIndex();
+
            return QModelIndex();
return mapping.value(sourceIndex);
+
        return mapping.value(sourceIndex);
}
+
    }
 
+
 
public slots:
 
public slots:
void hideEverythingButA1AndChildren()
+
        void hideEverythingButA1AndChildren()
{
+
        {
hideThem = !hideThem;
+
            hideThem = !hideThem;
// Now we set up the proxy <-> source mappings
+
            // Now we set up the proxy <-> source mappings
emit layoutAboutToBeChanged();
+
            emit layoutAboutToBeChanged();
fixModel();
+
            fixModel();
emit layoutChanged();
+
            emit layoutChanged();
}
+
        }
 
+
 
private:
 
private:
void fixModel()
+
    void fixModel()
{
+
    {
mapping.clear();
+
        mapping.clear();
proxySourceParent.clear();
+
        proxySourceParent.clear();
  for (int i=0;i<list.size();i+'') {
+
   
QStandardItem *si = list.at(i);
+
        //the following list is already populated
  if (hideThem) {
+
        //in the tree view and we shall browse and
  if (!si->text().startsWith("A") || !si->parent())
+
        //customize it here
continue;
+
        for (int i=0;i<list.size();i++)
  QModelIndex proxy = createIndex(si->row(), si->column(), si->index().internalPointer());
+
        {
  mapping.insert(QPersistentModelIndex(si->index()), proxy);
+
            //pull out a standard item
QModelIndex sourceParent;
+
            QStandardItem *si = list.at(i);
  if (si->parent()->parent())
+
   
sourceParent = si->parent()->index();
+
            if (hideThem)
proxySourceParent.insert(proxy, sourceParent);
+
            {
} else {
+
                //if the hide item flag is true
QModelIndex proxy = createIndex(si->row(), si->column(), si->index().internalPointer());
+
   
mapping.insert(QPersistentModelIndex(si->index()), proxy);
+
                //check if the standard item's text start with 'A'
QModelIndex sourceParent;
+
                //of the item is not parent
if (si->parent())
+
                if (!si->text().startsWith("A") || !si->parent())
sourceParent = si->parent()->index();
+
                    continue;
proxySourceParent.insert(proxy, sourceParent);
+
   
}
+
}
+
                //means that we have encountered item that does not start with 'A'
}
+
                //or the item is not the parent
  QMap<QPersistentModelIndex, QPersistentModelIndex> mapping;
+
QMap<QPersistentModelIndex, QPersistentModelIndex> proxySourceParent;
+
                //we pull out the model index by creating the model index with the source items
bool hideThem;
+
                //row , column
 +
                QModelIndex proxy = createIndex(si->row(), si->column(), si->index().internalPointer());
 +
   
 +
                //insert the source model's index and the proxy index into the map
 +
                mapping.insert(QPersistentModelIndex(si->index()), proxy);
 +
                QModelIndex sourceParent;
 +
   
 +
                if (si->parent()->parent())
 +
                    sourceParent = si->parent()->index();
 +
                proxySourceParent.insert(proxy, sourceParent);
 +
            }
 +
            else
 +
            {
 +
                QModelIndex proxy = createIndex(si->row(), si->column(), si->index().internalPointer());
 +
                mapping.insert(QPersistentModelIndex(si->index()), proxy);
 +
                QModelIndex sourceParent;
 +
                if (si->parent())
 +
                    sourceParent = si->parent()->index();
 +
                proxySourceParent.insert(proxy, sourceParent);
 +
            }
 +
        }
 +
    }
 +
   
 +
    QMap<QPersistentModelIndex, QPersistentModelIndex> mapping;
 +
    QMap<QPersistentModelIndex, QPersistentModelIndex> proxySourceParent;
 +
    bool hideThem;
 
};
 
};
 
+
 
SortProxy *proxyModel = 0;
 
SortProxy *proxyModel = 0;
 
+
 
class Tree : public QTreeView
 
class Tree : public QTreeView
 
{
 
{
Q_OBJECT
+
    Q_OBJECT
 
+
 
public:
 
public:
Tree(QWidget *parent = 0) : QTreeView(parent)
+
    Tree(QWidget *parent = 0) : QTreeView(parent)
{
+
    {
QStandardItemModel *sourceModel = new QStandardItemModel(this);
+
        QStandardItemModel *sourceModel = new QStandardItemModel(this);
 
+
QStandardItem *parentA = sourceModel->invisibleRootItem();
+
        QStandardItem *parentA = sourceModel->invisibleRootItem();
for (int i = 0; i < 2;i) {
+
        for (int i = 0; i < 2; ++i) {
itemA = new QStandardItem(QString("A %0").arg(i));
+
            itemA = new QStandardItem(QString("A %0").arg(i));
parentA->appendRow(itemA);
+
            parentA->appendRow(itemA);
parentA = itemA;
+
            parentA = itemA;
list.append(itemA);
+
            list.append(itemA);
}
+
        }
itemA = new QStandardItem(QString("A 2"));
+
        itemA = new QStandardItem(QString("A 2"));
parentA->appendRow(itemA);
+
        parentA->appendRow(itemA);
list.append(itemA);
+
        list.append(itemA);
itemA3 = new QStandardItem(QString("A 3"));
+
        itemA3 = new QStandardItem(QString("A 3"));
list.append(itemA3);
+
        list.append(itemA3);
parentA->appendRow(itemA3);
+
        parentA->appendRow(itemA3);
itemA4 = new QStandardItem(QString("A 4"));
+
        itemA4 = new QStandardItem(QString("A 4"));
list.append(itemA4);
+
        list.append(itemA4);
parentA->appendRow(itemA4);
+
        parentA->appendRow(itemA4);
itemNonA = new QStandardItem(QString("Non A"));
+
        itemNonA = new QStandardItem(QString("Non A"));
list.append(itemNonA);
+
        list.append(itemNonA);
parentA->appendRow(itemNonA);
+
        parentA->appendRow(itemNonA);
 
+
QStandardItem *parentB = sourceModel->invisibleRootItem();
+
        QStandardItem *parentB = sourceModel->invisibleRootItem();
for (int i = 0; i < 3;i) {
+
        for (int i = 0; i < 3; ++i) {
itemB = new QStandardItem(QString("B %0").arg(i));
+
            itemB = new QStandardItem(QString("B %0").arg(i));
parentB->appendRow(itemB);
+
            parentB->appendRow(itemB);
parentB = itemB;
+
            parentB = itemB;
list.append(itemB);
+
            list.append(itemB);
}
+
        }
 
+
QStandardItem *parentC = sourceModel->invisibleRootItem();
+
        QStandardItem *parentC = sourceModel->invisibleRootItem();
for (int i = 0; i < 3;i) {
+
        for (int i = 0; i < 3; ++i) {
itemC = new QStandardItem(QString("C %0").arg(i));
+
            itemC = new QStandardItem(QString("C %0").arg(i));
parentC->appendRow(itemC);
+
            parentC->appendRow(itemC);
parentC = itemC;
+
            parentC = itemC;
list.append(itemC);
+
            list.append(itemC);
 
+
}
+
        }
 
+
proxyModel = new SortProxy(this);
+
        proxyModel = new SortProxy(this);
proxyModel->setSourceModel(sourceModel);
+
        proxyModel->setSourceModel(sourceModel);
setModel(proxyModel);
+
        setModel(proxyModel);
expandAll();
+
        expandAll();
}
+
    }
QStandardItem *itemA;
+
    QStandardItem *itemA;
QStandardItem *itemA3;
+
    QStandardItem *itemA3;
QStandardItem *itemA4;
+
    QStandardItem *itemA4;
QStandardItem *itemNonA;
+
    QStandardItem *itemNonA;
QStandardItem *itemB;
+
    QStandardItem *itemB;
QStandardItem '''itemC;
+
    QStandardItem *itemC;
 
};
 
};
 
+
 
+
 
#include "main.moc"
 
#include "main.moc"
 
+
int main(int argc, char'''*argv)
+
int main(int argc, char **argv)
 
{
 
{
QApplication app(argc, argv);
+
    QApplication app(argc, argv);
QWidget widget;
+
    QWidget widget;
QPushButton *button = new QPushButton("Make only A1'' 'A' children visible", &widget);
+
    QPushButton *button = new QPushButton("Make only A1 + 'A' children visible", &widget);
Tree *tree = new Tree(&widget);
+
    Tree *tree = new Tree(&widget);
QVBoxLayout *lay = new QVBoxLayout(&widget);
+
    QVBoxLayout *lay = new QVBoxLayout(&widget);
lay->addWidget(button);
+
    lay->addWidget(button);
QObject::connect(button, SIGNAL (clicked()), proxyModel, SLOT (hideEverythingButA1AndChildren()));
+
    QObject::connect(button, SIGNAL(clicked()), proxyModel, SLOT(hideEverythingButA1AndChildren()));
lay->addWidget(tree);
+
    lay->addWidget(tree);
widget.show();
+
    widget.show();
return app.exec();
+
    return app.exec();
 
}
 
}
 
</code>
 
</code>

Latest revision as of 15:56, 22 June 2018

Related to this FAQ entry.
  1. include <QTreeView>
  2. include <QPushButton>
  3. include <QVBoxLayout>
  4. include <QStandardItem>
  5. include <QApplication>
  6. include <QAbstractProxyModel>
QList<QStandardItem *> list; class SortProxy : public QAbstractProxyModel { Q_OBJECT public: SortProxy(QObject *parent = 0) : QAbstractProxyModel(parent), hideThem(false) { fixModel(); } int rowCount(const QModelIndex &parent) const { QModelIndex sourceParent; if (parent.isValid()) sourceParent = mapToSource(parent); int count = 0; QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(proxySourceParent); while (it.hasNext()) { it.next(); if (it.value() == sourceParent) count++; } return count; } int columnCount(const QModelIndex &) const { return 1; } QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const { QModelIndex sourceParent; if (parent.isValid()) sourceParent = mapToSource(parent); QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(proxySourceParent); while (it.hasNext()) { it.next(); if (it.value() == sourceParent && it.key().row() == row && it.key().column() == column) return it.key(); } return QModelIndex(); } QModelIndex parent(const QModelIndex &child) const { QModelIndex mi = proxySourceParent.value(child); if (mi.isValid()) return mapFromSource(mi); return QModelIndex(); } QModelIndex mapToSource(const QModelIndex &proxyIndex) const { if (!proxyIndex.isValid()) return QModelIndex(); return mapping.key(proxyIndex); } QModelIndex mapFromSource(const QModelIndex &sourceIndex) const { if (!sourceIndex.isValid()) return QModelIndex(); return mapping.value(sourceIndex); } public slots: void hideEverythingButA1AndChildren() { hideThem = !hideThem; // Now we set up the proxy <-> source mappings emit layoutAboutToBeChanged(); fixModel(); emit layoutChanged(); } private: void fixModel() { mapping.clear(); proxySourceParent.clear(); //the following list is already populated //in the tree view and we shall browse and //customize it here for (int i=0;i<list.size();i++) { //pull out a standard item QStandardItem *si = list.at(i); if (hideThem) { //if the hide item flag is true //check if the standard item's text start with 'A' //of the item is not parent if (!si->text().startsWith("A") || !si->parent()) continue; //means that we have encountered item that does not start with 'A' //or the item is not the parent //we pull out the model index by creating the model index with the source items //row , column QModelIndex proxy = createIndex(si->row(), si->column(), si->index().internalPointer()); //insert the source model's index and the proxy index into the map mapping.insert(QPersistentModelIndex(si->index()), proxy); QModelIndex sourceParent; if (si->parent()->parent()) sourceParent = si->parent()->index(); proxySourceParent.insert(proxy, sourceParent); } else { QModelIndex proxy = createIndex(si->row(), si->column(), si->index().internalPointer()); mapping.insert(QPersistentModelIndex(si->index()), proxy); QModelIndex sourceParent; if (si->parent()) sourceParent = si->parent()->index(); proxySourceParent.insert(proxy, sourceParent); } } } QMap<QPersistentModelIndex, QPersistentModelIndex> mapping; QMap<QPersistentModelIndex, QPersistentModelIndex> proxySourceParent; bool hideThem; }; SortProxy *proxyModel = 0; class Tree : public QTreeView { Q_OBJECT public: Tree(QWidget *parent = 0) : QTreeView(parent) { QStandardItemModel *sourceModel = new QStandardItemModel(this); QStandardItem *parentA = sourceModel->invisibleRootItem(); for (int i = 0; i < 2; ++i) { itemA = new QStandardItem(QString("A %0").arg(i)); parentA->appendRow(itemA); parentA = itemA; list.append(itemA); } itemA = new QStandardItem(QString("A 2")); parentA->appendRow(itemA); list.append(itemA); itemA3 = new QStandardItem(QString("A 3")); list.append(itemA3); parentA->appendRow(itemA3); itemA4 = new QStandardItem(QString("A 4")); list.append(itemA4); parentA->appendRow(itemA4); itemNonA = new QStandardItem(QString("Non A")); list.append(itemNonA); parentA->appendRow(itemNonA); QStandardItem *parentB = sourceModel->invisibleRootItem(); for (int i = 0; i < 3; ++i) { itemB = new QStandardItem(QString("B %0").arg(i)); parentB->appendRow(itemB); parentB = itemB; list.append(itemB); } QStandardItem *parentC = sourceModel->invisibleRootItem(); for (int i = 0; i < 3; ++i) { itemC = new QStandardItem(QString("C %0").arg(i)); parentC->appendRow(itemC); parentC = itemC; list.append(itemC); } proxyModel = new SortProxy(this); proxyModel->setSourceModel(sourceModel); setModel(proxyModel); expandAll(); } QStandardItem *itemA; QStandardItem *itemA3; QStandardItem *itemA4; QStandardItem *itemNonA; QStandardItem *itemB; QStandardItem *itemC; };
  1. include "main.moc"
int main(int argc, char **argv) { QApplication app(argc, argv); QWidget widget; QPushButton *button = new QPushButton("Make only A1 + 'A' children visible", &widget); Tree *tree = new Tree(&widget); QVBoxLayout *lay = new QVBoxLayout(&widget); lay->addWidget(button); QObject::connect(button, SIGNAL(clicked()), proxyModel, SLOT(hideEverythingButA1AndChildren())); lay->addWidget(tree); widget.show(); return app.exec(); }