Understanding QML attributes
-
I am stuck on a problem, I will try to explain it. We have a GUI which was put together by another entity. They gave us a great shell but some alterations need to be made. Currently, I am working on the alphanumeric number pad and here is how it is being instantiated in a script called WizardSectionDisplay.qml:
onShowKeyboard: { var comp = Qt.createComponent("qrc:/Source//UiControls/WizardPopupKeyboard.qml"); comp.createObject(application, { "title": mod_data.label ,"objectName":"systemDialog" , "hint": qsTr("Enter a value between %1 and %2").arg(Math.round(mod_data.minValue)).arg(Math.round(mod_data.maxValue)) , "modelButtons": [qsTr("Cancel"), qsTr("Finished")] , "primaryIndex": 1 , "controlTarget": minMaxSplitBtn , "settingValue": mod_data }) }
so in other words I am adding some functionality to the WizzardPopupKeyboard.qml file. One of the problems I am addressing has to do with the units being displayed. Here, where the object is being created, they are accessing units like so:
mod_data.unit
I am trying to do something similar inside of WizzardPopupKeyboard.qml:
if(mod_Data.unit === "s") { entryDisplay.text = settingValue.value }
this does work, I am getting the functionality I need but for some reason an error is being reported:
ReferenceError: mod_Data is not defined
this seems odd to me because its working despite mod_Data not being defined. Here is how mod_Data is being defined inside of the WizardSectionDisplay.qml:
Loader{ id:contentContainer height: parent.height anchors.left: delegateLabel.right anchors.right: parent.right //this is required due to a qml *bug* that will eat the modelData property from the listmodel parent. property variant mod_data: modelData sourceComponent: numberEntry }
As you can see it's based off of modelData but modelData is not defined inside of WizardSectionDisplay.qml, in fact, I can't seem to figure out where its being defined. So my question is how can I go about using mod_data in the WizardPopupKeyboard.qml without getting the error?
-
modelData
is a property of all models in QML. See the docs. So I guess that your loader is used as a delegate in some view.That might explain why
mod_data
is not always defined - maybe youronShowKeyboard
is called before the model is ready, or before the delegate is created etc. Views can create / destroy delegates at any point in time, too, so it might be unreliable depending on them like that. Hard to say for sure as I don't know how your system works in detail - but maybe these hints will help. -
So that's why modelData is used all over the place. So modelData is only ever used in WizardSectionDisplay.qml after the keyboard is created but mod_data is used throughout the script. One thing I can't seem to understand. During the creation of the keyboard object mod_data is passed as settingValue:
, "settingValue": mod_data
however; I can't seem to use it's unit attribute, for instance if I try:
if(presentationManager.guiSettingsPresenter.model.useUSUnits) { if(settingValue.unit === "s") { true } false }
in WizardPopupKeyboard.qml the above code throws no errors but doesn't work. However, if I import the UiControls then, as I showed in the code from my previous post, I can simply call mod_data.unit directly and the it works but throws the error. I would think that they should both work and that they should both throw an error. I even tried passing the units directly:
, "unit": mod_data.unit
and then calling:
if(presentationManager.guiSettingsPresenter.model.useUSUnits) { if(unit === "s") { true } false }
however, that did not work either. I dont understand how I can use settingValue.value, or settingValue.label in WizardPopupKeyboard.qml without any errors but I can't use settingValue.unit... seems odd. In my previous code you can see the comment they left behind during the creation of the mod_data property:
//this is required due to a qml *bug* that will eat the modelData property from the listmodel parent.
perhaps my problem is related?
EDIT: A bit more confused now. Turns out I can access the settingValue.unit but I can't use it in an if statement like I want? To test and see if I have access to .unit I decided to change the text of the . button to:
settingValue.unit
and voila it worked:
PushButton { width: 75 height: width text: settingValue.unit //"." enabled: { if(presentationManager.guiSettingsPresenter.model.useUSUnits) { if(settingValue.unit === "s") { true } false } } onClicked: { outValue+="."; } }
the keyboard is now showing an s where the period use to be but for some reason the s is still being grayed out... as thought the condition can't be met...
-
Alright, perhaps someone can explain to me why the previous code did not work but this code does:
PushButton { width: 75 height: width text: "." enabled: { if(presentationManager.guiSettingsPresenter.model.useUSUnits) { if(settingValue.unit === "s") { true } else { false } } else { true } } onClicked: { outValue+="."; } }
the logic seems to be the same to me but adding these brackets and a few else clauses has fixed the issue. I was under the impression that as long as my logic was only one line then I didn't need the brackets.
-
@Circuits said in Understanding QML attributes:
if(mod_Data.unit === "s")
ReferenceError: mod_Data is not defined
Is this a copy and paste of actual code and is the error code a copy and paste?
Because the code you pasted before has:
"settingValue": mod_data
While the if statement has:
if(mod_Data.unit === "s")
You are mixing variable cases "mod_data" != "mod_Data"