11

I have added onClick and onDoubleClick handlers to an item in QML, but both of the events get executed when I double click on the area. I don't know if it has something to do with checking if the clicks were generated by right mouse button. Also the order of placing the code does not affect the problem.

MouseArea {
    id: idModuleMouseDebug;
    parent: repeaterDelegate;
    anchors.fill: parent;
    acceptedButtons: Qt.LeftButton | Qt.RightButton

    onDoubleClicked: {
        if(mouse.button == Qt.RightButton) {

            console.log("Double Click");
        }
    }

    onClicked: {
        if(mouse.button == Qt.RightButton) {
            console.log("Single Click");
        }
    }
}
BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
Dumbo
  • 13,555
  • 54
  • 184
  • 288
  • Seems to be a regression of this bug: https://bugreports.qt.io/browse/QTBUG-19940 – cmannett85 Sep 17 '15 at 22:35
  • But it's not clear because it says "both of the events get executed when I *double* click", which is the expected behavior. – cdonts Sep 18 '15 at 00:14
  • @cdonts I think it is clear! If I click once, the `onClick` gets called. If I double click, both `onClick` and `onDoubleClick` get called! – Dumbo Sep 18 '15 at 01:24
  • 2
    Buddy, calm down. You don't need to shout every sentence. You clearly contradicted yourself when you said "well obviously when I click once, the doubleClick event shouldnt rise!" - it doesn't do that. If you click once, only "Single Click" is printed. That's what @cdonts was pointing out. Also, they are correct: the behaviour is expected. – Mitch Sep 18 '15 at 07:31

2 Answers2

11

You should use threshold for single click, like that:

{
    function singleClick(){
        print("Single click")
    }
    function dblClick(){
        print("Double Click")
    }
    MouseArea {
        id: idModuleMouseDebug;
        parent: repeaterDelegate;
        anchors.fill: parent;
        acceptedButtons: Qt.LeftButton | Qt.RightButton
        Timer{
            id:timer
            interval: 200
            onTriggered: singleClick()
        }
        onClicked: {
            if(mouse.button == Qt.RightButton) {
                if(timer.running)
                {
                    dblClick()
                    timer.stop()
                }
                else
                    timer.restart()
            }
        }
    }
}
Razieru
  • 492
  • 3
  • 9
  • This will result in a visible lag between the time you click and the time the interface responds (e.g. if it was a button). – Mitch Sep 18 '15 at 14:17
  • @Mitch I know that, but TS wants to split single click and double click (As far as I understand) while double click is always works after single click. – Razieru Sep 18 '15 at 17:05
  • 3
    I hope I never have to use this UI. :p – Mitch Sep 19 '15 at 08:00
  • @Mitch Wrong! fine tuning the timer provides nice reults you wont notice it – Dumbo Sep 19 '15 at 14:12
  • Can handle it without any delay!! but in qml. – S At Sep 08 '21 at 15:03
  • You guys realize there is no "without any delay" solution right ? Whether it is you or Qt that implements the solution, when a click is caught, the program has to wait and see if it was the first click of a double click or not. Otherwise any double click would fire the click event as well – Adrien Grosjean Feb 13 '23 at 14:46
4

As @cdonts said, this is the expected behaviour, in the widgets world as well:

#include <QtWidgets>

class Widget : public QWidget
{
public:
    Widget() {}

protected:
    void mousePressEvent(QMouseEvent *) {
        qDebug() << "press";
    }

    void mouseReleaseEvent(QMouseEvent *) {
        qDebug() << "release";
    }

    void mouseDoubleClickEvent(QMouseEvent *) {
        qDebug() << "double click";
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

Output:

press
release
double click
release

Think about how your expected behaviour would be implemented. In order to not emit the single click if it was eventually a double click, you'd need to hold off on emitting the single click until the double click delay/threshold had elapsed, and if no second click came, you'd have to artificially send the single click event late. It would be a mess.

Mitch
  • 23,716
  • 9
  • 83
  • 122