Qt/QML如何从QAbstractListModel返回QList 来自虚拟数据metod的集合

问题描述:

我想总结要做什么。我有一个DataObject类有成员:Qt/QML如何从QAbstractListModel返回QList <T>来自虚拟数据metod的集合

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

我使用QAbstractListModel了这一点。我可以首先参考列表视图,但我不能参考像m_sublist[0].lesson。它给我的错误,如:

Cannot read property 'lesson' of undefined.

我的代码: 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" 
         } 
        } 
      } 
      } 
      } 


    } 

我无法找到任何解决方案。虚拟数据模型返回单一类型的对象。 FirsName是一个字符串。我不能参考像firstName(rolename)列表视图代表。另外LastName被引用为lastName(rolename)。但我不能指subList(roleNames)sublist[0].lesson

我的目标很简单。我想通过使用角色名称将单个类型(int,QString ....)引用到委托中的文本。我无法使用rolename(subList[0].lesson)将代收type(QList<SubObject*>)转发给代表中的文字。如何实现它们?

+0

如果'm_sublist'是'QList ',那你为什么要尝试像m_sublist [0] .lesson'而不是'm_sublist [0] - > lesson'那样访问它? –

+0

@SergeyTachenov,IN QML方面,你能编写像 - >符号的代码 –

+0

QML中有'DataObject'注册类型吗? – folibis

让我们一步步解决它。这在QML线text: subList[0].lesson产生错误信息

TypeError: Cannot read property 'lesson' of undefined

这意味着subList[0]是未定义对象和QML引擎无法读取任何属性,包括lesson,从该对象。实际上,从模型返回的subList是明确定义的QList<SubObject*>对象,但不是subList[0],因为QList<SubObject*>不是QML列表。要正确pass a list from C++ to QML,请返回QVariantList而不是QList

//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))); 
//... 

现在,subList[0]可以在QML访问,但是没有subList[0].lesson。到access properties in a C++ class,用宏Q_PROPERTY明确定义属性。

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

而QML代码现在工作。

+0

'QList '不是QML中的列表,而是'QList '。 – GrecKo