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
Forum Updated to NodeBB v4.3 + New Features

duplicate execution of QSpinBox arrow click when followed by long computation

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 1.1k 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