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.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sandro4912
    wrote on 28 Sept 2020, 16:40 last edited by sandro4912
    #1

    During runtime i'm generating n Datasets in QML.

    I have a qml item which I construct with one of the Datasets.

    Now I want to do the following:

    Create n qml items out of the datasets.

    Populate a StackView with these n objects.

    So how can I dynamically create n Objects and populate them in the StackView?

    I understand there is loader to load a single page from file Dynamically but that does not help here...

    1 Reply Last reply
    0
    • G Offline
      G Offline
      GrecKo
      Qt Champions 2018
      wrote on 28 Sept 2020, 19:03 last edited by
      #2

      I would use an Instantiator and push items on the StackView in onObjectAdded.

      Also are you sure StackView is the correct component to use? Have you considered SwipeView with a Repeater?

      1 Reply Last reply
      1
      • S Offline
        S Offline
        sandro4912
        wrote on 29 Sept 2020, 04:49 last edited by sandro4912
        #3

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

        I would use an Instantiator and push items on the StackView in onObjectAdded.

        Also are you sure StackView is the correct component to use? Have you considered SwipeView with a Repeater?

        Im not sure if I can use Instantiator to create all the Objects. Here is one Object created from the first data:

            QuizPage{
                question: randomQuestions[0]
            }
        

        How can i tell Instantiator to make n QuizPages?.

        With Stack or SwipeView im not completly sure. the Behaviour will be like this. I show the first page with a button at the end you can show the next page etc... I maybe want a small animation on Page change so I thought StackView would be good.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          sandro4912
          wrote on 29 Sept 2020, 17:27 last edited by
          #4

          I switched to the SwipeView because it is really what I want when it is inactive. However I could not get the Instantiator to work so I tried it like this:

          import QtQuick 2.15
          import QtQuick.Controls 2.15
          
          Item {
              id: quiz
          
              required property var randomQuestions
          
              width: parent.width
              height: parent.height
          
              SwipeView{
                  id: quizSwipeView
                  interactive: false
                  anchors.fill: parent
              }
          
              Component.onCompleted: {
                  var quizPage;
                  for(var i=0; i<randomQuestions.length; ++i) {
                      quizPage = createQuizPage(quizSwipeView, randomQuestions[i]);
                      quizSwipeView.addItem(quizPage);
                  }
                  quizSwipeView.setCurrentIndex(0)
                  console.log(quizSwipeView.count)
                  console.log(quizSwipeView.currentItem.width)
                  console.log(quizSwipeView.currentItem.height)
              }
          
              function createQuizPage(parent, randomQuestion) {
                  var component = Qt.createComponent("QuizPage.qml");
                  var object = component.createObject(parent, {question: randomQuestion});
          
                  if (object === null) {
                      console.log("Error creating quizPage");
                  }
                  return object
              }
          }
          

          Unfortunately when I load the File the programm freezes and I don't see the QuizPage.

          However in

              console.log(quizSwipeView.currentItem.width)
              console.log(quizSwipeView.currentItem.height)
          

          I can see the correct size of the Current Quiz Page. So why is it not loading?

          If you need more information you can check the full source code here: https://preview.tinyurl.com/yy84ofd7

          1 Reply Last reply
          0
          • 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

                                          1/25

                                          28 Sept 2020, 16:40

                                          • Login

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