Question

I got a from QWidget derived class that holds three QSpinBoxes (e.g. coordinates). The valueChanged() signal is connected and is emitted in at least these three cases:

  1. up/down button
  2. manually entered number
  3. setValue()

However, when using setValue(), I want to suppress the signal(s), since I don't want to have (three) signals. In my understanding, there are two ways to handle this:

  1. QObject::blockSignals()
  2. using a flag that indicates whether the values were explicitely set

Both variants work, but I think they are not straight-forward at all: For the first one, I generally block all signals AND I need to set blockSignals(true) for all underyling widgets (blockSignals doesn't block children QObjects in my application). For the second one, I need to query the flag in every update method AND the signals are raised although I don't need them.

Are there any general designing patterns that prevent such behavior? If not, what variant would you prefer?

Was it helpful?

Solution

The third option would be to subclass QSpinBox, implement desired functionality there, and used derived class instead of QSpinBox - this hides all associated complexity in derived class and allows you use it just like QSpinBox.

For example, following class

myQSpinBox.h

#ifndef MYQSPINBOX_H
#define MYQSPINBOX_H

#include <QSpinBox>

class myQSpinBox : public QSpinBox
{
    Q_OBJECT
public:
    myQSpinBox(QWidget * parent = 0 );
protected:
    bool valueBeingSet;
public slots:
    void setValue (int val);
private slots:
    void On_valueChanged(int val);
signals:
    void valueChangedNotBySet(int val);
};

#endif // MYQSPINBOX_H

myQSpinBox.cpp

#include "myQSpinBox.h"

myQSpinBox::myQSpinBox(QWidget * parent)
        : QSpinBox(parent)
        , valueBeingSet(false)
{
    connect(this,SIGNAL(valueChanged(int)),this,SLOT(On_valueChanged(int)));
}

void    myQSpinBox::setValue ( int val )
{
    valueBeingSet = true;
    QSpinBox::setValue(val);
    valueBeingSet = false;
}

void myQSpinBox::On_valueChanged(int val)
{
    if(!valueBeingSet)
        emit valueChangedNotBySet(val);
}

will emit valueChangedNotBySet(int); in cases 1. and 2., but not in case 3., keeping all QSpinBox functionality intact

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top