I've created a QAbstractListModel derived model based on an underlying QHash. Since I need to use the model in QML, I cannot make use of the sorting functionality Qt widgets and views have integrated.
I tried using a QSortFilterProxyModel but it doesn't seem to work with my model. Getting the model to properly work in QML wasn't tedious enough, and now I am stuck on sorting.
Any suggestions are appreciated.
Here is the model source:
typedef QHash<QString, uint> Data; class NewModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) public: NewModel(QObject * parent = 0) : QAbstractListModel(parent) {} enum Roles {WordRole = Qt::UserRole, CountRole}; QHash<int, QByteArray> roleNames() const { QHash<int, QByteArray> roles; roles[WordRole] = "word"; roles[CountRole] = "count"; return roles; } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { if (index.row() < 0 || index.row() >= m_data.size()) return QVariant(); Data::const_iterator iter = m_data.constBegin() + index.row(); switch (role) { case WordRole: return iter.key(); case CountRole: return iter.value(); } return QVariant(); } int rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) return m_data.size(); } int count() const { return m_data.size(); } public slots: void append(const QString &word) { bool alreadyThere = m_data.contains(word); if (alreadyThere) m_data[word]++; else m_data.insert(word, 1); Data::const_iterator iter = m_data.find(word); uint position = delta(iter); if (alreadyThere) { QModelIndex index = createIndex(position, 0); emit dataChanged(index, index); } else { beginInsertRows(QModelIndex(), position, position); endInsertRows(); emit countChanged(); } } void prepend(const QString &word) { if (m_data.contains(word)) m_data[word]++; else m_data.insert(word, 1); } signals: void countChanged(); private: uint delta(Data::const_iterator i) { uint d = 0; while (i != m_data.constBegin()) { ++d; --i; } return d; } Data m_data; };
Here is "trying" to sort it:
NewModel model; QAbstractItemModel * pm = qobject_cast<QAbstractItemModel *>(&model); QSortFilterProxyModel proxy; proxy.setSourceModel(pm); proxy.setSortRole(NewModel::WordRole); proxy.setDynamicSortFilter(true);
Alas, the proxy works as a model, but it doesn't sort the entries.