从模型中获取下一项

时间:2018-07-16 14:52:57

标签: c++ qt qml qt5

我已经创建了GridView,它委托了自定义对象(Item),并且其模型是从QSortFilterProxyModel派生的。当前,每当我单击GridView中的项目时,它都会显示有关该项目的一些信息,但是目前,我正尝试使用键盘箭头进行控制,因此我需要帮助功能,该功能可以获取下一个/上一个项目。 / p>

我设法解决了一些问题:

  • 获取GridView中当前所选项目的索引,我设法这样做:

    console.log(slabItemContainer.contentItem.data[index]),但是我没有设法从索引中获取委托(因为我不需要QQuickItem,但是我需要指向Item的指针)。我已经将Item的角色名称设置为"item",所以每当我用console.log(item)写行时,它就显示正确的对象,但是我没有设法从{{1 }}按索引。

  • QQuickItem衍生的模型中获取自定义对象

我尝试从模型中获取某种QSortFilterProxyModel,但是我不知道如何访问数据。我的模型包含指向当前选中的QList的指针,因此我试图从我的模型中获取整个列表,然后找到当前选中的项然后进行下一步设置,但是我什至没有创建列表,因为知道如何使用它。 我尝试使用Item,但没有成功。

mapToSource()

QModelIndex modelIndex = this->index(0,0, QModelIndex()); qDebug() << mapToSource(modelIndex);中单击Item会打印GridView,这会打印我Item(0x2d508408),但同样,我也不知道如何从中获取数据。

有人有经验吗?如何按当前项目获取下一个项目?

感谢您的帮助!

//编辑:

Filter.h

QModelIndex(0,0,0x0,ItemModel(0x2d528210))

Filter.cpp

#include <QSortFilterProxyModel>
#include "Item.h"

class MyModel : public QSortFilterProxyModel
{
    Q_OBJECT
    Q_PROPERTY(Item* currentDetailView READ currentDetailView WRITE setFilterCurrentDetailView NOTIFY currentDetailViewChanged)

public:
    ItemFilterSortModel(QObject *parent = 0);

    //! Return true, if entity matches with filter conditions
    bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;

    //! Returns Item to load into view
    Item * currentDetailView() const {return currentDetailView_;}

    //! Set up currently showing detail of Item
    Q_INVOKABLE void setFilterCurrentDetailView(Item *ItemToView);

    Q_INVOKABLE Item * getFilterNextDetailView();

    Q_INVOKABLE Item * getFilterPrevDetailView();

signals:
    currentDetailViewChanged();

private:
    Item *currentDetailView_;
};

GridView.qml

#include "MyModel.h"

ItemFilterSortModel::ItemFilterSortModel(QObject *parent)
    : QSortFilterProxyModel(parent)
{

}

bool ItemFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    QModelIndex modelIndex = sourceModel()->index(source_row, 0, source_parent);

    //Checking conditions for displaying Item into gridview
    return (foo(sourceModel()->data(modelIndex,confidenceRole).toDouble()));
}

Item *ItemFilterSortModel::getFilterNextDetailView()
{
    QModelIndex modelIndex = this->index(0,0, QModelIndex());
    qDebug() << mapToSource(modelIndex);
}

Item *ItemFilterSortModel::getFilterPrevDetailView()
{

}

//编辑:

按下向右箭头键会在屏幕上显示 What happens to screen when right arrow key is pressed

//编辑:

ItemModel.h

GridView {    
            model: slabGridModel.filterModel
            delegate: Item{
                height: slabItemContainer.cellHeight - 15
                width: slabItemContainer.cellWidth - 15
            }
            Action {
                 shortcut: "Right"
                 onTriggered: model.getFilterNextDetailView()
            }
        }

ItemModel.cpp

#include "Item.h"
#include <QAbstractListModel>
#include <QSortFilterProxyModel>

class ItemModel : public QAbstractListModel
{
    Q_OBJECT

public:
    // ---- PUBLIC METHODS ----
    //! Deletes items in list
    ~ItemModel();

    //! Returns number of items in list
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;

    //! Exposes data of Items to QML by their roles
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    //! Appends the Item into Item list
    void appendItem(Item * Item);

    //! Sets up role names for exposing them to QML
    QHash<int, QByteArray> roleNames() const;

    //! Returns list of all available Items
    QList<Item *> getItemList() const { return ItemList_; }

private:
    // ---- PRIVATE ATTRIBUTES ----
    QList<Item *> ItemList_;
};

1 个答案:

答案 0 :(得分:3)

使用我的previous answer,因为我认为您正在使用它作为代码的基础,因此我们可以在QML中获得以下元素,因为当您使用代理时,以下内容是相对于模型方面的,因为您在图中表示以下是视觉概念:

itemfiltersortmodel.h

#ifndef FILTERPROXYMODEL_H
#define FILTERPROXYMODEL_H

#include "item.h"

#include <QSortFilterProxyModel>
#include <QDebug>

class ItemFilterProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT
    Q_PROPERTY(Item* currentItem READ currentItem WRITE setCurrentItem NOTIFY currentItemChanged)
public:
    using QSortFilterProxyModel::QSortFilterProxyModel;
    Item *currentItem()
    {
        return mCurrentItem;
    }
    void setCurrentItem(Item *currentItem)
    {
        qDebug()<<currentItem;
        if(mCurrentItem == currentItem)
            return;
        mCurrentItem = currentItem;
        emit currentItemChanged();
    }
    bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
    {
        // foo process
        return true;
    }
signals:
    void currentItemChanged();
private:
    Item *mCurrentItem;
};

#endif // FILTERPROXYMODEL_H

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    GridView {
        id: gv
        anchors.fill: parent
        model: manager.filterModel
        property int nextIndex : mod(currentIndex+1, count)
        property int previousIndex : mod(currentIndex-1, count)
        property var currentModelItem
        onCurrentModelItemChanged: model.currentItem = currentModelItem
        delegate:
            Rectangle {
            width: 100
            height: 100
            property var view: GridView.view
            property bool isCurrentItem: index === view.currentIndex
            property bool isPreviousItem : index === view.nextIndex
            property bool isNextItem : index === view.previousIndex
            color: isCurrentItem ? "red" : isNextItem ? "green"  : isPreviousItem ? "blue" : "yellow"
            rotation: isCurrentItem ? 180 : isNextItem ? 90  : isPreviousItem? -90  : 0
            onIsNextItemChanged: if(isNextItem) view.currentModelItem = modelData
            Text {
                text: modelData.getVar
                anchors.centerIn: parent
            }
        }
    }
    // https://stackoverflow.com/a/50770689/6622587
    function mod(n, p){
        var r = n % p;
        return r < 0 ? r + p : r;
    }
    Action {
        shortcut: "Right"
        onTriggered: gv.currentIndex = mod(gv.currentIndex + 1, gv.count)

    }
    Action {
        shortcut: "Left"
        onTriggered: gv.currentIndex = mod(gv.currentIndex - 1, gv.count)
    }
}

enter image description here

颜色:

  • 上一个:蓝色
  • 当前:红色
  • 下一个:绿色

您可以在以下link中找到完整的代码。