QSortFilterProxyModel returning artificial row

2024/9/8 10:20:17

I'm using a QSortFilterProxyModel to filter results from a QAbstractListModel. However, I'd like to return a first entry which is not present in the original model, that is, it's somehow artificial.

This is what I have so far:

class ActivedAccountModel(QSortFilterProxyModel):                                                                                                                                  def __init__(self, model, parent=None):super(ActiveAccountModel, self).__init__(parent)self.setSourceModel(model)self.setDynamicSortFilter(True)def data(self, index, role=Qt.DisplayRole):account_info = super(ActiveAccountModel, self).data(index, Qt.UserRole).toPyObject()if role == Qt.DisplayRole:return account_info.nameelif role == Qt.UserRole:return account_inforeturn Nonedef filterAcceptsRow(self, source_row, source_parent):source_model = self.sourceModel()source_index = source_model.index(source_row, 0, source_parent)account_info = source_model.data(source_index, Qt.UserRole)return isinstance(account_info.account, Account) and account_info.account.enabled

This will return a list in the form of:

Account 1
Account 2
...

Id' like to return an extra element at the begining of the returned list f elements:

Extra Element
Account 1
Account 2
...

I tried to reimplement rowCount in order to return the real rowCount()+1, but somehow I'd need to shift all the items in order to return this artificial element at index 0, and I'm a bit lost there.

Any clue? I couldn't find any related code example so far... Thanks!

Answer

Because I struggled a little bit with the implementation of this and because I could not find any other sample code in the whole net, I post this sample implementation.

I hope this helps other people too...

/**** Written by Sven Anders (ANDURAS AG). Public domain code.**/#include <QDebug>
#include <QBrush>
#include <QFont>
#include <QSortFilterProxyModel>/** Definition **/class ProxyModelNoneEntry : public QSortFilterProxyModel
{Q_OBJECTpublic:ProxyModelNoneEntry(QString _entry_text = tr("(None)"), QObject *parent=0);int rowCount(const QModelIndex &parent = QModelIndex()) const;/* lessThan() is not necessary for this model to work, but can beimplemented in a derived class if a custom sorting method is required. */// bool lessThan(const QModelIndex &left, const QModelIndex &right) const;QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;QModelIndex mapToSource(const QModelIndex &proxyIndex) const;QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;Qt::ItemFlags flags(const QModelIndex &index) const;QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;QModelIndex parent(const QModelIndex &child) const;private:QString entry_text;
};/** Implementation **/ProxyModelNoneEntry::ProxyModelNoneEntry(QString _entry_text, QObject *parent) : QSortFilterProxyModel(parent)
{entry_text = _entry_text;
}int ProxyModelNoneEntry::rowCount(const QModelIndex &parent) const
{Q_UNUSED(parent)return QSortFilterProxyModel::rowCount()+1;
}QModelIndex ProxyModelNoneEntry::mapFromSource(const QModelIndex &sourceIndex) const
{if (!sourceIndex.isValid()) return QModelIndex();else if (sourceIndex.parent().isValid()) return QModelIndex();return createIndex(sourceIndex.row()+1, sourceIndex.column());
}QModelIndex ProxyModelNoneEntry::mapToSource(const QModelIndex &proxyIndex) const
{if (!proxyIndex.isValid()) return QModelIndex();else if (proxyIndex.row() == 0) return QModelIndex();return sourceModel()->index(proxyIndex.row()-1, proxyIndex.column());
}QVariant ProxyModelNoneEntry::data(const QModelIndex &index, int role) const
{if (!index.isValid()) return QVariant();if (index.row() == 0){if (role == Qt::DisplayRole)return entry_text;else if (role == Qt::DecorationRole)return QVariant();else if (role == Qt::FontRole){ QFont font; font.setItalic(true); return font; }elsereturn QVariant();}return QSortFilterProxyModel::data(createIndex(index.row(),index.column()), role);
}Qt::ItemFlags ProxyModelNoneEntry::flags(const QModelIndex &index) const
{if (!index.isValid()) return Qt::NoItemFlags;if (index.row() == 0) return Qt::ItemIsSelectable | Qt::ItemIsEnabled;return QSortFilterProxyModel::flags(createIndex(index.row(),index.column()));
}QModelIndex ProxyModelNoneEntry::index(int row, int column, const QModelIndex &parent) const
{if (row > rowCount()) return QModelIndex();return createIndex(row, column);
}QModelIndex ProxyModelNoneEntry::parent(const QModelIndex &child) const
{Q_UNUSED(child)return QModelIndex();
}

RegardsSven

https://en.xdnf.cn/q/73020.html

Related Q&A

@login_required is losing the current specified language

I am using i18n_patterns to internationalize my app and its working except when I click on a link that requires login (a view protected by @login_required decorator), I am being redirected to the login…

Python slow on fetchone, hangs on fetchall

Im writing a script to SELECT query a database and parse through ~33,000 records. Unfortunately Im running into problems at the cursor.fetchone()/cursor.fetchall() phase of things.I first tried iterati…

Pure Python Quadtree Implementation

All,There are a few examples on implementing a quadtree using Python but my question is, does anyone know of a class written in pure python as in a single .py file that I can easily include in my proje…

AttributeError: tuple object has no attribute write

I have a homework assignment for a Python class and am running into an error that I dont understand. Running Python IDLE v3.2.2 on Windows 7.Below is where the problem is happening:#local variables num…

How to catch all exceptions with CherryPy?

I use CherryPy to run a very simple web server. It is intended to process the GET parameters and, if they are correct, do something with them. import cherrypyclass MainServer(object):def index(self, **…

matplotlib: How can you specify colour levels in a 2D historgram

I would like to plot a 2D histogram that includes both positive and negative numbers. I have the following code which uses pcolormesh but I am unable to specify the color levels to force the white col…

Strange behavior from HTTP authentication with suds SOAP library

I have a working python program that is fetching a large volume of data via SOAP using suds. The web service is implemented with a paging function such that I can grab nnn rows with each fetch call an…

Scipy/Numpy/scikits - calculating precision/recall scores based on two arrays

I fit a Logistic Regression Model and train the model based on training dataset using the following import scikits as sklearn from sklearn.linear_model import LogisticRegression lr = LogisticRegression…

Cant create test client during unit test of Flask app

I am trying to find out how to run a test on a function which grabs a variable value from session[user_id]. This is the specific test method:def test_myProfile_page(self):with app.test_client() as c:w…

My python installation is broken/corrupted. How do I fix it?

I followed these instructions on my RedHat Linux version 7 server (which originally just had Python 2.6.x installed):beginning of instructions install build toolssudo yum install make automake gcc gcc-…