Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QVariantMap in a QAbstractListModel and C++/QML
Forum Updated to NodeBB v4.3 + New Features

QVariantMap in a QAbstractListModel and C++/QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
5 Posts 4 Posters 1.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    arctik
    wrote on last edited by arctik
    #1

    hello, I'm using a QAbstractListModel that contains a QVariantMap (m_map)

    class CItem
    {
    public:
        CItem(const QString &name, const QString &url);
    
        QString name() const;
        QString url() const;
        QVariantMap map() const;
    
        void setName(const QString& name);
        void setUrl(const QString& url);
        void setMap(const QVariantMap& map);
    
    private:
        QString m_name;
        QString m_url;
        QVariantMap m_map;
    };
    
    class CItemModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        enum ItemRoles {
            NameRole = Qt::UserRole + 1,
            UrlRole,
            MapRole
        };
    
        CItemModel(QObject *parent = 0);
    
        void addItem(const CItem &CItem);
        int rowCount(const QModelIndex & parent = QModelIndex()) const;
        QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
        bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
    
    
    
    protected:
        QHash<int, QByteArray> roleNames() const;
    private:
        QList<CItem> m_Items;
    
    signals:
    
    };
    

    and I want to visualize and modify all the datas QML like that:

        ListView {
            id: listView
            model : itemModel
            delegate:
                ItemDelegate {
                    id: root
                    contentItem: ColumnLayout {
                        RowLayout {
                            id: rowLayout
                            ColumnLayout {
                                id: columnLayout
                                Label {
                                    id: text1
                                    text: model.name
                                }
                                Label {
                                    id: text2
                                    text: model.url
                                }
                                Label {
                                    id: text3
                                    text: model.map["test1"] // it works
                                }
    
                               // did not work
                               Repeater{
                                    model: map
                                   Text { text: model.map["test1"]}
                                }
    
    

    no problem with model.name and model.url. (text3 is ok too) but I cant' display all data of my qVariantMap and modify it
    is it possible? can you explain me the best approach, please ?

    1 Reply Last reply
    0
    • oria66O Offline
      oria66O Offline
      oria66
      wrote on last edited by
      #2

      @arctik Hi. The first I notice is that the Repeater does not work with Javascript Objects (Conversion of QVariantMap from C++ side to QML side). Repeater component works with ListModels.

      So, maybe there is a better approach, but one way is:

      1. Declare an empty LisModel in your qml file.
      2. Load or your QVariantMap (JS Object) into ListModel created for that purpose. Automatically, your repeater is going to load the data.
      3. In order to modify your QVariantMap, any changes that you do in the ListModel, you are going to call a function that will load data from the ListModel to QVariantMap property from your original model again.

      Seems complex and some kind tricky but you can test it.

      The truth is out there

      1 Reply Last reply
      0
      • jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by
        #3

        I suspect the problem is that an object isn't one of the options for a Repeater model.

        https://doc.qt.io/qt-6/qml-qtquick-repeater.html#model-prop

        This property can be set to any of the supported data models:

        • A number that indicates the number of delegates to be created by the repeater
        • A model (e.g. a ListModel item, or a QAbstractItemModel subclass)
        • A string list
        • An object list

        Using object.keys() or object.values() to create a string list might work.

        Asking a question about code? http://eel.is/iso-c++/testcase/

        A 1 Reply Last reply
        0
        • jeremy_kJ jeremy_k

          I suspect the problem is that an object isn't one of the options for a Repeater model.

          https://doc.qt.io/qt-6/qml-qtquick-repeater.html#model-prop

          This property can be set to any of the supported data models:

          • A number that indicates the number of delegates to be created by the repeater
          • A model (e.g. a ListModel item, or a QAbstractItemModel subclass)
          • A string list
          • An object list

          Using object.keys() or object.values() to create a string list might work.

          A Offline
          A Offline
          arctik
          wrote on last edited by arctik
          #4

          @jeremy_k @oria66 Thanks for your answers, i am looking to go in this direction. one more question: if I change the QVariantMap to a QlistModel, will it be easier? what I don't understand is how to handle nested lists in lists with C ++ / Qml. it is however a case which must happen often, or I miss a point ?

          something like qobjectlist-based-model to replace my QVariantMap,
          https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html#qobjectlist-based-model

          if it is possible, do i have to do just one setContextProperty() for my CItemModel or do I have to do it for all nested classes ?
          thank you very much for your help

          GrecKoG 1 Reply Last reply
          0
          • A arctik

            @jeremy_k @oria66 Thanks for your answers, i am looking to go in this direction. one more question: if I change the QVariantMap to a QlistModel, will it be easier? what I don't understand is how to handle nested lists in lists with C ++ / Qml. it is however a case which must happen often, or I miss a point ?

            something like qobjectlist-based-model to replace my QVariantMap,
            https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html#qobjectlist-based-model

            if it is possible, do i have to do just one setContextProperty() for my CItemModel or do I have to do it for all nested classes ?
            thank you very much for your help

            GrecKoG Offline
            GrecKoG Offline
            GrecKo
            Qt Champions 2018
            wrote on last edited by
            #5

            @arctik There's nothing specific or blocking about nested models in C++ or QML. Just return a model for one of the role of your outer model.

            1 Reply Last reply
            2

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved