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. How to create n Objects dynamically to populate StackView
Forum Updated to NodeBB v4.3 + New Features

How to create n Objects dynamically to populate StackView

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
25 Posts 3 Posters 3.6k 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.
  • S Offline
    S Offline
    sandro4912
    wrote on last edited by
    #9

    I remembered I had this index issue before and asked it on stack overflow:
    https://stackoverflow.com/questions/62484078/required-property-not-working-with-repeater

    So solution is in QuizPage add:

    required property int index
    

    Than index can be accessed. Weired but thats the way.

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

      What does your repeater code look like?
      It cannot inject a property into an object. It has to be set inside the repeater statement.

      C++ is a perfectly valid school of magic.

      1 Reply Last reply
      1
      • S Offline
        S Offline
        sandro4912
        wrote on last edited by sandro4912
        #11

        Repeater code is like you suggested:

        SwipeView{
               id: quizSwipeView
               interactive: false
               anchors.fill: parent
        
               Repeater{
                   model: randomQuestions
                   delegate: QuizPage{
                       question: randomQuestions[index]
                   }
               }
           }
        
        Item{
            id: root
        
            required property var question
            required property int index
        //....
        }
        

        If I drop the required in question i can skip defining the index it is very weired behaviour.

        See also here: https://stackoverflow.com/questions/62484078/required-property-not-working-with-repeater

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

          @sandro4912 said in How to create n Objects dynamically to populate StackView:

          Item{
          id: root

          required property var question
          required property int index
          

          //....
          }

          What is the reason for this property index inside your object? This doesn't make sense if you are using "question" as your property.

          C++ is a perfectly valid school of magic.

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

            @sandro4912 said in How to create n Objects dynamically to populate StackView:

            Repeater{
            model: randomQuestions
            delegate: QuizPage{
            question: randomQuestions[index]
            }
            }

            What does this do?

            Repeater{
                       model: randomQuestions
                       delegate: Item{
                          Component.onCompleted: {
                            console.log(index)
                          }
                       }
                   }
            

            This "should" print out the index for each entry in randomQuestions. If it doesn't then you need a data model Repeater can use.

            C++ is a perfectly valid school of magic.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              sandro4912
              wrote on last edited by
              #14

              this

                      Repeater{
                         model: randomQuestions
                         delegate: Item{
                            Component.onCompleted: {
                              console.log(index)
                            }
                         }
                     }
              

              gives:

              qml: 0
              qml: 1
              qml: 2
              qml: 3
              qml: 4
              qml: 5
              qml: 6
              qml: 7
              qml: 8
              qml: 9
              

              Even without the added index property.

              But if I do:

              Repeater{
                       model: randomQuestions
                       delegate: QuizPage{
                           question: randomQuestions[index]
                       }
                   }
              

              It only works with adding into QuizPage:

              required property int index
              

              Otherwise:

              qrc:/qml/quiz/QuizPage.qml:52: TypeError: Cannot read property 'id' of undefined
              qrc:/qml/quiz/QuizPage.qml:57: TypeError: Cannot read property 'askedQuestion' of undefined
              qrc:/qml/quiz/QuizPage.qml:64: TypeError: Cannot read property 'picture' of undefined
              qrc:/qml/quiz/Quiz.qml:0: ReferenceError: index is not defined
              
              1 Reply Last reply
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on last edited by
                #15

                @sandro4912 said in How to create n Objects dynamically to populate StackView:

                required property int index

                Why are you doing this? This makes zero sense to create a require property when all your info is in your question property.

                C++ is a perfectly valid school of magic.

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

                  @sandro4912 said in How to create n Objects dynamically to populate StackView:

                  question.answer1

                  Also, for every usage of question inside of QuizPage do this:
                  Change this:
                  question.answer1
                  To this:
                  root.question.answer1

                  I think you may be having scoping issues with the question property.

                  C++ is a perfectly valid school of magic.

                  1 Reply Last reply
                  0
                  • fcarneyF fcarney

                    @sandro4912 said in How to create n Objects dynamically to populate StackView:

                    required property int index

                    Why are you doing this? This makes zero sense to create a require property when all your info is in your question property.

                    S Offline
                    S Offline
                    sandro4912
                    wrote on last edited by
                    #17

                    @fcarney

                    check out this:

                    https://stackoverflow.com/questions/62484078/required-property-not-working-with-repeater

                    The issue is if you have a required property in an item you put into an repeater it only gets access to the index in the weired way that you add an index as required property. I also don't understand why it is necessary.

                    You can try it out by copy the project on git hub and remove the line index:
                    https://github.com/SandroWissmann/Quiz

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

                      The problem they had is that you have to use the delegate property to get access to the properties the Repeater adds to the delegate.

                      If the "required" part makes it not work, then get rid of it.

                      C++ is a perfectly valid school of magic.

                      1 Reply Last reply
                      0
                      • S sandro4912

                        @fcarney

                        check out this:

                        https://stackoverflow.com/questions/62484078/required-property-not-working-with-repeater

                        The issue is if you have a required property in an item you put into an repeater it only gets access to the index in the weired way that you add an index as required property. I also don't understand why it is necessary.

                        You can try it out by copy the project on git hub and remove the line index:
                        https://github.com/SandroWissmann/Quiz

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

                        @sandro4912 I ran your program. I removed the property index from QuizPage and got rid of "required" from question. It then showed the quiz correctly. When I clicked next question it crashed. Not sure what was wrong there.

                        C++ is a perfectly valid school of magic.

                        S 1 Reply Last reply
                        1
                        • S Offline
                          S Offline
                          sandro4912
                          wrote on last edited by
                          #20

                          Of course I could change

                          required property var question
                          

                          to

                          property var question
                          

                          but I thought it would be good to make it required to indicate the page only works with a question supplied. To me that all sounds like a weired bug that index is only available when you don't make a property required.

                          so

                          required property var index
                          

                          looks like a workarround.

                          fcarneyF 1 Reply Last reply
                          0
                          • fcarneyF fcarney

                            @sandro4912 I ran your program. I removed the property index from QuizPage and got rid of "required" from question. It then showed the quiz correctly. When I clicked next question it crashed. Not sure what was wrong there.

                            S Offline
                            S Offline
                            sandro4912
                            wrote on last edited by
                            #21

                            @fcarney
                            you are right it does not work anymore. I will check that issue tomorrow and then come back to here.

                            1 Reply Last reply
                            0
                            • S sandro4912

                              Of course I could change

                              required property var question
                              

                              to

                              property var question
                              

                              but I thought it would be good to make it required to indicate the page only works with a question supplied. To me that all sounds like a weired bug that index is only available when you don't make a property required.

                              so

                              required property var index
                              

                              looks like a workarround.

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

                              @sandro4912 said in How to create n Objects dynamically to populate StackView:

                              To me that all sounds like a weired bug that index is only available when you don't make a property required.

                              That issue on SO was because the OP was not using "delegate" inside of Repeater. The relevance to "required" was due to the repeater not being able to set the property.

                              C++ is a perfectly valid school of magic.

                              GrecKoG 1 Reply Last reply
                              1
                              • fcarneyF fcarney

                                @sandro4912 said in How to create n Objects dynamically to populate StackView:

                                To me that all sounds like a weired bug that index is only available when you don't make a property required.

                                That issue on SO was because the OP was not using "delegate" inside of Repeater. The relevance to "required" was due to the repeater not being able to set the property.

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

                                @fcarney said in How to create n Objects dynamically to populate StackView:

                                That issue on SO was because the OP was not using "delegate" inside of Repeater. The relevance to "required" was due to the repeater not being able to set the property.

                                No, it was not because of not using delegate, as a comment said delegate is a default property so you can omit it.
                                Repeater { Item {} } is the same as Repeater { delegate : Item {} }.

                                The problem was indeed because of the required property. Since Qt 5.15, if a delegate has a required property, the view won't assign the delegate context properties based on the roles of the model. It will only assign roles corresponding to the required properties present in the delegate.

                                https://doc.qt.io/qt-5/qtquick-modelviewsdata-modelview.html#models

                                To get finer control over which roles are accessible, and to make delegates more self-contained and usable outside of views, required properties can be used. If a delegate contains required properties, the named roles are not provided. Instead, the QML engine will check if the name of a required property matches that of a model role. If so, that property will be bound to the corresponding value from the model.
                                [...]
                                Note: model, index, and modelData roles are not accessible if the delegate contains required properties, unless it has also required properties with matching names.

                                That's why you can't access index or modelData if you don't declare them as required property in QuizPage.

                                And instead of index, you should use modelData :

                                delegate: QuizPage{
                                    required property var modelData
                                    question: modelData
                                }
                                

                                Note that QQmlListProperty is not meant to expose C++ data to QML, it is meant to allow the QML to populate a C++ list from QML.
                                You should use QList<QObject*>, QVariantList or even better QAbstractListModel if you need a dynamic model. QQmlListProperty does work, but it's not its job.

                                S 1 Reply Last reply
                                2
                                • fcarneyF Offline
                                  fcarneyF Offline
                                  fcarney
                                  wrote on last edited by
                                  #24

                                  @GrecKo
                                  No wonder I was going crazy trying to understand this problem. Thanks for shedding light on this.

                                  C++ is a perfectly valid school of magic.

                                  1 Reply Last reply
                                  1
                                  • GrecKoG GrecKo

                                    @fcarney said in How to create n Objects dynamically to populate StackView:

                                    That issue on SO was because the OP was not using "delegate" inside of Repeater. The relevance to "required" was due to the repeater not being able to set the property.

                                    No, it was not because of not using delegate, as a comment said delegate is a default property so you can omit it.
                                    Repeater { Item {} } is the same as Repeater { delegate : Item {} }.

                                    The problem was indeed because of the required property. Since Qt 5.15, if a delegate has a required property, the view won't assign the delegate context properties based on the roles of the model. It will only assign roles corresponding to the required properties present in the delegate.

                                    https://doc.qt.io/qt-5/qtquick-modelviewsdata-modelview.html#models

                                    To get finer control over which roles are accessible, and to make delegates more self-contained and usable outside of views, required properties can be used. If a delegate contains required properties, the named roles are not provided. Instead, the QML engine will check if the name of a required property matches that of a model role. If so, that property will be bound to the corresponding value from the model.
                                    [...]
                                    Note: model, index, and modelData roles are not accessible if the delegate contains required properties, unless it has also required properties with matching names.

                                    That's why you can't access index or modelData if you don't declare them as required property in QuizPage.

                                    And instead of index, you should use modelData :

                                    delegate: QuizPage{
                                        required property var modelData
                                        question: modelData
                                    }
                                    

                                    Note that QQmlListProperty is not meant to expose C++ data to QML, it is meant to allow the QML to populate a C++ list from QML.
                                    You should use QList<QObject*>, QVariantList or even better QAbstractListModel if you need a dynamic model. QQmlListProperty does work, but it's not its job.

                                    S Offline
                                    S Offline
                                    sandro4912
                                    wrote on last edited by
                                    #25

                                    @GrecKo

                                    Thanks for clarify. I was very confused how to expose my randomQuestions correctly.

                                    Now comes the big Question.

                                    Currently it is like this:

                                    All Questions are in a class Derived from QSqlTableModel.

                                    Now for RandomQuestions currently I create with an additional function in that class the QQmlListProperty<Questions>.

                                    Wouldn't it the best to implement QSortFilterProxModel which picks um the required random questions to expose that to QML?

                                    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