2015-05-29 56 views
2

我已经公开QList<MyItem*>作为ListView的模型。但是,我怎样才能得到​​对象的ListView索引?我正在C++中创建一个findObject()函数,当我找到对象(一个​​)时,我想滚动到ListView中的相应项目。获取QList对象的ListView索引

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

该项目类:

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; 
}; 

型号:

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 
}; 

的 '主' 功能:

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(); 
} 

而且,最后的QML:

ApplicationWindow { 
    title: qsTr("Testing") 
    width: 640 
    height: 480 
    visible: true 

    ColumnLayout { 
     anchors.centerIn: parent 

     Rectangle { 
      width: 150 
      height: 25 
      color: "#e67e22" 
      border.width: 1 
      border.color: "black" 

      Text { 
       anchors.centerIn: parent 
       text: "Mark Special Item" 
      } 
      MouseArea { 
       anchors.fill: parent 
       onClicked: { 
        var item = myCppModel.specialItem() 
        console.debug("how to color the special item: " + item) 
       } 
      } 
     } 

     ListView { 
      id: itemList 
      width: 200 
      height: 25 * count 

      model: myCppModel.itemList 

      delegate: Item { 
       width: parent.width 
       height: 25 

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

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

你有什么试过?你的代码是什么样的(例如,包含'QQmlListProperty '的类)?我想到的答案很简单,所以我觉得我错过了有两个upvotes但没有答案的东西。 – Mitch

+0

@Mitch:我加了一些资料。这很可能是我错过了一些简单的东西 - 我是Qt/Qml的初学者。 – jco

+0

在QML创建模型('ListElement')的情况下,它就像在委托中调用'index'一样简单,但我不确定在公开外部模型时它是否工作相同 – Nadarian

回答

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" 
    } 
} 

这是最简单的方法,但污染MyItem的东西,你可能考虑更多的UI特定。

2.进行MyCppModelQAbstractItemModel

获得使用这个选项,你可以有一个SpecialItemrole是在委托可提供,委托各自相同选项1#QML代码。

我会称之为这个问题的规范方法,特别是如果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"