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. ListModel needs data from other model
Forum Updated to NodeBB v4.3 + New Features

ListModel needs data from other model

Scheduled Pinned Locked Moved Solved QML and Qt Quick
9 Posts 3 Posters 671 Views 2 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #1

    Hi all -

    I have a screen with a GridView that displays summaries of equipment items. When one of the items is clicked, I open a detail drawer. The drawer needs information about the selected (clicked) item.

    // EquipmentScreen.qml
    GridView {
        model: equipmentModel // from C++
            EquipmentCard {
                id: card
                name: model.name
                imageURI: "qrc:/icons/VariableSpeed.svg"
                uuid: model.uuid
                onCardClicked: {
                                   drawer.open()
                                   drawerStack.push("EquipmentDetail.qml")
                               }
    
    // EquipmentDetail.qml
    RowLayout {
        ListModel {
            id: clickables
            ListElement { name: "Name should go here"; image: "" } // what to do here?
            ListElement { name: "Diagnostics"; image: "" }
            ListElement { name: "Operations"; image: "" }
            ListElement { name: "Settings"; image: "" }
            ListElement { name: "Zones"; image: "" }
        }
    
        ListView {
            model: clickables
            delegate: Rectangle {
                Text {
                    text: model.name
                }
    

    Can I somehow "inject" this drawer with information from the GridView item? And if not, how do I derive this information from within the drawer?

    Thanks...

    1 Reply Last reply
    0
    • mzimmersM mzimmers

      @JoeCFD in my EquipmentModel class, I have this:

          Q_INVOKABLE EquipmentItem getItem(int index) { return m_list->getItem(index); }
      

      And my EquipmentItem class has this:

          Q_PROPERTY(QString name MEMBER m_name)
      

      So I think I have my C++ covered. And I can get the name in QML using:

      property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
      

      So, now how do I use that in my model? I tried this:

      ListModel {
          id: clickables
          property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
          ListElement { name: equipmentItem; color: "blue" }
      

      But I get this error:

      ListElement: cannot use script for property value
      

      Thanks...

      JoeCFDJ Offline
      JoeCFDJ Offline
      JoeCFD
      wrote on last edited by JoeCFD
      #8

      @mzimmers said in ListModel needs data from other model:

      ListElement: cannot use script for property value

      something like this?

      Component.onCompleted: { /*<====  can be a slot */
          clickables.get(0).name = equipmentModel.getItem(equipmentModel.index().name()); or
         clickables.get( index ).name = equipmentModel.getItem(equipmentModel.index().name());
      }
      
      mzimmersM 1 Reply Last reply
      1
      • jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by jeremy_k
        #2

        Populating the temporary ListModel when a cell from the GridView is clicked is a waste of memory and compute time.

        • Put all of the data in equipmentModel.
        • Remove the clickables ListModel, and use equipmentModel for both the ListView as well as the GridView.
        • Bind the ListView's currentIndex to the GridView's current index.
        • Size the ListView delegate to fit the view, and disable flicking.

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

        mzimmersM 1 Reply Last reply
        0
        • jeremy_kJ jeremy_k

          Populating the temporary ListModel when a cell from the GridView is clicked is a waste of memory and compute time.

          • Put all of the data in equipmentModel.
          • Remove the clickables ListModel, and use equipmentModel for both the ListView as well as the GridView.
          • Bind the ListView's currentIndex to the GridView's current index.
          • Size the ListView delegate to fit the view, and disable flicking.
          mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by
          #3

          @jeremy_k the clickables model is something I put together to use for creating a series of buttons in the left column of EquipmentDetail, so I don't think I can get rid of it completely.

          I like your idea of using the original equipmentModel, though I'm not sure how to access information about an individual item (just one item) from the model, which uses a list as its basis. Is it going to look something like (pseudocode here):

          equipmentModel.getItem(equipmentModel.index).name()
          

          I know this isn't right, but am I on the right track?

          Thanks...

          jeremy_kJ 1 Reply Last reply
          0
          • mzimmersM mzimmers

            @jeremy_k the clickables model is something I put together to use for creating a series of buttons in the left column of EquipmentDetail, so I don't think I can get rid of it completely.

            I like your idea of using the original equipmentModel, though I'm not sure how to access information about an individual item (just one item) from the model, which uses a list as its basis. Is it going to look something like (pseudocode here):

            equipmentModel.getItem(equipmentModel.index).name()
            

            I know this isn't right, but am I on the right track?

            Thanks...

            jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on last edited by
            #4

            @mzimmers said in ListModel needs data from other model:

            @jeremy_k the clickables model is something I put together to use for creating a series of buttons in the left column of EquipmentDetail, so I don't think I can get rid of it completely.

            Unless the model is an ObjectModel, it should not contain buttons or visual items of any sort. It may contain the data used to populate a view with buttons, but where does that data come from? If the answer is some mutation of data from the other model, take the data from the model and mutate in the view delegate.

            I like your idea of using the original equipmentModel, though I'm not sure how to access information about an individual item (just one item) from the model,

            Access works the same as with any other view.

            GridView {
                id: gv
                model: equipmentModel
                delegate: Text { text: model.name }
            }
            ListView {
                interactive: false
                model: equipmentModel
                currentIndex: gv.currentIndex
                delegate: Text {
                    width: ListView.view.width
                    height: ListView.view.height
                    text: "The current item is " + model.name
                    Button { text: model.buttonName; onClicked: Qt.quit() }
                }
            }
            
            equipmentModel.getItem(equipmentModel.index).name()
            

            Is name accessible as a role in equipmentModel? If it is displayed in the context of something that acts like a view, it should be.

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

            mzimmersM 1 Reply Last reply
            1
            • jeremy_kJ jeremy_k

              @mzimmers said in ListModel needs data from other model:

              @jeremy_k the clickables model is something I put together to use for creating a series of buttons in the left column of EquipmentDetail, so I don't think I can get rid of it completely.

              Unless the model is an ObjectModel, it should not contain buttons or visual items of any sort. It may contain the data used to populate a view with buttons, but where does that data come from? If the answer is some mutation of data from the other model, take the data from the model and mutate in the view delegate.

              I like your idea of using the original equipmentModel, though I'm not sure how to access information about an individual item (just one item) from the model,

              Access works the same as with any other view.

              GridView {
                  id: gv
                  model: equipmentModel
                  delegate: Text { text: model.name }
              }
              ListView {
                  interactive: false
                  model: equipmentModel
                  currentIndex: gv.currentIndex
                  delegate: Text {
                      width: ListView.view.width
                      height: ListView.view.height
                      text: "The current item is " + model.name
                      Button { text: model.buttonName; onClicked: Qt.quit() }
                  }
              }
              
              equipmentModel.getItem(equipmentModel.index).name()
              

              Is name accessible as a role in equipmentModel? If it is displayed in the context of something that acts like a view, it should be.

              mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by
              #5

              @jeremy_k the model doesn't contain buttons; just the text for the buttons. (This might be overkill, but the problem remains.)

              The first button is kind of a special case in that it should contain information about the individual item in the model. Eventually I'll need other information from the model as well.

              So here's what I tried:

              ListModel {
                  id: clickables
                  ListElement { name: equipmentModel.getItem(equipmentModel.index().name()); color: "blue" }
                  ListElement { name: "Diagnostics"; color: "green" }
                  ListElement { name: "Operations"; color: "purple" }
                  ListElement { name: "Settings"; color: "yellow" }
                  ListElement { name: "Zones"; color: "black" }
              }
              

              At runtime I get an error:

              qrc:/qt/qml/nga_demo/EquipmentDetail.qml:27 ListElement: cannot use script for property value
              
              JoeCFDJ 1 Reply Last reply
              0
              • mzimmersM mzimmers

                @jeremy_k the model doesn't contain buttons; just the text for the buttons. (This might be overkill, but the problem remains.)

                The first button is kind of a special case in that it should contain information about the individual item in the model. Eventually I'll need other information from the model as well.

                So here's what I tried:

                ListModel {
                    id: clickables
                    ListElement { name: equipmentModel.getItem(equipmentModel.index().name()); color: "blue" }
                    ListElement { name: "Diagnostics"; color: "green" }
                    ListElement { name: "Operations"; color: "purple" }
                    ListElement { name: "Settings"; color: "yellow" }
                    ListElement { name: "Zones"; color: "black" }
                }
                

                At runtime I get an error:

                qrc:/qt/qml/nga_demo/EquipmentDetail.qml:27 ListElement: cannot use script for property value
                
                JoeCFDJ Offline
                JoeCFDJ Offline
                JoeCFD
                wrote on last edited by
                #6

                @mzimmers I guess you may need something like:

                equipmentModel.getIndexItem( index )
                

                and

                equipmentModel.getItem(equipmentModel.index().name())
                

                is better done inside equipmentModel

                mzimmersM 1 Reply Last reply
                0
                • JoeCFDJ JoeCFD

                  @mzimmers I guess you may need something like:

                  equipmentModel.getIndexItem( index )
                  

                  and

                  equipmentModel.getItem(equipmentModel.index().name())
                  

                  is better done inside equipmentModel

                  mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by mzimmers
                  #7

                  @JoeCFD in my EquipmentModel class, I have this:

                      Q_INVOKABLE EquipmentItem getItem(int index) { return m_list->getItem(index); }
                  

                  And my EquipmentItem class has this:

                      Q_PROPERTY(QString name MEMBER m_name)
                  

                  So I think I have my C++ covered. And I can get the name in QML using:

                  property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
                  

                  So, now how do I use that in my model? I tried this:

                  ListModel {
                      id: clickables
                      property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
                      ListElement { name: equipmentItem; color: "blue" }
                  

                  But I get this error:

                  ListElement: cannot use script for property value
                  

                  Thanks...

                  JoeCFDJ 1 Reply Last reply
                  0
                  • mzimmersM mzimmers

                    @JoeCFD in my EquipmentModel class, I have this:

                        Q_INVOKABLE EquipmentItem getItem(int index) { return m_list->getItem(index); }
                    

                    And my EquipmentItem class has this:

                        Q_PROPERTY(QString name MEMBER m_name)
                    

                    So I think I have my C++ covered. And I can get the name in QML using:

                    property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
                    

                    So, now how do I use that in my model? I tried this:

                    ListModel {
                        id: clickables
                        property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
                        ListElement { name: equipmentItem; color: "blue" }
                    

                    But I get this error:

                    ListElement: cannot use script for property value
                    

                    Thanks...

                    JoeCFDJ Offline
                    JoeCFDJ Offline
                    JoeCFD
                    wrote on last edited by JoeCFD
                    #8

                    @mzimmers said in ListModel needs data from other model:

                    ListElement: cannot use script for property value

                    something like this?

                    Component.onCompleted: { /*<====  can be a slot */
                        clickables.get(0).name = equipmentModel.getItem(equipmentModel.index().name()); or
                       clickables.get( index ).name = equipmentModel.getItem(equipmentModel.index().name());
                    }
                    
                    mzimmersM 1 Reply Last reply
                    1
                    • JoeCFDJ JoeCFD

                      @mzimmers said in ListModel needs data from other model:

                      ListElement: cannot use script for property value

                      something like this?

                      Component.onCompleted: { /*<====  can be a slot */
                          clickables.get(0).name = equipmentModel.getItem(equipmentModel.index().name()); or
                         clickables.get( index ).name = equipmentModel.getItem(equipmentModel.index().name());
                      }
                      
                      mzimmersM Offline
                      mzimmersM Offline
                      mzimmers
                      wrote on last edited by
                      #9

                      @JoeCFD that works! I introduced an intermediate variable for clarity:

                      ColumnLayout {
                          property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
                          Component.onCompleted: clickables.get(0).name = equipmentItem
                          ListModel {
                              id: clickables
                              Component.onCompleted: console.log("equipmentItem is " + equipmentItem)
                              ListElement { name: "TO BE FILLED IN AT RUNTIME"; color: "blue" }
                          ...
                      

                      This is functional, though I get the impression from @jeremy_k's comments that it might not be the desired way to go about this.

                      1 Reply Last reply
                      0
                      • mzimmersM mzimmers has marked this topic as solved on

                      • Login

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