Solved Making repeating code generic
-
So I have come up with a plan for how I want to implement my keypad. In total the code will looking something similar to this (haven't refined the idea yet):
Rectangle { id: rect anchors.verticalCenter: parent.verticalCenter width: parent.width - 100 height: parent.height anchors.centerIn: parent color: "white" radius: 5 QtObject { id: modelData property var label: "The Label" property var unit: "The Unit" property int minValue: 0 property int maxValue: 100 property int value: 100 } Text { id: numericEntryDisplay elide: Text.ElideRight width: parent.width anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom horizontalAlignment: Text.AlignHCenter text: modelData.value } Text { id: unitText text: modelData.unit anchors.left: parent.right anchors.bottom: parent.bottom } MouseArea { anchors.fill: parent onClicked: showNumericKeyboard("systemDialog", [qsTr("Cancel"), qsTr("Finished")], 1, modelData, qsTr(""), 0); } }
The problem is that I am going to have instantiate this code 3 or 4 times per page. So I am looking to make it more generic. Perhaps make it it's own component? In general, what would the process of making this generic look like?
For instance, I would love it if I could just call it something like
KeypadRect
and whenever I call that I could specify a few things... for example in my mind it would look something like:KeypadRect { id: inputX anchors { //some anchoring bindings } model: { value: x unit: "x" minValue: y etc... } }
Would I need to wrap it in
Item
to do this or what's the Qt standard for doing something like this? -
@Circuits said in Making repeating code generic:
Would I need to wrap it in Item to do this or what's the Qt standard for doing something like this?
- Your top-level Rectangle is enough
- Add a
property
for your model, to expose it to the outside world - Move your code to a new QML file and remember to start file name with Capital letter (otherwise QML engine won't see it)
- Then you can start using that component in your other QML files (if it's in different directory, use
import
statement)
-
@sierdzio "Add a
property
to your model, to expose it to the outside world."Could you elaborate a bit on this? What would this property be? Do you mean:
property (x) myModel: QtObject { id: modelData property var label property var unit property int minValue property int maxValue property int value }
-
I meant the rectangle. Only top-level properties are visible to the outside (to other QML files). It can even be something as simple as:
Rectangle { property alias model: modelData }
-
@sierdzio Perhaps I am not allowed to do what I am trying to do. I will post the code so you know what's going on:
//main.qml import QtQuick 2.12 import QtQuick.Window 2.12 Window { id: _theWindow visible: true width: 640 height: 480 function showComponent(settingValue) { var comp = Qt.createComponent("qrc:/theObjectToCreate.qml"); comp.createObject(_theWindow,{"settingValue": settingValue}) } RectComp { id: _theRectangleComponent property alias theAlias: _theRectangleComponent theAlias.myObject.mainValue: 5 } } //RectComp.qml import QtQuick 2.12 import QtQuick.Window 2.12 Rectangle { id: _theRectangle width: 100 height: 100 anchors.centerIn: parent color: "lightblue" property alias myObject: _theObject QtObject { id: _theObject property int mainValue } MouseArea { anchors.fill: parent onClicked: showComponent(_theObject); } } //theObjectToCreate.qml import QtQuick 2.12 import QtQuick.Window 2.12 Window { id: _newWindow visible: true width: 640 height: 480 property QtObject settingValue Rectangle { id: _newRectangle width: 100 height: 100 color: "gray" anchors.centerIn: parent Text { id: _displayText anchors.centerIn: parent text: settingValue.mainValue } } }
As you can see I am attempting to create a
Component
on a click. TheComponent
will then display the values passed to it from theQtObject
and I would like to set thatQtObject
's properties from within main. However, the second rectangle is displaying 0 when I am expecting it to display 5.EDIT:
So I figured out that I can set the value if I do something like this:
RectComp { id: _theRectangleComponent property alias theAlias: _theRectangleComponent Component.onCompleted: theAlias.myObject.mainValue = 5 }
but I was hoping I could just set the
_theObject
's property values from within main as though they were_theRectangleComponent
's own properties. Perhaps that just isn't possible? -
@Circuits said in Making repeating code generic:
property alias theAlias: _theRectangleComponent
This line is completely unnecessary.
theAlias.theModel.mainValue: 5
This should be:
theModel.mainValue: 5
-
@sierdzio That's how I figured it should work but it doesn't seem to like the
QtObject
property. For instance, if I setup two property's inside of RectComp.qml like so://RectComp.qml ... Rectangle { id: _theRectangle ... property alias myObject: _theObject property string genericString QtObject { id: _theObject property int mainValue } ...
and I then try to assign values to them in main:
genericString: "generic" myObject.mainValue: 5
There is no trouble with
genericString
but I get an error onmyObject.mainValue: 5
:Cannot assign to non-existent property "mainValue"
However, if I instead assign it a value in main like so:
Component.onCompleted: { myObject.mainValue = 5 }
then it works.
-
@Circuits Fixed by making the
QtObject
an internal component of_theRectangle
like so://RectComp.qml import QtQuick 2.12 import QtQuick.Window 2.12 Rectangle { id: _theRectangle width: 100 height: 100 anchors.centerIn: parent color: "lightblue" property alias myObject: _theObject InternalObjectComp { id: _theObject } MouseArea { anchors.fill: parent onClicked: showComponent(_theObject); } }