获取QList对象的ListView索引

时间:2015-05-29 13:57:12

标签: c++ qt qml model-view

我已将QList<MyItem*>作为ListView的模型展示。但是如何获得ListView对象的MyItem*索引?

上下文:我在C ++中创建了一个findObject()函数,当我找到了对象(MyItem*)时,我想滚动到{{1}中的相应项}}

一些代码(完整的源代码和Qt Creator项目可以在https://github.com/joncol/qml_test找到。)

项目类:

ListView

模特:

class MyItem : public QObject
{
    Q_OBJECT
    Q_PROPERTY(qint32 data READ data NOTIFY dataChanged)

public:
    MyItem() : m_data(s_counter++) {}

    quint32 data() const { return m_data; }

signals:
    void dataChanged();

private:
    static int s_counter;
    int m_data;
};

&#39;主要&#39;功能:

class MyCppModel : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QQmlListProperty<MyItem> itemList READ itemList NOTIFY itemListChanged)

public:
    MyCppModel()
    {
        m_specialItem = new MyItem;

        m_model.append(new MyItem);
        m_model.append(new MyItem);
        m_model.append(new MyItem);
        m_model.append(m_specialItem);
        m_model.append(new MyItem);
    }

    QQmlListProperty<MyItem> itemList()
    {
        return QQmlListProperty<MyItem>(this, m_model);
    }

    Q_INVOKABLE QVariant specialItem()
    {
        return QVariant::fromValue(m_specialItem);
    }

signals:
    void itemListChanged();

private:
    QList<MyItem*> m_model;
    MyItem* m_specialItem; // simulate found item
};

最后是QML:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    QQmlContext* c = engine.rootContext();

    MyCppModel* myCppModel = new MyCppModel;
    c->setContextProperty("myCppModel", myCppModel);

    qmlRegisterUncreatableType<MyItem>("CppModel", 1, 0, "MyItem", "");

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

1 个答案:

答案 0 :(得分:1)

根据您的应用程序逻辑,有几种方法可以执行此操作。

<强> 1。将isSpecialItem属性添加到MyItem

class MyItem : public QObject
{
    Q_OBJECT
    Q_PROPERTY(qint32 data READ data NOTIFY dataChanged)
    Q_PROPERTY(bool isSpecialItem READ isSpecialItem WRITE setIsSpecialItem NOTIFY isSpecialItemChanged)
    // ...
}

您的代表将如下所示:

Rectangle {
    width: parent.width
    height: 20
    color: "#34495e"
    border.width: 1
    border.color: isSpecialItem ? "red" : "black"

    Text {
        x: 10
        anchors.verticalCenter: parent.verticalCenter
        text: modelData.data
        color: "white"
    }
}

这是最简单的方法,但是使用您可能认为更具特定于UI的内容来污染MyItem

<强> 2。将MyCppModel派生自QAbstractItemModel

使用此选项,您可以在委托中使用SpecialItem role,委托的QML代码与选项#1相同。

我会称之为解决此问题的规范方法,尤其是itemList不需要QQmlListProperty时。它不需要将可能的特定于UI的isSpecialItem属性添加到MyItem,并且可以按照您当前存储它的相同方式存储;在你的data()函数中,你会写出类似的东西:

if (role == SpecialItem) {
    return QVariant(m_specialItem == m_model.at(index.row()));
}

第3。将特殊项目公开为列表的索引属性

要这样做,您可以将specialItem()函数转换为MyCppModel的属性:

Q_PROPERTY(int specialItemIndex READ specialItemIndex WRITE specialItemIndex NOTIFY specialItemIndexChanged)

然后,您的代表看起来与选项2非常相似,除了一行:

border.color: myCppModel.specialItemIndex == index ? "red" : "black"