Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Change a state of Roundbutton from C++
QtWS25 Last Chance

Change a state of Roundbutton from C++

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmlc++states
7 Posts 3 Posters 2.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    Eyal Erez
    wrote on 27 Sept 2017, 08:46 last edited by
    #1

    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:

    1. http://doc.qt.io/qt-5/qtqml-syntax-signals.html
    2. http://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html#attached-properties-and-attached-signal-handlers
    3. 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

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 27 Sept 2017, 10:14 last edited by
      #2

      Hi,

      Please show us the code you wrote. Without that it's pretty much Crystal Ball Debugging (tm).

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • E Offline
        E Offline
        Eyal Erez
        wrote on 27 Sept 2017, 10:51 last edited by
        #3

        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

        E 1 Reply Last reply 27 Sept 2017, 11:22
        0
        • E Eyal Erez
          27 Sept 2017, 10:51

          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

          E Offline
          E Offline
          Eeli K
          wrote on 27 Sept 2017, 11:22 last edited by
          #4

          @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.

          1 Reply Last reply
          1
          • E Offline
            E Offline
            Eyal Erez
            wrote on 27 Sept 2017, 12:03 last edited by
            #5

            @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

            E 1 Reply Last reply 27 Sept 2017, 12:32
            0
            • E Eyal Erez
              27 Sept 2017, 12:03

              @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

              E Offline
              E Offline
              Eeli K
              wrote on 27 Sept 2017, 12:32 last edited by
              #6

              @Eyal-Erez Nice. It's even shorter if you leave 'property string btnState' out and use directly

              state: _activeVehicle ? _activeVehicle.myBtnState :"A"
              
              E 1 Reply Last reply 27 Sept 2017, 13:16
              2
              • E Eeli K
                27 Sept 2017, 12:32

                @Eyal-Erez Nice. It's even shorter if you leave 'property string btnState' out and use directly

                state: _activeVehicle ? _activeVehicle.myBtnState :"A"
                
                E Offline
                E Offline
                Eyal Erez
                wrote on 27 Sept 2017, 13:16 last edited by
                #7

                @Eeli-K Correct :-)
                Wow i don't know if it good or bad that i just spent almost 2 days for less than 10 rows of code :-)

                1 Reply Last reply
                0

                7/7

                27 Sept 2017, 13:16

                • Login

                • Login or register to search.
                7 out of 7
                • First post
                  7/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved