Change a state of Roundbutton from C++
-
Hello,
I've a button with 3 states("A", "B", "C"), Starting state is "A".
I verified that without the C++ code, just moving state in each press of the button the states are well define/working.When the button is pressed a C++ function is invoked and open QInputDialog. According to the answer i need to change the state of the button to "B" or to stay at state "A". (for now state "C" is not used).
My problem, i'm unable to change the state !!! :-(.
i've tried sending a signal from the C++ and catch it in the QML , i follow this directions:- http://doc.qt.io/qt-5/qtqml-syntax-signals.html
- http://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html#attached-properties-and-attached-signal-handlers
- http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html
but none of them work on me.. i must be missing something but i can't figure out what... :-(
did anybody can help??
Thanks
-
Hi,
Please show us the code you wrote. Without that it's pretty much Crystal Ball Debugging (tm).
-
No Problem, here is the code:
QML code :RoundButton { id: BoxLeft objectName: "BoxLeft" visible: true state: "A" states: [ State { name: "A" PropertyChanges { target: BoxLeft onClicked :{ //state = "B" _activeVehicle.A()} buttonImage: "/qmlimages/ZoomMinus.svg"} }, State { name: "B" PropertyChanges { target: BoxLeft onClicked: { //state = "C" _activeVehicle.B()} buttonImage: "/qmlimages/ZoomPlus.svg" } }, State { name: "C" PropertyChanges { target: BoxLeft enabled: false } } ] }
C++ code:
void Vehicle::A() { qDebug() << "Enter A"; int randomNumber = (qrand() % 9000)+1000; bool ok; userTry = QInputDialog::getInt(0, "Random Code", "enter 4 digit number", 0, 1000, 9999, 1, &ok); if (userTry !=randomNumber) return; //Don't change button state emit buttonStateChange(1); //1 is represent for "B" state }
_activeVehicle is a C++ object that is define like this(in the QML):
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
I don't add the B() code because i don't get to it.
I can see the "Enter A" and as you can see in the QML i verified that if i don't use the C++ code the state is change and working.I also deleted the code that i've added in order to receive the signal because it doesn't work :-(
Again, any help will be highly appreciated and surly be used by future QT/QML users.
@SGaist if more info is needed, just ask.
Thanks
-
@Eyal-Erez It's a bit difficult to follow what you're doing with your code. In a simple situation we have a c++ object, e.g. 'backend'. It's been set as a context property.
Backend backend; QQmlApplicationEngine* engine{new QQmlApplicationEngine()}; QQmlContext* ctx{engine->rootContext()}; ctx->setContextProperty("backend", &backend);
After that it's visible as a global object named 'backend' in QML.
Then in QML you call a method:backend.mySlotWhichEmitsASignal()
In QML you must have
Connections { target: backend onButtonStateChanged: console.log(buttonState) }
This works if buttonState is a property in Backend or if buttonStateChanged is a signal with one parameter named 'buttonState'.
You can do it even more simple way by binding a qml property with backend.buttonState property:
Item{
property int btnState: backend.buttonState
onBtnStateChanged: console.log(btnState)
}
So there's no need to catch the signal manually at all. This works automatically if Backend and its property is written correctly. -
@Eeli-K
Yes i agree, i'm adding a code to an Open-Source QGC(https://github.com/mavlink/qgroundcontrol) so i'm (still) having limited knowlage of the code(both C++ and QML).
For example they are calling:
qmlRegisterUncreatableType<Vehicle> ("QGroundControl.Vehicle", 1, 0, "Vehicle", "Reference only");
and in most tutorials they ask to call qmlRegisterType.Anyway, what solve my problem is the use of:
propery string(!!!not QString!!!) btnState: _activeVehicle ? _activeVehicle.myBtnState :"A"
state: btnState
and of course setting the Q_PROPERTY with the read,write and notify function.Thank you so much for the help... Hope that it will help others in the future..
Cheers