Strange interaction of QAbstractItemModel with QSortFilterProxyModel

861 views Asked by At

What is wrong with this an interaction of QAbstractItemModel with QSortFilterProxyModel? On left part of screen I connected my implementation of QAbstractItemModel and on right part part I did QSortFilterProxyModel.

UPD: upload the code: [email protected]:h0x0d9/myfilterproxymodel.git

Code:

ListsRegisterModel *model = new ListsRegisterModel(this);

QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(model);


QTreeView *view = new QTreeView(this);
view->setModel(model);

QTreeView *view2 = new QTreeView(this);
view2->setModel(proxyModel);

Headers:

class ListsRegisterModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    explicit ListsRegisterModel(QObject *parent = 0);
    ~ListsRegisterModel();

    QVariant data(const QModelIndex &index, int role) const;
    Qt::ItemFlags flags(const QModelIndex &index) const;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const;
    QModelIndex index(int row, int column,
                      const QModelIndex &parent = QModelIndex()) const;
    QModelIndex parent(const QModelIndex &index) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    bool setData(const QModelIndex &index, const QVariant &value,
                 int role = Qt::CheckStateRole);

private:
    enum Columns
    {
        RamificationColumn,
        ListNameColumn = RamificationColumn,
        ListSubscriberColumn
    };

    TreeItem *rootItem;

    QMultiMap<QString, QString> parseListsFile(QString path);
    void setupModelData(QMultiMap<QString, QString> lists, TreeItem *parent);
    TreeItem *getItem(const QModelIndex &index) const;
};



ListsRegisterModel::ListsRegisterModel(QObject *parent) :
    QAbstractItemModel(parent)
{
    QList<QVariant> rootData;
    rootData << tr("List") << tr("Subscribers");
    rootItem = new TreeItem(rootData);

    QMultiMap<QString, QString> listsReg = parseListsFile("etc/lists.reg");
    setupModelData(listsReg, rootItem);
}


QVariant ListsRegisterModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    TreeItem *item = getItem(index);

    switch (role) {
    case Qt::DisplayRole:
        if (item->parent() == rootItem) {
            return item->data(index.column());
        }
        else {
            qDebug() << item->data(index.column() - 1);
            return item->data(index.column() - 1);
        }
        break;
    case Qt::CheckStateRole:
        if (index.column() == RamificationColumn
                && item->parent() == rootItem) {
            return QVariant(item->checkState());
        }
        break;
    default:
        return QVariant();
        break;
    }
    return QVariant();
}




QModelIndex ListsRegisterModel::index(int row, int column, const QModelIndex &parent) const
{
    TreeItem * parentItem;

    if (row < 0 || column < 0)
        return QModelIndex();

    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = getItem(parent);

    TreeItem *childItem = parentItem->child(row);

    if (childItem)
        return createIndex(row, column, childItem);

    return QModelIndex();
}


QModelIndex ListsRegisterModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    TreeItem *childItem = getItem(index);
    TreeItem *parentItem = childItem->parent();

    if (parentItem == rootItem)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}
1

There are 1 answers

0
Pavel On

I'm sprinkling ashes upon my head. I defined falsely columnCount() function. The correct version will be this:

int ListsRegisterModel::columnCount(const QModelIndex &parent) const
{
    return LastColumn; // = 2
}