Search code examples
c++qtsignalsslotqspinbox

How to get the value of a spin box just before it changes


Using Qt, I need to get the value of a spin box (by a signal) just before it changes.

I've got:

QSpinBox spinBoxWidth:
QSpinBox spinBoxScale;

I want to connect a signal from spinBoxWidth to spinBoxScale, so that the value of spinBoxScale is always "the Value of spinBoxWidth after changing", to "its value before changing".

Scale = width_new / width_old

I didn't find any slot in Qt which returns the old value of a spin box while changing the value. Can I somehow write a slot for that?


Solution

  • There are two ways of doing this:

    • Catch the change before it happens and store the old value using the event system (QKeyEvent, QMouseEvent). This is error-prone, as the value of spinBoxWidth can be set manually.
    • Connect spinBoxWidth's valueChanged(int) signal to a slot and reference the last value it was called with. I recommend this method.

    Try something like this:

    class MonitoringObject : public QObject
    {
        Q_OBJECT
        int lastValue;
        int currentValue;
        ...
    public Q_SLOTS:
        void onValueChanged(int newVal)
        {
            lastValue = currentValue;
            currentValue = newVal;
            if (lastValue == 0) //catch divide-by-zero
                emit ratioChanged(0);
            else
                emit ratioChanged(currentValue/lastValue);
        }
    Q_SIGNALS:
        void ratioChanged(int);
    

    After your signals are connected, the flow should look like this:

    • spinBoxWidth emits valueChanged(int)
    • MonitoringObject::onValueChanged(int) is invoked, does its work and emits ratioChanged(int)
    • spinBoxScale receives the signal in its setValue(int) slot and sets the appropriate value.