Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the right way to suppress Qt signals when values are explicitely set

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?

like image 403
braggPeaks Avatar asked Apr 02 '13 11:04

braggPeaks


1 Answers

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

like image 62
Ilya Kobelevskiy Avatar answered Nov 14 '22 13:11

Ilya Kobelevskiy