Allen Shaw
Allen Shaw

Reputation: 1492

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

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.

Upvotes: 5

Views: 2504

Answers (3)

JarMan
JarMan

Reputation: 8277

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.

Upvotes: 7

Allen Shaw
Allen Shaw

Reputation: 1492

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
    }
}

Upvotes: 2

Cullen
Cullen

Reputation: 102

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.

Upvotes: 3

Related Questions