Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent QML button multiple click in a short period?

Tags:

qt

qml

I hava a QML button, and I want to prevent the button to be clicked before my function call is finished.

I tried the code below and it's not working. Button does not toggle enabled/disabled within the clicked signal. I guess the binding does not take effect immediately.

import QtQuick
import QtQuick.Control

Button {
    onClicked: {
        console.log('clicked')
        this.enabled = false
        do_something()
        this.enabled = true
    }
}

I also tried pressed signal

Button {
    onPressed: {
        console.log('pressed')
        this.enabled = false
    }
    onClicked: {
        console.log('clicked')
        do_something()
        this.enabled = true
    }
}

But the onClicked signal is not triggered at all.

like image 915
Allen Shaw Avatar asked Jan 12 '21 16:01

Allen Shaw


3 Answers

If the enabled property binding doesn't work, you can always prevent your function from getting called yourself:

Button {
    onClicked: {
        if (this.enabled) {  // Don't allow multiple clicks
            console.log('clicked')
            this.enabled = false
            do_something()
            this.enabled = true
        }
    }
}

UPDATE:

In response to your own answer to your question, I'd suggest an alternative to a timer is Qt.callLater(). It will essentially post an event on the event queue rather than call the function directly. That allows just enough time for other processing to occur.

Button {
    id: btn
    onClicked: {
        console.log('clicked')
        this.enabled = false
        Qt.callLater(callback);
    }
    function callback() {
        do_something()
        btn.enabled = true
    }
}

But I'm still wondering if you ever tried my original answer, because I think it's much easier, and it should work.

like image 175
JarMan Avatar answered Nov 02 '22 02:11

JarMan


You can enclose the button onClicked properties within if statement like

if (this.enabled)
{
// Do something
}

This if statement would not allow multiple clicks on your button. You can also set other properties within this if statement like what should happen if the button is clicked or unclicked.

like image 22
Cullen Avatar answered Nov 02 '22 02:11

Cullen


Finally I find the answer myself. User setTimeout like html/javascript for a delay execution. Since QML do not have setTimeout, it needs to add a Timer.

import QtQuick
import QtQuick.Control

Timer { id: timer }

Button {
    id: btn
    onClicked: {
        console.log('clicked')
        this.enabled = false
        timer.interval = 100  // a short delay, enabled status would change properly.
        timer.triggered.connect(callback)
        timer.start()
    }
    function callback() {
        do_something()
        timer.triggered.disconnect(callback) // don't forget to remove the callback
        btn.enabled = true
    }
}
like image 22
Allen Shaw Avatar answered Nov 02 '22 00:11

Allen Shaw