2016-06-10 26 views
1

zurückgeben Ich möchte zusammenfassen, was zu tun ist. Ich habe eine DataObject Klasse, die Mitglieder haben:Qt/QML Wie QList <T> Sammlung von virtuellen Daten Metode aus QAbstractListModel

QString first;QString last;QList<SubObject*> m_sublist; 

Ich verwende QAbstractListModel dazu. Ich kann zuerst und zuletzt auf listview beziehen, aber ich kann nicht auf m_sublist[0].lesson verweisen. Es gibt mir Fehler wie:

Cannot read property 'lesson' of undefined.

Mein Code: dataobject.h

 class SubObject :public QObject 
    { 
     Q_OBJECT 


    public: 
     SubObject(const QString &lesson,QObject *parent = 0); 
     const QString lesson; 

    private: 


    // bool operator==(const SubObject* &other) const { 
    //   return other->lesson == lesson; 
    // } 

    }; 

    class DataObject :public QObject{ 

     Q_OBJECT 
    public: 
    DataObject(const QString &firstName, 
       const QString &lastName, 
       const QList<SubObject*> &sublist); 


    QString first; 
    QString last; 
    QList<SubObject*> m_sublist; 
    }; 

simplelistmodel.h

class SimpleListModel : public QAbstractListModel { 
     Q_OBJECT 
    public: 
     SimpleListModel(QObject *parent=0); 
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; 
     int rowCount(const QModelIndex &parent = QModelIndex()) const; 
     QHash<int,QByteArray> roleNames() const { return m_roleNames; } 



    private: 
    // Q_DISABLE_COPY(SimpleListModel); 

     QList<DataObject*> m_items; 
     static const int FirstNameRole; 
     static const int LastNameRole; 
     static const int SubListRole; 
    QHash<int, QByteArray> m_roleNames; 
    }; 

simplelistmodel.cpp

 const int SimpleListModel::FirstNameRole = Qt::UserRole + 1; 
    const int SimpleListModel::LastNameRole = Qt::UserRole + 2; 
    const int SimpleListModel::SubListRole = Qt::UserRole + 3; 


    SimpleListModel::SimpleListModel(QObject *parent) : 
      QAbstractListModel(parent) { 
     // Create dummy data for the list 

     QList<SubObject*> mysublist; 
     mysublist.append(new SubObject("MAT")); 
     mysublist.append(new SubObject("FEN")); 


     DataObject *first = new DataObject(QString("Arthur"), QString("Dent"),mysublist); 
     DataObject *second = new DataObject(QString("Ford"), QString("Prefect"),mysublist); 
     DataObject *third = new DataObject(QString("Zaphod"), QString("Beeblebrox"),mysublist); 
     m_items.append(first); 
     m_items.append(second); 
     m_items.append(third); 



    // m_roleNames = SimpleListModel::roleNames(); 
    m_roleNames.insert(FirstNameRole, QByteArray("firstName")); 
    m_roleNames.insert(LastNameRole, QByteArray("lastName")); 
    m_roleNames.insert(SubListRole, QByteArray("subList")); 


    } 

    int SimpleListModel::rowCount(const QModelIndex &) const { 
    return m_items.size(); 
    } 

    QVariant SimpleListModel::data(const QModelIndex &index, 
               int role) const { 
     if (!index.isValid()) 
      return QVariant(); // Return Null variant if index is invalid 
     if (index.row() > (m_items.size()-1)) 
      return QVariant(); 

     DataObject *dobj = m_items.at(index.row()); 
     switch (role) { 
     case Qt::DisplayRole: // The default display role now displays the first name as well 
     case FirstNameRole: 
      return QVariant::fromValue(dobj->first); 
     case LastNameRole: 
      return QVariant::fromValue(dobj->last); 
     case SubListRole: 
      return QVariant::fromValue(dobj->m_sublist); 

     default: 
      return QVariant(); 
     } 
    } 

main.cpp

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

     QGuiApplication app(argc, argv); 

     QQmlApplicationEngine engine; 
     SimpleListModel model; 


     QQmlContext *classContext = engine.rootContext(); 
     classContext->setContextProperty("absmodel",&model); 

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

     return app.exec(); } 

myuiscript.qml

 import QtQuick 2.0 
    import QtQuick.Window 2.0 
    Window { 
     id: bgRect 
     width: 200 
     height: 200 
      color: "black" 
      visible: true 

      ListView { 
       id: myListView 
       anchors.fill: parent 
       delegate: myDelegate 
       model: absmodel 

      } 
      Component { 
    id: myDelegate 
      Item { 
    width: 200 
      height: 40 
      Rectangle { 
       anchors.fill: parent 
        anchors.margins: 2 
        radius: 5 
        color: "lightsteelblue" 
        Row { 
         anchors.verticalCenter: parent.verticalCenter 
          Text { 

    text: firstName 
      color: "black" 
      font.bold: true 
          } 
         Text { 
    text: subList[0].lesson 
      color: "black" 
         } 
        } 
      } 
      } 
      } 


    } 

ich keine Lösung finden können. Das virtuelle Datenmodell gibt einen einzelnen Objekttyp zurück. FirsName ist eine Zeichenfolge. Ich kann Listenansicht Delegat wie firstName(rolename) verweisen. Auch LastName wird wie lastName(rolename) verwiesen. Aber ich kann subList(roleNames) wie sublist[0].lesson nicht verweisen.

Mein Ziel ist sehr einfach. Ich möchte den einzelnen Typ (int,QString ....) auf Text in Delegaten verweisen, indem Sie Rolename verwenden. Ich kann die Sammlung type(QList<SubObject*>) nicht auf Text im Delegaten unter Verwendung von rolename(subList[0].lesson) verweisen. Wie erreiche ich sie?

+0

Wenn 'm_sublist' eine' QList 'ist, warum versuchen Sie dann darauf zuzugreifen wie' m_sublist [0] .lesson' und nicht 'm_sublist [0] -> lektion'? –

+0

@SergeyTachenov, IN QML-Seite, können Sie Code schreiben wie -> Notationen –

+0

Ist 'DataObject' in QML-Typ registriert? – folibis

Antwort

0

Lassen Sie uns es Schritt für Schritt beheben. Diese Linie text: subList[0].lesson in QML erzeugen die Fehlermeldung

TypeError: Cannot read property 'lesson' of undefined

Das bedeutet subList[0] ist ein undefiniertes Objekt und QML-Engine jede Eigenschaft nicht lesen können, einschließlich lesson, von diesem Objekt. In der Tat subList von Modell zurückgegeben ist ein wohldefiniertes QList<SubObject*> Objekt, aber nicht subList[0] seit QList<SubObject*> ist keine QML-Liste. Um pass a list from C++ to QML korrekt zurückzugeben, geben Sie anstelle von QList ein.

//class DataObject 
DataObject(const QString &firstName, 
      const QString &lastName, 
      const QVariantList &sublist); 
QVariantList m_sublist; //use QVariantList instead of QList<SubObject*> 

//--- 
//SimpleListModel::SimpleListModel 
QVariantList mysublist; //use QVariantList instead of QList<SubObject*> 
mysublist.append(QVariant::fromValue(new SubObject("MAT", this))); //remember parent 
mysublist.append(QVariant::fromValue(new SubObject("FEN", this))); 
//... 

Nun subList[0] kann in QML zugegriffen werden, aber nicht subList[0].lesson. Definieren Sie die access properties in a C++ class Eigenschaft explizit mit Q_PROPERTY Makro.

class SubObject :public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QString lesson READ getLesson NOTIFY lessonChanged) 

public: 
    SubObject(const QString &lesson,QObject *parent = 0): 
     QObject(parent), m_lesson(lesson){;} 
    QString getLesson() const {return m_lesson;} 

signals: 
    void lessonChanged(); 

private: 
    QString m_lesson; 
}; 

Und der QML-Code funktioniert jetzt.

+0

Eine 'QList ' ist keine Liste in QML, sondern eine 'QList ' ist. – GrecKo