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

How to avoid clicking button twice in Qt



  • Hello !

    I want to avoid clicking button twice during sometime.

    I tried some method in the following
    Method 1

    int clicktime = 0;
    void start()
    {
       ui->button->setEnabled(false);
       clicktime++;
       qDebug() << clicktime ;
       QThread::msleep(1000);
       ui->button->setEnabled(true);
    }
    

    when I clicked the button many times quickly, the function will run many times slowly.

    now I try to block the signals of button

    Method 2

    int clicktime = 0;
    void start()
    {
       ui->button->blocksignals(true);
       ui->button->setEnabled(false);
       clicktime++;
       qDebug() << clicktime ;
       QThread::msleep(1000);
       ui->button->setEnabled(true);
       ui->button->blocksignals(false);
    
    }
    

    After I push the button many times, quickly, the function also run many times.
    The result of Method 1 is the same with Method 2

    I tried to disconnected the button from function start.
    It is not work.

    Could any one can help me or get me some suggestions?
    Thanks in advance.



  • @LeonSu

    If possible, do not use the sleep () function in the GUI. Thereby causing the GUI to be blocked.

    See the following sample:

    connect(ui->button, &QPushButton::clicked, [&]{
        qDebug() << "clicked";
        ui->button->setEnabled(false);
        QTimer::singleShot(1000, [&]{ ui->button->setEnabled(true); });
    });
    
    


  • @Devopia53

    Thank you for your solution.

    Your solution is work well in Qt 5.9.3, but there are some errors in Qt 5.3.2.

    I find another solution is work OK, also

    int clicktime = 0;
    void start()
    {
       ui->button->blocksignals(true);
       ui->button->setEnabled(false);
       clicktime++;
       qDebug() << clicktime ;
       QThread::msleep(1000);
       ui->button->setEnabled(true);
       ui->button->blocksignals(false);
       QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
    }
    

    I think your method is batter.
    I will study how to using your method in Qt 5.3.2

    thanks again.
    LeonSu



  • @LeonSu said in How to avoid clicking button twice in Qt:

    QThread::msleep(1000);

    Sorry, but anything which involves QThread::msleep(); or ::sleep(), regardless of Qt version, is just wrong/bad/unusable/interferes unacceptably with user interaction.


  • Lifetime Qt Champion

    @LeonSu said in How to avoid clicking button twice in Qt:

    I will study how to using your method in Qt 5.3.2

    Just don't use lambda, use normal slot in older Qt versions instead...



  • @LeonSu
    BTW, what is so special about preventing another click within 1 second? Why not half a second or 2 seconds or whatever? Is your actual intention to prevent a second click while the code for the first click is still executing? In which case, your re-enablement of the button should not be on some kind of timer but rather when the first click handler's code has completed?



  • @LeonSu

    Your solution is work well in Qt 5.9.3, but there are some errors in Qt 5.3.2.

    Qt 5.3.2 supports C++11. If the compiler supports it, add the following directive in your .pro file. I tested it with the Qt 5.3.2 / MinGW 4.8.2 version.

    like this: CONFIG += c++11



  • @jsulm
    lambda can be compiled with C++11.
    but I get the error message : "no matching function for call to 'QTimer::singleShot(int, MainWindow::bigbuttontest()<lambda()>'.....

    The Qt 5.3.2 does not support this method.
    There are only two overloaded functions.

    /
     void	singleShot(int msec, const QObject * receiver, const char * member)
     void      singleShot(int msec, Qt::TimerType timerType, const QObject * receiver, const char * member)
    

    In Qt 5.9.3 had ten overloaded functions

    void  singleShot(int msec, const QObject *receiver, const char *member)
    void  singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
    void  singleShot(int msec, const QObject *receiver, PointerToMemberFunction method)
    void  singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, PointerToMemberFunction method)
    void singleShot(int msec, Functor functor)
    void singleShot(int msec, Qt::TimerType timerType, Functor functor)
    void singleShot(int msec, const QObject *context, Functor functor)
    void singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor)
    void singleShot(std::chrono::milliseconds msec, const QObject *receiver, const char *member)
    void singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
    
    

    @JonB
    I try to avoid to clicking button twice during 1 second.

    @Devopia53
    Qt 5.3.2 does not support this method.



  • @LeonSu

    As suggested by @jsulm, use an alternative string-based SLOT () macro.


Log in to reply