szumial
szumial

Reputation: 73

Setting minimum and current values on QSpinBox calls valueChanged slot automatically leading to unwanted behavior

I've noticed that setting the minimum and current values allowed for a QSpinBox automatically calls the valueChanged slot. Interestingly, setting the maximum value doesn't result in a slot call. This leads to some unwanted behavior in my simple GUI program, resulting in redundant API calls, sometimes bottlenecking the application performance. I assumed, that the valueChanged slot is only meant to be called on user action (changed with the small arrow button or typed from keyboard). Is this intended behavior? Here's what my program roughly looks like:

Added a QSpinBox with QtDesigner. The properties of this object are configured in the MainWindow constructor as such:

ui->spinBox->setMinimum(100);
ui->spinBox->setMaximum(100000);
ui->spinBox->setValue(apiCall->getValue()); // retrieve the correct setting from external API

Added a valueChanged slot using QtDesigner.

void MainWindow::on_spinBox_valueChanged(int arg1)
{
    qDebug() << "valueChanged called with arg: " << arg1;
    apiCall->setValue(arg1); // Set a given value in external API
}

What I see from qDebug's output at program launch:

valueChanged called with arg: 100

valueChanged called with arg: [value retrieved from an external API call]

Upvotes: 0

Views: 888

Answers (1)

as I suggested, it is better to 1st setup the object and finally connect the signals and slots

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
    //1st set the object up
    ui->spinBox->setMinimum(10);
    ui->spinBox->setMaximum(20);
    ui->spinBox->setValue(15);
    
    //then connect
    connect(ui->spinBox, qOverload<int>(&QSpinBox::valueChanged), this, [](int newValue)
    {
        qDebug() << "NewValue: " << newValue;
    });

but what if your code is designed to dynamically change those min and max values after you connected the signal slots???

then in that case you can : block the signals of the QSpinbox like:

//then connect
connect(ui->spinBox, qOverload<int>(&QSpinBox::valueChanged), this, [](int newValue)
{
    qDebug() << "NewValue: " << newValue;
});

ui->spinBox->blockSignals(true);
//1st set the object up
ui->spinBox->setMinimum(10);
ui->spinBox->setMaximum(20);
ui->spinBox->setValue(15);
ui->spinBox->blockSignals(false);

so as you can see, in this 2nd case, blockSignal(true) will "turn off" the signal emitted by the QObject so nothing is triggered

Upvotes: 1

Related Questions