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. Animate color in QML when C++ binding variable in modified
Forum Updated to NodeBB v4.3 + New Features

Animate color in QML when C++ binding variable in modified

Scheduled Pinned Locked Moved QML and Qt Quick
8 Posts 3 Posters 3.3k Views 1 Watching
  • 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.
  • G Offline
    G Offline
    godbod
    wrote on last edited by
    #1

    Hello everyone,

    Do you know how can I animate a Rectangle color property in QML when a C++ binding has been modified?

    my qml part look like this :
    @
    Rectangle
    {
    id : power_cons_tile
    // I want to animate the color when the new color is used
    color : model.power_cons < 100 ? "#008A00" : "#E51400"
    height: 85
    width : 175
    smooth: true
    ...
    @

    L'imagination est tout, c'est l’aperçu des futures attractions de la vie.

    1 Reply Last reply
    0
    • P Offline
      P Offline
      portoist
      wrote on last edited by
      #2

      Could you also post related C++ code?

      1 Reply Last reply
      0
      • L Offline
        L Offline
        Lucijan
        wrote on last edited by
        #3

        It doesn't make sense to me to animate the color like that since you haven't given an initial color. That is, you are assigning either the green or the red color and it will be the initial color so there's nothing to animate to. But if power_cons were to change later, then you could animate the color using states.

        Here's a small demo using height instead of model.power_cons. When the height of the rectangle changes (you can just drag the window in this case) the onHeightChanged() signal will be sent. When the height of the rectangle becomes higher than 100, the state will be changed to "red", when it becomes lower than 100 it will change back to the default state "".

        @import QtQuick 2.0

        Rectangle
        {
        id: power_cons_tile
        // I want to animate the color when the new color is used
        color: "#008A00" //"#E51400"
        height: 85
        width: 175
        smooth: true

        onHeightChanged: {
            if(height >= 100)
                state = "red";
            else
                state = "";
        }
        
        states: [
            State {
                name: "red"
                PropertyChanges {
                    target: power_cons_tile
                    color: "#E51400"
                }
            }
        ]
        
        transitions: [
            Transition {
                from: ""
                to: "red"
                ColorAnimation {
                    duration: 400
                    easing.type: Easing.InOutQuad
                }
            },
            Transition {
                from: "red"
                to: ""
                ColorAnimation {
                    duration: 400
                    easing.type: Easing.InOutQuad
                }
            }
        ]
        

        }
        @

        Hopefully, this will point you in the right direction, even if it's not exactly what you're looking for.

        1 Reply Last reply
        0
        • G Offline
          G Offline
          godbod
          wrote on last edited by
          #4

          Here is the C++ code :

          @
          #include "Model.h"

          Model::Model()
          {
          m_temperature = 0;
          m_power_cons = 0;

          temp = new Temperature();
          pwr = new Power_Cons();

          QObject::connect(&timer_temp, SIGNAL(timeout()), this, SLOT(getTemperatureFromSensor()));
          QObject::connect(&timer_pwr, SIGNAL(timeout()), this, SLOT(getPower_ConsFromSensor()));

          timer_temp.start(500);
          timer_pwr.start(3000);
          }

          void Model::getTemperatureFromSensor()
          {
          setTemperature(temp->temperature_sensor());
          }

          void Model::getPower_ConsFromSensor()
          {
          setPower_Cons(pwr->power_cons_sensor());
          }

          int Model::getTemperature()
          {
          return m_temperature;
          }

          int Model::getPower_Cons()
          {
          return m_power_cons;
          }

          void Model::setTemperature(int c)
          {
          if(c!=m_temperature)
          {
          m_temperature = c;
          emit temperatureUpdated();
          }
          }

          void Model::setPower_Cons(int c)
          {
          if(c!=m_power_cons)
          {
          m_power_cons = c;
          emit power_consUpdated();
          }
          }
          @

          Why should I initiate a color with a value since the binding does it?
          My aim is only to (smoothly) change the color of the rectangle from green to red when the power consumption is higher than a certain value.
          You will agree, this is a correct Use Case.

          L'imagination est tout, c'est l’aperçu des futures attractions de la vie.

          1 Reply Last reply
          0
          • L Offline
            L Offline
            Lucijan
            wrote on last edited by
            #5

            Well if you don't want to animate it initially (it wouldn't make sense anyway), then it might be better to bind the power consumption to a custom property called e.g. powerConsumption and use states for animation. Something like this (I'm using height as a dummy for powerConsumption):

            @import QtQuick 2.0

            Rectangle
            {
            id: power_cons_tile
            // I want to animate the color when the new color is used
            color: "#008A00" //"#E51400"
            height: 85
            width: 175
            smooth: true

            property alias powerConsumption: power_cons_tile.height
            
            onPowerConsumptionChanged: {
                if(powerConsumption >= 100)
                    state = "red";
                else
                    state = "";
            }
            
            states: [
                State {
                    name: "red"
                    PropertyChanges {
                        target: power_cons_tile
                        color: "#E51400"
                    }
                }
            ]
            
            transitions: [
                Transition {
                    from: ""
                    to: "red"
                    ColorAnimation {
                        duration: 400
                        easing.type: Easing.InOutQuad
                    }
                },
                Transition {
                    from: "red"
                    to: ""
                    ColorAnimation {
                        duration: 400
                        easing.type: Easing.InOutQuad
                    }
                }
            ]
            

            }
            @

            1 Reply Last reply
            0
            • G Offline
              G Offline
              godbod
              wrote on last edited by
              #6

              Okay, Thnaks a lot, I understand.
              I will try it then. But can you please explain more why I should use a custom property.
              I am guessing, maybe the QML doesn't evaluate expressions? Espacially when I do :
              @
              color : model.power_cons < 100 ? "#008A00" : "#E51400"
              @
              Are you saying that when the binding updates the value within
              @
              model.power_cons
              @

              the expression is not evaluated, so an animation is not applicable on it?

              L'imagination est tout, c'est l’aperçu des futures attractions de la vie.

              1 Reply Last reply
              0
              • L Offline
                L Offline
                Lucijan
                wrote on last edited by
                #7

                I am not sure how it would work with model.power_cons, but you would need to react to the change of the power consumption, not the change of color, because if the color has already changed, then it makes no sense to animate it anymore (it has already changed to the destination color).

                If you don't want to use a custom property, then maybe you could make a C++ signal for when the power consumption changes and then handle the signal in QML. I've never tried that, so I don't know how you would go about doing that.

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  godbod
                  wrote on last edited by
                  #8

                  bq.
                  you would need to react to the change of the power consumption, not the change of color, because if the color has already changed, then it makes no sense to animate it anymore (it has already changed to the destination color).

                  this is logic.
                  I tested it, and it does work.

                  Thanks a lot

                  L'imagination est tout, c'est l’aperçu des futures attractions de la vie.

                  1 Reply Last reply
                  0

                  • Login

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