实现一个QAbstractItemModel迭代器

Implementing a QAbstractItemModel Iterator

本文关键字:一个 QAbstractItemModel 迭代器 实现      更新时间:2023-10-16

我一直在努力了解如何为QAbstractItemModel开发一个标准样式的迭代器,但遇到了相当大的困难。我可以使用深度优先或广度优先算法来搜索模型,但当涉及到将这些模式应用于迭代器时,我不知道如何进行。如果有人能直接告诉我(可能有伪代码),或者他们有一个愿意分享的例子,我将不胜感激。

感谢

C++14迭代器,用于给定角色的QAbstractItemModel的行。它只在模型的行上迭代,列保持不变。

class ModelRowIterator : public std::iterator
    <
        std::input_iterator_tag,    // iterator_category
        QVariant,                   // value_type
        int,                        // difference_type
        const QVariant*,            // pointer
        QVariant                    // reference
    >
{
    QModelIndex index_;
    int role_ = 0;
public:
    ModelRowIterator() {}
    ModelRowIterator(const QModelIndex& index, int role) : index_(index), role_(role) {}
    ModelRowIterator& operator++()
    {
        if (index_.isValid())
            index_ = index_.model()->index(index_.row()+1, index_.column());
        return *this;
    }
    ModelRowIterator operator++(int)
    {
        ModelRowIterator ret = *this;
        ++(*this);
        return ret;
    }
    bool operator==(const ModelRowIterator& other) const
    {
        return (!other.index_.isValid() && !index_.isValid()) // ending condition
            || (other.index_ == index_ && other.role_ == role_);
    }
    bool operator!=(const ModelRowIterator& other) const
    {
        return !(other == *this);
    }
    reference operator*() const
    {
        return index_.isValid() ? index_.data(role_) : QVariant{};
    }
};

注意:std::iteratorC++17中已弃用。

用法:

QAbstractItemModel model;
int role = ...;
ModelRowIterator begin { model.index(0,0), role };
ModelRowIterator end {};
std::for_each(begin, end, [](const QVariant& v) { qDebug() << v; });
auto range = boost::make_range(begin, end);
boost::range::equal(range, [](const QVariant& v) { qDebug() << v; });