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. Chosing `contentItem` on condition
Forum Updated to NodeBB v4.3 + New Features

Chosing `contentItem` on condition

Scheduled Pinned Locked Moved Solved QML and Qt Quick
9 Posts 2 Posters 1.4k 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.
  • M Offline
    M Offline
    mleoni
    wrote on last edited by
    #1

    Hello everyone,
    I just learnt how to load a component from an external QML file, now I would like to be able to dynamically decide which to load among a few options.

    Let's say I have files

    // BuysItem.qml
    Rectangle
    {...}
    

    and

    // EmployeeItem.qml
    Rectangle
    {...}
    

    Now if I do

    ListView {
        delegate: ItemDelegate {
            contentItem: BuysItem {}
        }
    }
    

    or

    ListView {
        delegate: ItemDelegate {
            contentItem: EmployeeItem {}
        }
    

    I see the correct item, but now I want to be able to choose which one to use based on the value of some other variable.
    I have tried

    ListView {
        delegate: ItemDelegate {
            contentItem: projList.currentType == "Buys" ? BuysItem {} : EmployeeItem {}
        }
    

    which gives Syntax error, and

    ListView {
        delegate: ItemDelegate {
            function getContentItem()
            {
                if(projList.currentType == "Buys")
                {
                    return BuysItem {}
                }
                if(projList.currentType == "Employee")
                {
                    return EmployeeItem {}
                }
            }
            contentItem: getContentItem()
        }
    

    which gives Expected token ';' on the return statements.

    I think it's a syntax error, what is the correct way to do this?

    Also, where can I learn this stuff [syntax and the like] so that I don't have to ask here ever two lines of code I write?

    Thanks!

    raven-worxR 1 Reply Last reply
    0
    • M mleoni

      Hello everyone,
      I just learnt how to load a component from an external QML file, now I would like to be able to dynamically decide which to load among a few options.

      Let's say I have files

      // BuysItem.qml
      Rectangle
      {...}
      

      and

      // EmployeeItem.qml
      Rectangle
      {...}
      

      Now if I do

      ListView {
          delegate: ItemDelegate {
              contentItem: BuysItem {}
          }
      }
      

      or

      ListView {
          delegate: ItemDelegate {
              contentItem: EmployeeItem {}
          }
      

      I see the correct item, but now I want to be able to choose which one to use based on the value of some other variable.
      I have tried

      ListView {
          delegate: ItemDelegate {
              contentItem: projList.currentType == "Buys" ? BuysItem {} : EmployeeItem {}
          }
      

      which gives Syntax error, and

      ListView {
          delegate: ItemDelegate {
              function getContentItem()
              {
                  if(projList.currentType == "Buys")
                  {
                      return BuysItem {}
                  }
                  if(projList.currentType == "Employee")
                  {
                      return EmployeeItem {}
                  }
              }
              contentItem: getContentItem()
          }
      

      which gives Expected token ';' on the return statements.

      I think it's a syntax error, what is the correct way to do this?

      Also, where can I learn this stuff [syntax and the like] so that I don't have to ask here ever two lines of code I write?

      Thanks!

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @mleoni

      Component {
          id: buysItem
          BuysItem {}
      }
      
      Component {
           id: employeeItem
           EmployeeItem {}
      }
      
      ListView {
          delegate: ItemDelegate {
              id: delegate
              contentItem: {
                     switch( projList.currentType ) {
                            case "Buys":   return buysItem.createObject(delegate);
                            case "Employee": return employeeItem.createObject(delegate);
                     }
              }
          }
      }
      

      or alternatively:

      ListView {
          delegate: ItemDelegate {
              contentItem: Loader {
                     sourceComponent: {
                         switch( projList.currentType ) {
                             case "Buys":   return "qrc:/qml/BuysItem.qml"
                             case "Employee": return "qrc:/qml/EmployeeItem.qml"
                         }
                   }
              }
          }
      }
      

      (untested)

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      2
      • M Offline
        M Offline
        mleoni
        wrote on last edited by
        #3

        Hi, thanks for your help!
        I tried both your solutions, with the first one I get a ReferenceError: model is not defined inside the external component, at the lines where I access the data in the ListView model.
        The second one complains saying Unable to assign QString to QQmlComponent*, presumably on the return statement inside the switch.

        raven-worxR 1 Reply Last reply
        0
        • M mleoni

          Hi, thanks for your help!
          I tried both your solutions, with the first one I get a ReferenceError: model is not defined inside the external component, at the lines where I access the data in the ListView model.
          The second one complains saying Unable to assign QString to QQmlComponent*, presumably on the return statement inside the switch.

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @mleoni said in Chosing `contentItem` on condition:

          with the first one I get a ReferenceError: model is not defined inside the external component, at the lines where I access the data in the ListView model.

          there is no appearance of "model" in my code. So that one comes from your code.
          But why do you need to access the model directly?! Your model should expose its data via roles (see QAbstractItemModel::roleNames())

          @mleoni said in Chosing `contentItem` on condition:

          The second one complains saying Unable to assign QString to QQmlComponent*, presumably on the return statement inside the switch.

          my fault. change sourceComponent to source

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          M 1 Reply Last reply
          0
          • raven-worxR raven-worx

            @mleoni said in Chosing `contentItem` on condition:

            with the first one I get a ReferenceError: model is not defined inside the external component, at the lines where I access the data in the ListView model.

            there is no appearance of "model" in my code. So that one comes from your code.
            But why do you need to access the model directly?! Your model should expose its data via roles (see QAbstractItemModel::roleNames())

            @mleoni said in Chosing `contentItem` on condition:

            The second one complains saying Unable to assign QString to QQmlComponent*, presumably on the return statement inside the switch.

            my fault. change sourceComponent to source

            M Offline
            M Offline
            mleoni
            wrote on last edited by
            #5

            @raven-worx said in Chosing `contentItem` on condition:

            my fault. change sourceComponent to source

            Ok, now it works better!

            @raven-worx said in Chosing `contentItem` on condition:

            there is no appearance of "model" in my code. So that one comes from your code.
            But why do you need to access the model directly?! Your model should expose its data via roles (see QAbstractItemModel::roleNames())

            It's true. My components look like this.

            Rectangle
            {
                Text
                {
                    text: model.date
                }
            }
            

            where model is the model defined in the ListView and date is a role that I defined in the C++ implementation where I override the function that you mentioned.

            In particular, in the C++ code I inherit QAbstractListModel and reimplement rowCount, roleNames and data, then instantiate it and use engine.rootContext()->setContextProperty to expose it to QML, where I use the instance as a model, and then access, for example, model.date where date was defined in roleNames. Is this a bad approach? Can you suggest any better one?

            raven-worxR 1 Reply Last reply
            0
            • M mleoni

              @raven-worx said in Chosing `contentItem` on condition:

              my fault. change sourceComponent to source

              Ok, now it works better!

              @raven-worx said in Chosing `contentItem` on condition:

              there is no appearance of "model" in my code. So that one comes from your code.
              But why do you need to access the model directly?! Your model should expose its data via roles (see QAbstractItemModel::roleNames())

              It's true. My components look like this.

              Rectangle
              {
                  Text
                  {
                      text: model.date
                  }
              }
              

              where model is the model defined in the ListView and date is a role that I defined in the C++ implementation where I override the function that you mentioned.

              In particular, in the C++ code I inherit QAbstractListModel and reimplement rowCount, roleNames and data, then instantiate it and use engine.rootContext()->setContextProperty to expose it to QML, where I use the instance as a model, and then access, for example, model.date where date was defined in roleNames. Is this a bad approach? Can you suggest any better one?

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by raven-worx
              #6

              @mleoni said in Chosing `contentItem` on condition:

              text: model.date

              since you already implemented roleNames() in your model, simply use text: date instead of text: model.date
              Each delegate instance then has the value for the corresponding index set in the variable with the name from roleNames()

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mleoni
                wrote on last edited by mleoni
                #7

                If I take out model I get ReferenceError: date is not defined.

                Meanwhile, the second solution seems to work well so let me thank you for that at least!

                raven-worxR 1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mleoni
                  wrote on last edited by mleoni
                  #8

                  While we are at it, can you point me to any reference to learn about stuff of the same level as the one you just taught me?

                  1 Reply Last reply
                  0
                  • M mleoni

                    If I take out model I get ReferenceError: date is not defined.

                    Meanwhile, the second solution seems to work well so let me thank you for that at least!

                    raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #9

                    @mleoni said in Chosing `contentItem` on condition:

                    If I take out model I get ReferenceError: date is not defined.

                    maybe only the delegate component gets the data set, i don't know now, it may be.
                    So try to forward it from the root delegate item to your child items

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    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