How to create n Objects dynamically to populate StackView
-
@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.
-
@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.answer1I think you may be having scoping issues with the question property.
-
@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.
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 -
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@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.
-
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.
-
@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.
@fcarney
you are right it does not work anymore. I will check that issue tomorrow and then come back to here. -
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.
@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.
-
@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.
@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 saiddelegate
is a default property so you can omit it.
Repeater { Item {} }
is the same asRepeater { 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
ormodelData
if you don't declare them as required property inQuizPage
.And instead of
index
, you should usemodelData
: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 useQList<QObject*>
,QVariantList
or even betterQAbstractListModel
if you need a dynamic model.QQmlListProperty
does work, but it's not its job. -
@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 saiddelegate
is a default property so you can omit it.
Repeater { Item {} }
is the same asRepeater { 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
ormodelData
if you don't declare them as required property inQuizPage
.And instead of
index
, you should usemodelData
: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 useQList<QObject*>
,QVariantList
or even betterQAbstractListModel
if you need a dynamic model.QQmlListProperty
does work, but it's not its job.Thanks for clarify. I was very confused how to expose my randomQuestions correctly.
Now comes the big Question.
Currently it is like this:
All Questions are in a class Derived from
QSqlTableModel
.Now for RandomQuestions currently I create with an additional function in that class the
QQmlListProperty<Questions>
.Wouldn't it the best to implement
QSortFilterProxModel
which picks um the required random questions to expose that to QML?