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.
  • F Offline
    F Offline
    fcarney
    wrote on 29 Sept 2020, 17:38 last edited by
    #5

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

    SwipeView{
    id: quizSwipeView
    interactive: false
    anchors.fill: parent
    }

      SwipeView{
            id: quizSwipeView
            interactive: false
            anchors.fill: parent
    
            Repeater {
               model: randomQuestions
               delegate: QuizPage {
                     question: modelData
               }
            }
        }
    

    This was from memory, so you may have to lookup the syntax for things.

    C++ is a perfectly valid school of magic.

    1 Reply Last reply
    2
    • S Offline
      S Offline
      sandro4912
      wrote on 30 Sept 2020, 04:57 last edited by sandro4912
      #6

      That givies similar errors like my complicated solution:

      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/QuizPage.qml:30: TypeError: Cannot read property 'answer1' of undefined
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/Quiz.qml:21:23: QML QuizPage: SwipeView has detected conflicting anchors. Unable to layout the item.
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:0: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:0: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:0: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:0: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:0: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:0: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:0: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:22: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:22: ReferenceError: modelData is not defined
      qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
      qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
      qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
      qrc:/qml/quiz/Quiz.qml:22: ReferenceError: modelData is not defined
      

      Strangley I can read randomQuestions in onCompleted:

      import QtQuick 2.15
      import QtQuick.Controls 2.15
      
      Item {
          id: quiz
      
          required property var randomQuestions
      
          Component.onCompleted: {
              // this works
              console.log(randomQuestions[0].id)
              console.log(randomQuestions[0].answer1)
              console.log(randomQuestions[0].answer2)
              console.log(randomQuestions[0].answer3)
              console.log(randomQuestions[0].answer4)
              console.log(randomQuestions[0].askedQuestion)
          }
      
          width: parent.width
          height: parent.height
      
          SwipeView{
              id: quizSwipeView
              interactive: false
              anchors.fill: parent
      
              Repeater{
                  model: randomQuestions
                  delegate: QuizPage{
                      question: modelData
                  }
              }
          }
      }
      

      randomQuestions is an QQmlListProperty <Question> exposed in C++:

      1 Reply Last reply
      0
      • F Offline
        F Offline
        fcarney
        wrote on 30 Sept 2020, 13:20 last edited by
        #7

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

        QQmlListProperty

        It looks like it is repeating, but not creating modelData. Not sure if QQmlListProperty is 100% supported, but it should be creating an "index" variable you can use.

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

        C++ is a perfectly valid school of magic.

        1 Reply Last reply
        1
        • S Offline
          S Offline
          sandro4912
          wrote on 30 Sept 2020, 15:26 last edited by
          #8

          I tried that but it also insist that index is not existing:

          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:0: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:0: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:0: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:0: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:0: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:0: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:0: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:30: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:30: ReferenceError: index is not defined
          qrc:/qml/quiz/QuizPage.qml:51: TypeError: Cannot read property 'id' of undefined
          qrc:/qml/quiz/QuizPage.qml:56: TypeError: Cannot read property 'askedQuestion' of undefined
          qrc:/qml/quiz/QuizPage.qml:63: TypeError: Cannot read property 'picture' of undefined
          qrc:/qml/quiz/Quiz.qml:30: ReferenceError: index is not defined
          

          Some more background information of random Questions.

          A Question is defined like this:

          class Question : public QObject
          {
              Q_OBJECT
              Q_PROPERTY(int id READ getId CONSTANT)
              Q_PROPERTY(QString askedQuestion READ getAskedQuestion CONSTANT)
              Q_PROPERTY(QString answer1 READ getAnswer1 CONSTANT)
              Q_PROPERTY(QString answer2 READ getAnswer2 CONSTANT)
              Q_PROPERTY(QString answer3 READ getAnswer3 CONSTANT)
              Q_PROPERTY(QString answer4 READ getAnswer4 CONSTANT)
              Q_PROPERTY(int correctAnswer READ getCorrectAnswer CONSTANT)
              Q_PROPERTY(QString picture READ getPicture CONSTANT)
          public:
              enum class Correct{
                  Answer1 = 1,
                  Answer2 = 2,
                  Answer3 = 3,
                  Answer4 = 4
              };
          
              Question() = default;
          
              Question(int id,
                       QString askedQuestion,
                       QString answer1,
                       QString answer2,
                       QString answer3,
                       QString answer4,
                       Correct correctAnswer,
                       QString picture = QString{});
          
              int getId() const;
              QString getAskedQuestion() const;
              QString getAnswer1() const;
              QString getAnswer2() const;
              QString getAnswer3() const;
              QString getAnswer4() const;
              int getCorrectAnswer() const;
              QString getPicture() const;
          
          private:
              int mId;
              QString mAskedQuestion;
              QString mAnswer1;
              QString mAnswer2;
              QString mAnswer3;
              QString mAnswer4;
              Correct mCorrectAnswer;
              QString mPicture;
          };
          

          In annother class which has sql connection I read the randomQuestions:

          class QuestionSqlTableModel : public QSqlTableModel
          {
              Q_OBJECT
              Q_PROPERTY(QQmlListProperty<Question> randomQuestions
                         READ getRandomQuestions
                         NOTIFY randomQuestionsChanged)
          public:
              explicit QuestionSqlTableModel(QObject *parent = nullptr,
                                             const QSqlDatabase &db = QSqlDatabase());
          
              Q_INVOKABLE QVariant data(const QModelIndex &index, int role) const override;
          
          
              Q_INVOKABLE bool addNewEntry(const QString& askedQuestion,
                  const QString& answer1,
                  const QString& answer2,
                  const QString& answer3,
                  const QString& answer4,
                  int correctAnswer,
                  const QString& picturePath);
          
              Q_INVOKABLE void generateNewRandomQuestions(int count);
          
              QQmlListProperty <Question> getRandomQuestions();
          
          signals:
              void randomQuestionsChanged();
          
          private:
              void appendRandomQuestion(Question *question);
              int randomQuestionsCount() const;
              Question* randomQuestionAt(int index) const;
              void randomQuestionsClear();
          
              static void appendRandomQuestion(
                      QQmlListProperty<Question>* list, Question *question);
              static int randomQuestionsCount(QQmlListProperty<Question>* list);
              static Question* randomQuestionAt(
                      QQmlListProperty<Question>* list, int index);
              static void randomQuestionsClear(QQmlListProperty<Question>* list);
          
              QVector<Question*> mRandomQuestions;
          };
          

          They get registered like this:

              qmlRegisterAnonymousType<Question>("sandro.custom.types",1);
          
              auto context = engine.rootContext();
              context->setContextProperty("questionSqlTableModel", questionSqlTableModel);
          

          I pass the random questions like this to the Quiz:

                  ToolButton {
                      text: qsTr("New Quiz")
                      icon.name: "address-book-new"
                      onClicked: {
                          questionSqlTableModel.generateNewRandomQuestions(10)
                          loader.setSource("quiz/Quiz.qml",
                                           {"randomQuestions":
                                               questionSqlTableModel.randomQuestions})
                      }
                  }
          

          What I could already do is show a single page likes this:

          import QtQuick 2.15
          import QtQuick.Controls 2.15
          
          Item {
              id: quiz
          
              required property var randomQuestions
              width: parent.width
              height: parent.height
          
              QuizPage{
                  id: quizPage
                  anchors.fill: parent
                  question: randomQuestions[0]
              }
          }
          

          This works without problem so I really wonder why the delegate solution does not work.

          For completion here is QuizPage:

          import QtQuick 2.15
          import QtQuick.Layouts 1.15
          import QtQuick.Controls 2.15
          
          Item{
              id: root
          
              required property var question
          
              property var __shuffledAnswers
              property bool __correctAnswer: false
          
              signal answeredCorrectly()
              signal answeredWrong()
          
              width: parent.width
              height: parent.height
              anchors.fill: parent
          
          
              Rectangle {
                  id: dialog
          
                  width: parent.width
                  height: parent.height
          
                  Component.onCompleted: {
                      checkButton.enabled = false;
                      nextQuestionButton.enabled = false;
          
                      root.__shuffledAnswers = makeAnswerArray(question.answer1,
                                                          question.answer2,
                                                          question.answer3,
                                                          question.answer4);
                      shuffleArray(root.__shuffledAnswers);
          
                      answer1TextField.text = root.__shuffledAnswers[0];
                      answer2TextField.text = root.__shuffledAnswers[1];
                      answer3TextField.text = root.__shuffledAnswers[2];
                      answer4TextField.text = root.__shuffledAnswers[3];
                  }
          
                  ButtonGroup {
                      id: radioGroup
                  }
          
                  ColumnLayout{
                      anchors.fill: parent
          
                      RowLayout{
                          Text{
                              text: qsTr("Question: " + question.id)
                          }
                      }
                      RowLayout{
                          Text{
                              text: qsTr(question.askedQuestion)
                          }
                      }
                      RowLayout{
                          Image{
                              id: image
          
                              source: question.picture.length > 0 ?
                                          "data:image/png;base64," + question.picture: ""
                          }
                      }
                      RowLayout{
                          RadioButton{
                              id: radioButtonAnswer1
                              ButtonGroup.group: radioGroup
                              onCheckedChanged: {
                                  if(checked) {
                                      checkButton.enabled = true
                                      if(root.question.correctAnswer === 1) {
                                          __correctAnswer = true
                                      }
                                      else {
                                          __correctAnswer = false
                                      }
                                  }
                              }
                          }
                          AnswerTextField{
                              Layout.fillWidth: true
                              id: answer1TextField
                          }
                      }
                      RowLayout{
                          RadioButton{
                              id: radioButtonAnswer2
                              ButtonGroup.group: radioGroup
                              onCheckedChanged: {
                                  if(checked) {
                                      checkButton.enabled = true
                                      if(root.question.correctAnswer === 2) {
                                          __correctAnswer = true
                                      }
                                      else {
                                          __correctAnswer = false
                                      }
                                  }
                              }
                          }
                          AnswerTextField{
                              Layout.fillWidth: true
                              id: answer2TextField
                          }
                      }
                      RowLayout{
                          RadioButton{
                              id: radioButtonAnswer3
                              ButtonGroup.group: radioGroup
                              onCheckedChanged: {
                                  if(checked) {
                                      checkButton.enabled = true
                                      if(root.question.correctAnswer === 3) {
                                          __correctAnswer = true
                                      }
                                      else {
                                          __correctAnswer = false
                                      }
                                  }
                              }
                          }
                          AnswerTextField{
                              Layout.fillWidth: true
                              id: answer3TextField
                          }
                      }
                      RowLayout{
                          RadioButton{
                              id: radioButtonAnswer4
                              ButtonGroup.group: radioGroup
                              onCheckedChanged: {
                                  if(checked) {
                                      checkButton.enabled = true
                                      if(root.question.correctAnswer === 4) {
                                          __correctAnswer = true
                                      }
                                      else {
                                          __correctAnswer = false
                                      }
                                  }
                              }
                          }
                          AnswerTextField{
                              Layout.fillWidth: true
                              id: answer4TextField
                          }
                      }
                      RowLayout{
                          Layout.alignment: Qt.AlignRight
                          Button{
                              id: checkButton
                              text: qsTr("Check Answer")
                              onPressed: {
                                  markAnswers(root.question.correctAnswer);
                                  disableRadioButtons();
                                  enabled = false
                                  nextQuestionButton.enabled = true
                              }
                          }
                          Button{
                              id: nextQuestionButton
                              text: qsTr("Next Question")
                              onPressed: {
                                  if(root.__correctAnswer) {
                                      root.answeredCorrectly()
                                  }
                                  else {
                                      root.answeredWrong()
                                  }
                              }
                          }
                      }
                  }
              }
          
              function makeAnswerArray(answer1, answer2, answer3, answer4)
              {
                  return [answer1, answer2, answer3, answer4];
              }
          
              function shuffleArray(array)
              {
                  for (var i = array.length - 1; i > 0; i--) {
                      var j = Math.floor(Math.random() * (i + 1));
                      var temp = array[i];
                      array[i] = array[j];
                      array[j] = temp;
                  }
              }
          
              readonly property string correctAnswerColor: "#99FFCC"
              readonly property string wrongAnswerColor: "#FF9999"
          
              function markAnswers(correctAnswer)
              {
                  switch(correctAnswer)
                  {
                      case 1:
                          markAnswersIfAnswer1IsCorrect();
                          break;
                      case 2:
                          markAnswersIfAnswer1IsCorrect();
                          break;
                      case 3:
                          markAnswersIfAnswer1IsCorrect();
                          break;
                      case 4:
                          markAnswersIfAnswer1IsCorrect();
                          break;
                      default:
                          console.assert(false, "Invalid Value for correctAnswer: "
                                          + correctAnswer)
          
                  }
              }
          
              function markAnswersIfAnswer1IsCorrect()
              {
                  answer1TextField.backgroundColor = correctAnswerColor
                  answer2TextField.backgroundColor = wrongAnswerColor
                  answer3TextField.backgroundColor = wrongAnswerColor
                  answer4TextField.backgroundColor = wrongAnswerColor
              }
          
              function markAnswersIfAnswer2IsCorrect()
              {
                  answer1TextField.backgroundColor = wrongAnswerColor
                  answer2TextField.backgroundColor = correctAnswerColor
                  answer3TextField.backgroundColor = wrongAnswerColor
                  answer4TextField.backgroundColor = wrongAnswerColor
              }
          
              function markAnswersIfAnswer3IsCorrect()
              {
                  answer1TextField.backgroundColor = wrongAnswerColor
                  answer2TextField.backgroundColor = wrongAnswerColor
                  answer3TextField.backgroundColor = correctAnswerColor
                  answer4TextField.backgroundColor = wrongAnswerColor
              }
          
              function markAnswersIfAnswer4IsCorrect()
              {
                  answer1TextField.backgroundColor = wrongAnswerColor
                  answer2TextField.backgroundColor = wrongAnswerColor
                  answer3TextField.backgroundColor = wrongAnswerColor
                  answer4TextField.backgroundColor = correctAnswerColor
              }
          
              function disableRadioButtons()
              {
                  radioButtonAnswer1.enabled = false
                  radioButtonAnswer2.enabled = false
                  radioButtonAnswer3.enabled = false
                  radioButtonAnswer4.enabled = false
              }
          }
          
          
          1 Reply Last reply
          0
          • S Offline
            S Offline
            sandro4912
            wrote on 30 Sept 2020, 15:30 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
            • F Offline
              F Offline
              fcarney
              wrote on 30 Sept 2020, 15:43 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 30 Sept 2020, 15:57 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
                • F Offline
                  F Offline
                  fcarney
                  wrote on 30 Sept 2020, 16:00 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
                  • F Offline
                    F Offline
                    fcarney
                    wrote on 30 Sept 2020, 16:06 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 30 Sept 2020, 16:34 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
                      • F Offline
                        F Offline
                        fcarney
                        wrote on 30 Sept 2020, 17:07 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 30 Sept 2020, 17:13
                        0
                        • F Offline
                          F Offline
                          fcarney
                          wrote on 30 Sept 2020, 17:11 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
                          • F fcarney
                            30 Sept 2020, 17:07

                            @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 30 Sept 2020, 17:13 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

                            F 1 Reply Last reply 30 Sept 2020, 17:25
                            0
                            • F Offline
                              F Offline
                              fcarney
                              wrote on 30 Sept 2020, 17:17 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
                                30 Sept 2020, 17:13

                                @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

                                F Offline
                                F Offline
                                fcarney
                                wrote on 30 Sept 2020, 17:25 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 30 Sept 2020, 17:51
                                1
                                • S Offline
                                  S Offline
                                  sandro4912
                                  wrote on 30 Sept 2020, 17:46 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.

                                  F 1 Reply Last reply 30 Sept 2020, 17:55
                                  0
                                  • F fcarney
                                    30 Sept 2020, 17:25

                                    @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 30 Sept 2020, 17:51 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
                                      30 Sept 2020, 17:46

                                      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.

                                      F Offline
                                      F Offline
                                      fcarney
                                      wrote on 30 Sept 2020, 17:55 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 30 Sept 2020, 20:18
                                      1
                                      • F fcarney
                                        30 Sept 2020, 17:55

                                        @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 Online
                                        GrecKoG Online
                                        GrecKo
                                        Qt Champions 2018
                                        wrote on 30 Sept 2020, 20:18 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 1 Oct 2020, 04:24
                                        2
                                        • F Offline
                                          F Offline
                                          fcarney
                                          wrote on 30 Sept 2020, 20:43 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

                                          14/25

                                          30 Sept 2020, 16:34

                                          • Login

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