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. Accessing QAbstractListModel's Data Through Properties In QML
Forum Updated to NodeBB v4.3 + New Features

Accessing QAbstractListModel's Data Through Properties In QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
7 Posts 3 Posters 2.4k 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.
  • Q Offline
    Q Offline
    qtyler
    wrote on last edited by
    #1

    I have a custom c++ class CustomListModel that extends QAbstractListModel. I am looking for a way to access data for an item in that model through properties in QML.

    In QML I have the following:

    CustomListModel { //Contains people information
      id: customDataModel
    }
    
    Text {
      id: nameLabel
    }
    

    To set the label's text to the first person in the CustomListModel, I could do something like the following which uses the "data" method of CustomListModel requiring specifying the index and role:

    Button {
      id: personOneButton
      text: "Show Person One"
    
      onClicked: {
         var sourceIndex = customDataModel.index(0,0)
         nameLabel.text = customDataModel.data(sourceIndex,  customDataModel.roleName("name"))
      }
    }
    

    Instead I would like to bind the label text to a specific item in the CustomListModel. The following is an example of a simpler interface I'd like to have.

    function getDataItem(){ //todo }
    property var currentDataItem //object of unknown type acting as proxy to a item in the model
    
    Button {
    id: personOneButton
    text: "Show Person One"
      onClicked: {
        var sourceIndex =  customDataModel.index(0,0)
        currentDataItem = getDataItem(customDataModel, sourceIndex)
      }
    }
    
    Text {
      id: nameLabel
      text: currentDataItem.name //the target interface to achieve
    }
    

    Is there any existing functionality in Qt that has the functionality of this "currentDataItem"? Or some other mechanism for binding to an item's roles.

    The only existing functionality I'm aware of that makes these role properties available is when using a GridView's delegate https://doc.qt.io/qt-5/qml-qtquick-gridview.html#delegate-prop. Within that GridView's delegate there is a "model" property of type "QQmlDMAbstractItemModelData” which allows for reading and writing to a role with the syntax "model.name".

    1 Reply Last reply
    0
    • GabrielRRG Offline
      GabrielRRG Offline
      GabrielRR
      wrote on last edited by
      #2

      Hello,

      I think you may use a .json file to get the properties from the model or a listView and assign the model to the listView.

      Lic-Ing. Jose Gabriel Lopez Villalobos
      Embedded Software Engineer
      RidgeRun Engineering Ltd.
      www.ridgerun.com
      Email: gabriel.lopez@ridgerun.com

      1 Reply Last reply
      0
      • fcarneyF Offline
        fcarneyF Offline
        fcarney
        wrote on last edited by
        #3

        You use a view of the needed type. Then the items exposed by the different roles are available to delegates. You use a redefined data/setData to read the write to those roles. Search for QML model view objects available to QML.

        C++ is a perfectly valid school of magic.

        1 Reply Last reply
        0
        • Q Offline
          Q Offline
          qtyler
          wrote on last edited by qtyler
          #4

          Is there a QML view object that can be used for showing detailed information of a single item within a model? The only views I'm aware of are GridView, ListView, TableView, and PathView. These seem to be primary for visualizing the entire set or subset of the items in a model.

          The high level problem I'm trying to address is the following:
          I have a source model(QAbstractListModel), a filter model(QSortFilterProxyModel) used to show only items matching a criteria, and a gridview and listview for displaying a list of items in the filter model. When an item in the gridview/listview is clicked on, the delegate's "model" property for that gridview item is being passed to another qml item that is used for displaying detailed information and editing that item's data in the model. The problem is that if that gridview item is filtered out while displaying/using the delegate's property, the property is destroyed in the detail information qml item even though the item still exists in the source model. Is there another way do this or best practice to display/edit a single item within a source model?

          Ideally, I would like to just create a delegate to an item in a model without having to use a view. Is that possible?

          fcarneyF 1 Reply Last reply
          0
          • Q qtyler

            Is there a QML view object that can be used for showing detailed information of a single item within a model? The only views I'm aware of are GridView, ListView, TableView, and PathView. These seem to be primary for visualizing the entire set or subset of the items in a model.

            The high level problem I'm trying to address is the following:
            I have a source model(QAbstractListModel), a filter model(QSortFilterProxyModel) used to show only items matching a criteria, and a gridview and listview for displaying a list of items in the filter model. When an item in the gridview/listview is clicked on, the delegate's "model" property for that gridview item is being passed to another qml item that is used for displaying detailed information and editing that item's data in the model. The problem is that if that gridview item is filtered out while displaying/using the delegate's property, the property is destroyed in the detail information qml item even though the item still exists in the source model. Is there another way do this or best practice to display/edit a single item within a source model?

            Ideally, I would like to just create a delegate to an item in a model without having to use a view. Is that possible?

            fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by
            #5

            @qtyler
            You might be able to do something like that with an Instantiator. The problem is it doesn't seem to have a concept of a currentItem like a ListView does. Maybe a visible and separate ListView that only shows the item pointed by its current index.

            C++ is a perfectly valid school of magic.

            1 Reply Last reply
            0
            • Q Offline
              Q Offline
              qtyler
              wrote on last edited by
              #6

              I'm not sure how I would use an Instanitator. My guess is that if I created an Instanitator tied to a source model, it would then create a delegate for every item in the model. I don't know if it would be possible to have it create only one delegate for one item in the model or if the object returned by objectAt would provide property bindings to all of the roles for an item in the model.

              A second listview with only one item visible at a time might work but might be inefficient.

              Could the DelegateModel type be used in some way to get an object with property bindings to an item in a model without using a view?

              1 Reply Last reply
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on last edited by
                #7

                @qtyler said in Accessing QAbstractListModel's Data Through Properties In QML:

                Could the DelegateModel type be used in some way to get an object with property bindings to an item in a model without using a view?

                It might. You can specify the index for the item, but I am not sure if it would look for children of the index or not. So it might not work as expected.

                How big is your list? Can you filter it to a sublist? If you try the ListView route you could track what it accesses out of the data() function by printing something to console. You could also delay load things using a loader keyed off selection criteria. Not sure how well it would see the roles from the model. Might be tricky.

                C++ is a perfectly valid school of magic.

                1 Reply Last reply
                0

                • Login

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