2

I have a QSpinbox whose range I am setting:

QSpinBox *SpinBox = new QSpinBox;
SpinBox->setRange(0, 100);

However, I'm able to manually enter a + sign which is not reflected in my slot.

connect (SpinBox, SIGNAL (valueChanged (QString)), this,
            SLOT (onSpinBoxChanged (QString)));

I tried replacing QString with int also. But + is not reflected in the slot.

How can I restrict entering the + sign?

I have referred some Qt and StackOverflow posts/answers of disabling the line-edit in the spinbox:

I tried to make the spinbox's line-edit ReadOnly but I am unable to do so since it's a const variable.

Some answers suggest inheriting the QSpinbox class.

Is there any other approach to restrict the + sign or disabling the QSpinbox's line-edit itself?

TrebledJ
  • 8,713
  • 7
  • 26
  • 48
george
  • 339
  • 3
  • 12

1 Answers1

3

A possible solution if you do not want to inherit from the QSpinBox class is to use eventFilter, in the following code I show an example:

#include <QApplication>
#include <QSpinBox>
#include <QLineEdit>
#include <QKeyEvent>

class PlusRemoveHelper: public QObject{
public:
    using QObject::QObject;
    void addWidget(QWidget *widget){
        if(widget){
            widgets.append(widget);
            widget->installEventFilter(this);
        }
    }
public:
    bool eventFilter(QObject *watched, QEvent *event) override
    {
        if(std::find(widgets.begin(), widgets.end(), watched) != widgets.end()
                && event->type() == QEvent::KeyPress){
            QKeyEvent *keyevent = static_cast<QKeyEvent *>(event);
            if(keyevent->text() == "+")
                return true;
        }
        return  QObject::eventFilter(watched, event);
    }
private:
    QWidgetList widgets;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QSpinBox w;
    w.setRange(0, 100);
    PlusRemoveHelper helper;
    helper.addWidget(&w);
    w.show();

    return a.exec();
}

You can implement the same logic if you are inside a widget:

*.h

...
class QSpinBox;

class SomeClass: public SuperClass
{
...
public:
    bool eventFilter(QObject *watched, QEvent *event);
private:
    ...
    QSpinBox *SpinBox
};

*.cpp

SomeClass::SomeClass(...):
  SuperClass(..)
{
    SpinBox = new QSpinBox;
    SpinBox->setRange(0, 100);
    SpinBox->installEventFilter(this):
}


bool SomeClass::eventFilter(QObject *watched, QEvent *event){
    if(watched == SpinBox && event->type() == QEvent::KeyPress){
        QKeyEvent *keyevent = static_cast<QKeyEvent *>(event);
        if(keyevent->text() == "+")
            return true;
    }
    return  SomeClass::eventFilter(watched, event);
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thanks for the detailed answer @eyllanesc..I tried your first example..I tried with a ui form spinbox: **ui->spinBox->setRange(0, 100); PlusRemoveHelper helper;helper.addWidget((ui->spinBox));** But it is still accepting '+' sign.Am I missing something in the form? – george Sep 21 '18 at 09:19
  • @george If you realize helper would be a local variable that would be deleted when the function where it was created is finished, the solution is to create it in the heap to change it to: `ui->spinBox->setRange(0, 100); PlusRemoveHelper* helper = new PlusRemoveHelper(this); helper->addWidget(ui->spinBox);` – eyllanesc Sep 21 '18 at 09:26
  • Thanks @eyllanesc..I think the first solution will be apt for my case,since I have around 10 to 20 spinboxes.So adding them all to the **QWidgetList** should make them all restrict **'+' sign**,irrespective of in which class they are created right? – george Sep 21 '18 at 10:45