Разделите QAbstarctListModel на подмодели - PullRequest
1 голос
/ 03 апреля 2020

У меня есть список пользовательских объектов, которые мне нужно разделить на несколько страниц SwipeView.

Прямо сейчас я реализую QAbstractListModel, чтобы предоставлять данные для моего представления QML через пользовательские роли. Но когда у меня больше заданного числа объектов, мне нужно разделить мою модель на несколько кусков, которые будут отображаться на разных страницах SwipeView.

Если в моей модели 20 объектов, мой SwipeView будет иметь 2 страницы с 12 элементами в первом и 8 оставшимися на второй странице, например, но количество элементов, конечно, динамически c.

Я знаю, что могу использовать QSortProxyFilter или DelegateModel фильтровать мою модель по критериям, но я не знаю, как их использовать для создания групп, пригодных для использования в качестве подмоделей для содержимого страниц SwipeView. Конечно, я не могу просто изменить фильтр при смене страницы, потому что это не сделает элементы видимыми при пролистывании с одной страницы на другую.

Спасибо за любой намек или идею о том, как этого добиться.

1 Ответ

0 голосов
/ 07 апреля 2020

Почему бы вам не включить модель в другую модель? Вы можете вернуть модель в QML через QVariant::fromValue. См. Мой пример:

models.h

class ChildItem{
public:
    ChildItem() {}
};

class ChildModel: public QAbstractListModel{
    Q_OBJECT
public:
    explicit ChildModel(QObject *parent = nullptr);
    void addItem(const ChildItem &item);
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
signals:
    void itemAdded();
protected:
    QHash<int,QByteArray> roleNames() const;
private:
    QVector<ChildItem> m_items;
};

class ModelItem{
public:
    ModelItem() {}
    ChildModel *childModel() const;
private:
    ChildModel *m_childModel;
};

class MainModel: public QAbstractListModel{
    Q_OBJECT
public:
    explicit MainModel(QObject *parent = nullptr);
    void addItem(const ModelItem &item);
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
signals:
    void itemAdded();
protected:
    QHash<int,QByteArray> roleNames() const;
private:
    QVector<ModelItem> m_items;
};

models.cpp

ChildModel *ModelItem::childModel() const{
    return m_childModel;
}

QVariant MainModel::data(const QModelIndex & index, int role) const {
    if (index.row() < 0 || index.row() >= (int)m_items.size())
        return QVariant();
    const MainModel &item = m_items[index.row()];
    switch (role) {
    case MainModelRoles::ChildModel:{
        return QVariant::fromValue(item.childModel());
    }
    default: {
        break;
    }
    }
    return QVariant();
}

QHash<int, QByteArray> MainModel::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[MainModelRoles::ChildModel] = "child_model";
    return roles;
}

В QML вы можете представить имя роли модели в качестве новой модели для другого элемента , Например:

  1. StackLayout, который является вашим основным элементом, включает в себя Repeater.
  2. Repeater модель MainModel экземпляр класса.
  3. Repeater делегат включает ListView
  4. ListView принимает ChildModel в качестве модели для себя (child_model ссылка)

Таким образом, вы можете содержать любое количество различных моделей внутри Основная модель и выставить их в QML как свойство модели. Это то, что вы ищете?

...