Unable to change bools in C++ struct
-
@JonB agree completely, though I'm not sure what the next step is, given how "close to the top" this code is. It probably has something to do with how I coded my struct, but I sure can't see what might be doing this.
-
@mzimmers when I get strange stuff not working I do a clean, run qmake, build. Sometimes it is just a moc issue. Not sure how that works with cmake though.
-
OK, so I discovered something, but I don't understand it. I stepped through this in the debugger, and confirmed the problem is in the C++ side:
Then, for lack of anything else to try, I removed the initializer in my struct:
// bool m_maintenance = false; // before bool m_maintenance; // now
and...
For another test, I added this line to my c'tor:bool m_maintenance = false;
And got the original (bad) result.
I also "changed polarity" (initialize to true; try to set to false) with the same (bad) result.
So...this problem just got a little bigger. I'm not willing to release code to the field that creates structs with uninitialized values; I need to figure out what's going on here.
EDIT: this occurs on 6.6 as well as 6.5.3.
ANY ideas, no matter how far-fetched, are welcome. Thanks...
-
OK, so I discovered something, but I don't understand it. I stepped through this in the debugger, and confirmed the problem is in the C++ side:
Then, for lack of anything else to try, I removed the initializer in my struct:
// bool m_maintenance = false; // before bool m_maintenance; // now
and...
For another test, I added this line to my c'tor:bool m_maintenance = false;
And got the original (bad) result.
I also "changed polarity" (initialize to true; try to set to false) with the same (bad) result.
So...this problem just got a little bigger. I'm not willing to release code to the field that creates structs with uninitialized values; I need to figure out what's going on here.
EDIT: this occurs on 6.6 as well as 6.5.3.
ANY ideas, no matter how far-fetched, are welcome. Thanks...
Check this out.
https://stackoverflow.com/questions/1069621/are-members-of-a-c-struct-initialized-to-0-by-default
It may not be a C++ problem. Instead it is a C problem. Struct is very C style. I even avoid using it. -
Check this out.
https://stackoverflow.com/questions/1069621/are-members-of-a-c-struct-initialized-to-0-by-default
It may not be a C++ problem. Instead it is a C problem. Struct is very C style. I even avoid using it. -
@JoeCFD interesting article, though my issue is with modification, not initialization.
Regarding the use of structs: I suppose I could use a class, but I'd be astonished if that made a difference. I'm deliberately avoiding using QObject here, too.
-
@mzimmers bool m_maintenance; // now
is undefined.can you try:
bool m_maintenance{ false };
I do not know if it will make a difference.@JoeCFD said in Unable to change bools in C++ struct:
@mzimmers bool m_maintenance; // now
is undefined.I realize that, and that's not acceptable. But currently I have the options of leaving it undefined, or initializing it and (somehow) making it QML-immutable in the process.
I can't even modify it if I initialize it in QML, like this:
property schedule newSchedule: ({ "maintenance": false })
-
@mzimmers bool m_maintenance; // now
is undefined.can you try:
bool m_maintenance{ false };
I do not know if it will make a difference. -
@JoeCFD said in Unable to change bools in C++ struct:
can you try:
bool m_maintenance{ false };Same (bad) result. Thanks for the suggestion, though.
-
@GrecKo this:
Component.onCompleted: { var tempSchedule = newSchedule console.log("ScheduleScreen.qml: newSchedule is " + newSchedule) tempSchedule.name = "xxx" tempSchedule.m_maintenance = true tempSchedule.timeOffset = 55 tempSchedule.timeFrame = ScheduleEnums.TIMEFRAME_DAILY; newSchedule = tempSchedule console.log("ScheduleScreen.qml: tempSchedule is " + tempSchedule) console.log("ScheduleScreen.qml: newSchedule is " + newSchedule) }
Produces this:
qml: ScheduleScreen.qml: newSchedule is Schedule({00000000-0000-0000-0000-000000000000}, , {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_WEEKLY, REPEAT_EVERY_WEEK, , , , 0, ) qml: ScheduleScreen.qml: tempSchedule is Schedule({00000000-0000-0000-0000-000000000000}, xxx, {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_DAILY, REPEAT_EVERY_WEEK, , , , 55, ) qml: ScheduleScreen.qml: newSchedule is Schedule({00000000-0000-0000-0000-000000000000}, xxx, {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_DAILY, REPEAT_EVERY_WEEK, , , , 55, )
So...no change. Really odd, isn't it?
-
@mzimmers what's the issue on this output? We don't know which field is which. Also why are you using m_maintenance in QML? That's not the name of your property.
-
OK, guys - here's a minimal repeatable example:
// schedule.h #pragma once #include <QObject> #include <QMetaType> #include <QtQml/qqmlregistration.h> #include <QtQmlIntegration/QtQmlIntegration> struct Schedule { Q_GADGET QML_VALUE_TYPE(schedule) QML_STRUCTURED_VALUE Q_PROPERTY(bool maintenance MEMBER m_maintenance) public: bool m_maintenance; Q_INVOKABLE Schedule() {} bool operator ==(const Schedule &rhs) const {return true;} };
// Main.qml import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Window Window { id: mainWindow width: 640 height: 480 visible: true property schedule newSchedule: ({ }) Switch { onClicked: { console.log("switch is " + checked) newSchedule.maintenance = checked console.log("newSchedule.maintenance is " + newSchedule.maintenance) } } }
Output:
qml: switch is true qml: newSchedule.maintenance is false qml: switch is false qml: newSchedule.maintenance is false qml: switch is true qml: newSchedule.maintenance is false qml: switch is false qml: newSchedule.maintenance is false
I can provide the cmake file as well if desired, but it doesn't contain anything unusual.
-
OK, guys - here's a minimal repeatable example:
// schedule.h #pragma once #include <QObject> #include <QMetaType> #include <QtQml/qqmlregistration.h> #include <QtQmlIntegration/QtQmlIntegration> struct Schedule { Q_GADGET QML_VALUE_TYPE(schedule) QML_STRUCTURED_VALUE Q_PROPERTY(bool maintenance MEMBER m_maintenance) public: bool m_maintenance; Q_INVOKABLE Schedule() {} bool operator ==(const Schedule &rhs) const {return true;} };
// Main.qml import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Window Window { id: mainWindow width: 640 height: 480 visible: true property schedule newSchedule: ({ }) Switch { onClicked: { console.log("switch is " + checked) newSchedule.maintenance = checked console.log("newSchedule.maintenance is " + newSchedule.maintenance) } } }
Output:
qml: switch is true qml: newSchedule.maintenance is false qml: switch is false qml: newSchedule.maintenance is false qml: switch is true qml: newSchedule.maintenance is false qml: switch is false qml: newSchedule.maintenance is false
I can provide the cmake file as well if desired, but it doesn't contain anything unusual.
@mzimmers said in Unable to change bools in C++ struct:
bool operator ==(const Schedule &rhs) const {return true;}
If you remove this non-sensical
operator==
your code works as expected.My guess is that the engine modifies a temp Schedule internally, checks the equality and assign it only if it's different. As it's always equal it won't modify it.
-
@mzimmers said in Unable to change bools in C++ struct:
bool operator ==(const Schedule &rhs) const {return true;}
If you remove this non-sensical
operator==
your code works as expected.My guess is that the engine modifies a temp Schedule internally, checks the equality and assign it only if it's different. As it's always equal it won't modify it.
@GrecKo bingo!
I'd just stubbed out that comparison function to satisfy the compiler, but you were absolutely right. In my app, I'd neglected to include the maintenance member in my comparison function. Seems to work fine now.
Kind of has me wondering -- if I set my compiler options to no optimization, I wonder if it would have worked...
Anyway, thanks to EVERYONE for the help on this.
-
M mzimmers has marked this topic as solved on