2017-06-27 2 views
2

Ich habe eine QML-ListView, die eine QAbstractListModel-Subklasse als Modell verwendet.Daten in einem QAbstractListModel aus einer QML-ListView bearbeiten

ListView { 
    id: myListView 
    x: 208 
    y: 19 
    width: 110 
    height: 160 
    delegate: myListDelegate {} 
    model: MyListModel 
    opacity: 0 
} 

Das Modell ist eine Liste von MyListItem s.

class MyListModel : public QAbstractListModel 
{ 
    Q_OBJECT 
public: 
    enum MyRoles { 
     HeadingRole = Qt::UserRole + 1, 
     DescriptionRole, 
     QuantityRole 
    }; 

    explicit MyListModel(QObject *parent = 0); 

    void addMyListItem(const MyListItem &item); 
    int rowCount(const QModelIndex & parent = QModelIndex()) const; 
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 
    void dropList(); 

private: 
    QList<MyListItem> m_list; 

}; 

Im Delegaten habe ich einen Mausbereich.

Wie ich einen Klick auf den mousearea abfangen und holen dassMyListItem von meinem QList Modell und es irgendwo im ++ Teil der Anwendung C schicken?

+0

haben Sie versucht, zu erstellen ein Mausbereich in Ihrem MyListItem oder überschreiben Sie die OnClick-Methode? –

+0

@GabrieldeGrimouard Ich beabsichtige das 'QList ' -Element, nicht 'myListItem' als ListView-Delegat – Zhigalin

+0

Sie können eine neue Rolle (' QAbstractItemModel :: roleNames') definieren, die das 'MyListItem' zurückgibt und es im' onClick'-Event verwendet beschrieben [hier] (http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html#qabstractitemmodel-subclass) – m7913d

Antwort

1

Die Kommentare erwähnen die Rückgabe eines Zeigers auf MyListItem von data() zu QML und Zugriff und Änderung in QML. Dies erfordert, dass Ihr MyListItem von QObject erbt und einen Q_PROPERTY für jedes Mitglied hinzufügt, auf das Sie in QML zugreifen möchten. Es erfordert auch, dass der Objektbesitz genau überwacht wird (QQmlEngine::ObjectOwnership).

Es gibt einen anderen Weg: Implementieren Sie QAbstractListModel::setData() und QAbstractListModel::roleNames(), und der Modellinhalt kann von QML, wie model.roleName = foo geändert werden.

Minimal Arbeitsbeispiel unten, die die Menge jedes Mal verdoppelt sich die Delegierten angeklickt wird:

C++:

struct MyListItem 
{ 
    QString heading; 
    QString description; 
    int quantity; 
}; 

class MyListModel : public QAbstractListModel 
{ 
    Q_OBJECT 
    Q_ENUMS(MyRoles) 
public: 
    enum MyRoles { 
     HeadingRole = Qt::UserRole + 1, 
     DescriptionRole, 
     QuantityRole 
    }; 

    using QAbstractListModel::QAbstractListModel; 

    QHash<int,QByteArray> roleNames() const override { 
     return { { HeadingRole, "heading" }, 
      { DescriptionRole, "description" }, 
      { QuantityRole, "quantity" }, 
     }; 
    } 
    int rowCount(const QModelIndex & parent = QModelIndex()) const override { 
     if (parent.isValid()) 
      return 0; 
     return m_list.size(); 
    } 

    bool setData(const QModelIndex &index, const QVariant &value, int role) override 
    { 
     if (!hasIndex(index.row(), index.column(), index.parent()) || !value.isValid()) 
      return false; 

     MyListItem &item = m_list[index.row()]; 
     if (role == DescriptionRole) item.description = value.toString(); 
     else if (role == HeadingRole) item.heading = value.toString(); 
     else if (role == QuantityRole) item.quantity = value.toInt(); 
     else return false; 

     emit dataChanged(index, index, { role }); 

     return true ; 

    } 

    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override { 
     if (!hasIndex(index.row(), index.column(), index.parent())) 
      return {}; 

     const MyListItem &item = m_list.at(index.row()); 
     if (role == DescriptionRole) return item.description; 
     if (role == HeadingRole) return item.heading; 
     if (role == QuantityRole) return item.quantity; 

     return {}; 
    } 

private: 
    QVector<MyListItem> m_list = { 
     { "heading 1", "description 1", 1 }, 
     { "heading 2", "description 2", 42 }, 
     { "heading 3", "description 3", 4711 } 
    }; 
}; 

QML:

ListView { 
    id: listView 
    anchors.fill: parent 
    model: MyListModel {} 

    delegate: Item { 
     implicitHeight: text.height 
     width: listView.width 
     Text { 
      id: text 
      text: model.heading + " " + model.description + " " + model.quantity 
     } 

     MouseArea { 
      anchors.fill: text 
      onClicked: { 
       model.quantity *= 2; 
      } 
     } 
    } 
} 
Verwandte Themen