Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QSpinBox::valueChanged with debugger breakpoint brain-damaged



  • Ubuntu 19.04, Qt 5.12.2 as supplied with Ubuntu, Qt Creator 4.8.1, gdb 8.2.91.

    I have spent over a day on the most unbelievable frustration, and I want my money back :@

    connect(ui->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::spinBoxValueChanged);
    
    void MainWindow::spinBoxValueChanged(int number)
    {
    }
    

    That's it. Run suitable, and click the up-arrow to increment the number. All is well....

    ...Put a breakpoint on the { or } line in spinBoxValueChanged(). Just that. Now, when you increment it hits the breakpoint. Continue. spinBoxValueChanged() gets called a second time (after first spinBoxValueChanged() has exited, with the same stack trace as first time) , with number 1 higher than before. So for every click spin box number is increased by 2 if you hit a breakpoint (but only by 1 if you remove/disable the breakpoint)!! :@:@

    Spent a day till I realized it is hitting any breakpoint anywhere when within valueChanged() or anything it calls which causes the second call behaviour. Only now that my code is sorted so I don't need to break can I actually get on, but if I ever need to break again in something it calls I will be back to bad behaviour.

    Anyone able to repro in similar/different environment? I would like to know wth is going on?



  • @Christian-Ehrlicher said in QSpinBox::valueChanged with debugger breakpoint brain-damaged:

    The problem is the click timer of QSpinBox. There is also a bug report about this in the bugtracker: https://bugreports.qt.io/browse/QTBUG-14259

    @Christian-Ehrlicher is a genius/life-saver! He also advised a workaround:

    connect(ui->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::spinBoxValueChanged, Qt::QueuedConnection);
    

    I don't know if it is always suitable, but specifying Qt::QueuedConnection for any QSpinBox::valueChanged connection makes it work for me whether I have any breakpoint or not, so I thought others would like to know.

    Thanks @Christian-Ehrlicher !



  • First a question: Why do yo overload the signal? The slot and signal both use int arguments so just connect it like this (or the new connect style)

    connect(ui->spinBox, SIGNAL(valueChanged(int), this, SLOT(spinBoxValueChanged(int));
    

    The behavior with the breakpoint really seems strange. It seems like something is broken with you gdb maybe? Do you get similar strange behavior with other code or only at that specific line?



  • @gde23 said in QSpinBox::valueChanged with debugger breakpoint brain-damaged:

    Why do yo overload the signal? The slot and signal both use int arguments so just connect it like this (or the new connect style)

    I do not understand what you mean. What I have written precisely is how you do it with "or the new connect style"..., and is exactly the "new style" equivalent of what you suggest, how else do you think it should be? Unless you or someone else say otherwise...? See the example at https://doc.qt.io/qt-5/qspinbox.html#valueChanged. Just to keep you happy, I changed over to your old style, and naturally it behaves identically: increment by 1 when no breakpoint, hit & incremented twice if I put in a breakpoint.

    gdb will not be "broken", and I don't think it will be to do with gdb per se. No, I have used gdb/Creator etc. everything is fine, just this one case. Hence my question & frustration! And why I'd like someone to explain how it can lead to the behaviour I see?


  • Lifetime Qt Champion

    The problem is the click timer of QSpinBox. There is also a bug report about this in the bugtracker: https://bugreports.qt.io/browse/QTBUG-14259



  • @Christian-Ehrlicher said in QSpinBox::valueChanged with debugger breakpoint brain-damaged:

    The problem is the click timer of QSpinBox. There is also a bug report about this in the bugtracker: https://bugreports.qt.io/browse/QTBUG-14259

    @Christian-Ehrlicher is a genius/life-saver! He also advised a workaround:

    connect(ui->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::spinBoxValueChanged, Qt::QueuedConnection);
    

    I don't know if it is always suitable, but specifying Qt::QueuedConnection for any QSpinBox::valueChanged connection makes it work for me whether I have any breakpoint or not, so I thought others would like to know.

    Thanks @Christian-Ehrlicher !


Log in to reply