Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. duplicate execution of QSpinBox arrow click when followed by long computation
Qt 6.11 is out! See what's new in the release blog

duplicate execution of QSpinBox arrow click when followed by long computation

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 2.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Joachim W
    wrote on last edited by
    #1

    Under Linux, clang5, Qt5.10, the following misbehaviour is quite reproducible:

    If a QSpinBox or QDoubleSpinBox is connected to a function that takes longer than about 0.5 seconds, then a single click on an up or down arrow is followed by a second incrementation and a second execution of the connected function.

    Minimal example:

    int delay = 600;
    auto* test = new QSpinBox;
    connect(test, _SLOT_(QSpinBox, valueChanged, int), [this](int val) {
            qDebug() << "GOT VALUE " << val;
            QThread::msleep(delay);
            qDebug() << "WOKE UP "; });
    

    One single click on the "up" arrow will cause the following:

    GOT VALUE 1
    [delay]
    WOKE UP
    GOT VALUE 2
    [delay]
    WOKE UP
    

    Whereas with t of about 500 or smaller, I get the expected

    GOT VALUE 1
    [delay]
    WOKE UP
    

    What could be the cause? How to further analyze?

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      If you stop it for longer it will probably increase by even more that 1.
      You are blocking the event loop before it process the QEvent::MouseButtonRelease so it behaves like if you are holding the mouse button down.
      Try:

      int delay = 600;
      auto* test = new QSpinBox;
      connect(test, QOverload<int>::of(&QSpinBox::valueChanged), test, [delay](int val) {
              qDebug() << "GOT VALUE " << val;
              QThread::msleep(delay);
              qDebug() << "WOKE UP "; }, Qt::QueuedConnection);
      

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      5
      • J Offline
        J Offline
        Joachim W
        wrote on last edited by VRonin
        #3

        Try: ...

        Tried. Still incrementing twice.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          Joachim W
          wrote on last edited by Joachim W
          #4

          So upon QSpinBox::valueChanged, I ought to wait for QEvent::MouseButtonRelease?

          That would have no undesirable side effects?

          Is there some example code?

          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by VRonin
            #5

            The problem is definetly what I described but 1 event loop cycle is not enough to capture the release.
            This solves it but I agree it's ugly

            #include <QApplication>
            #include <QStyle>
            #include <QTimer>
            #include <QDebug>
            #include <QThread>
            #include <QSpinBox>
            
            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
                QSpinBox wid;
                QObject::connect(&wid, QOverload<int>::of(&QSpinBox::valueChanged), &wid, [&wid](int val) {
                        QTimer::singleShot(1+qMax(
                            wid.style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate, 0, &wid)
                            ,wid.style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, 0, &wid)
                        ),&wid,[val](){
                            qDebug() << "GOT VALUE " << val;
                            QThread::msleep(600);
                            qDebug() << "WOKE UP ";
                        });
            
                });
                wid.show();
                return a.exec();
            }
            

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            5
            • Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by VRonin
              #6

              This could be the same as in QTBUG-14259

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              2

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved