QML - signals for nested properties
-
I have an object that I populate from the backend (in this case - I'm learning C# and QML at once, so the backend is in C#). What I have in QML is:
AppModel { id: appmodel }
(for the curious - it's populated from C# here)
I can then use various properties such as
appmodel.scopeDirectory
,appmodel.resourceText
,appmodel.dotnetResult.errorCount
and so on.How can I trigger on
appmodel.dotnetResult.errorCount
changing is my exact question? -
@Vadi2 I still don't really understand what you want to achieve... Why do you have a C# part? do you use Qml.Net?
What do you want to do? Is it inside
AppModel
component? What is AppModel?If you want to made public and internal state, you can do something like this, in AppModel.qml, I suppose
AppModel
is base onItem
:import QtQuick 2.4 Item { ... property alias errorCount: dotnetResult.errorCount }
-
Yep, I'm using Qml.Net!
AppModel
is a component I register in C# (https://github.com/vadi2/Hammer/blob/master/Program.cs#L628), this is similar to how you register a custom component from C++ I think.I don't have an
AppModel.qml
, but I'll try the property aliases anyway... -
If your sub properties are correctly typed, you can do that:
AppModel { id: appmodel dotNetResult.onErrorCountChanged: print("error count changed") }
If the
dotNetResult
is a generic type (I assume it would be aQObject*
, aQQmlPropertyMap*
or aQVariantMap
), this won't work because there is noerrorCountChanged
signal in the base type, even if the actual instance has one.A solution in this case would be to use
Connections
:Connections { target: appmodel.dotNetResult onErrorCountChanged: print("error count changed") }
-
@GrecKo said in QML - signals for nested properties:
If your sub properties are correctly typed
I guess they're not, it says
Cannot assign to non-existent property "dotNetResult"
. I see thatConnections
doc says they're useful forConnecting to targets not defined in QML
which is perhaps the case here.It didn't work either unfortunately:
file:///home/vadi/Programs/Hammer/Main.qml:382:29: QML Connections: Cannot assign to non-existent property "onErrorCountChanged" file:///home/vadi/Programs/Hammer/Main.qml:383:33: Unable to assign [undefined] to QObject*
From reading the doc, I can put it anywhere, right?
-
-
I did it both deep down in a component where I actually use
appmodel.dotNetResult.errorCount
successfully and at the root level:AppModel { id: appmodel } Connections { target: appmodel.dotNetResult onErrorCountChanged: print("error count changed") Component.onCompleted: appmodel.testMe() }
Root level use says:
file:///home/vadi/Programs/Hammer/Main.qml:25:5: QML Connections: Cannot assign to non-existent property "onErrorCountChanged" Writing test - errorcount is 0 file:///home/vadi/Programs/Hammer/Main.qml:26:9: Unable to assign [undefined] to QObject*
I also defined a
TestMe()
method which prints this:public void TestMe() { Console.WriteLine($"Writing test - errorcount is {DotnetResult.ErrorCount}"); }
So we can be pretty certain the property does exist and is filled in...
-
@Vadi2 said in QML - signals for nested properties:
Unable to assign [undefined] to QObject*
That errors means
appmodel.dotNetResult
is undefined, the property might incorrectly be exposed.Your
TestMe()
test only shows thatDotnetResult.ErrorCount
is accessible from C#, not that it is properly exposed to QML. -
Aha we had a typo, it should be
dotnetResult
and notdotNetResult
. Fixing the typo so the code becomes:AppModel { id: appmodel } Connections { target: appmodel.dotnetResult onErrorCountChanged: print("error count changed") Component.onCompleted: { appmodel.testMe(); console.log(`errors: ${appmodel.dotnetResult.errorCount}`) } }
I get the following output:
Writing test - errorcount is 0 qml: errors: 0
But no notification of the change.
I _am_replacing
DotnetResult
in C# with another validation result when I get it - perhaps I shouldn't replace the object but copy/set the properties instead. I'll try it. -
No, the object replacing theory wasn't in. Before I do any validation, so
appmodel.dotnetResult
stays as-is, still don't get a notification with the following code:AppModel { id: appmodel } Connections { target: appmodel.dotnetResult onErrorCountChanged: print("error count changed") Component.onCompleted: { appmodel.testMe(); console.log(`errors: ${appmodel.dotnetResult.errorCount}`) } } Timer { interval: 1000; running: true; onTriggered: { appmodel.testMe(); console.log(`errors: ${appmodel.dotnetResult.errorCount}`) } }
Output:
Writing test - errorcount is 8 qml: errors: 8 Writing test - errorcount is 6 qml: errors: 6
So the properties are accessible - but not able to be notified correctly. What techniques can I use to debug this?