QML QQuickItem处理鼠标事件

使用QtQuick时,因为QML和C++都能处理鼠标事件,这就造成了麻烦。以我目前经验来看,两者不能并存。除非手动调用另一个。

QML鼠标事件处理

先说QML的鼠标事件处理,处理的事件和C++一样,像clicked, pressed, release,不再赘述。示例如下:

Rectangle {
    id: rect
    MouseArea{
        anchors.fill: parent //MouseArea也是Item,必须设定了它的大小才能工作,否则默认区域是0X0
        onClicked:{
            rect.doSomething()
            // 也可以是 "任何可访问对象".doSometing()
        }
    }
}

C++鼠标事件处理

Qt C++处理鼠标事件,相信用过Qt的人都比较熟悉,但要在QtQuick中使用C++对象来处理鼠标事件就有点麻烦了。以例子说明:

// main.cpp
#include 
#include 
#include 
class MyItem : public QQuickItem
{
public:
    MyItem()
    {
        // 以下3行是C++处理鼠标事件的前提,否则所有(C++)鼠标事件直接忽略
        setAcceptHoverEvents(true);
        setAcceptedMouseButtons(Qt::AllButtons);
        setFlag(ItemAcceptsInputMethod, true);
    }

    void mousePressEvent(QMouseEvent* event)
    {
        //除非非常清楚调用结果是自己想要的,否则千万不要调用注释这行!!!
        //因为QQuickItem::mousePressEvent()里仅仅调用了event->ignore(),会导致接下来的mouseMove和mouseRelease接受不到信号
        //QQuickItem::mousePressEvent(event);
        qDebug() << event->pos();
    }
    void mouseMoveEvent(QMouseEvent* event)
    {
        //除非非常清楚调用结果是自己想要的,否则千万不要调用注释这行!!!
        //因为QQuickItem::mouseMoveEvent()里仅仅调用了event->ignore(),会导致接下来的mouseRelease接受不到信号
        //QQuickItem::mouseMoveEvent(event);
        qDebug() << event->pos();
    }
    void mouseReleaseEvent(QMouseEvent* event)
    {
        //除非非常清楚调用结果是自己想要的,否则千万不要调用注释这行!!!
        //QQuickItem::mouseReleaseEvent(event);
        qDebug() << event->pos();
    }


    //处理MouseMoveEvent的关键!!!
    //不处理这个函数,mouseMoveEvent(QMouseEvent*)不会工作。
    void hoverMoveEvent(QHoverEvent* event) {
        QQuickItem::hoverMoveEvent(event);
        qDebug() << event->pos();
    }
};

int main(int argc, char** argv)
{
    QGuiApplication app(argc, argv);
    QQuickView* view = new QQuickView;
    qmlRegisterType("Test", 1, 0, "MyItem");
    view->setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view->show();
    return app.exec();
}

再说下QML部分

import QtQuick 2.4
import QtQuick.Controls 1.3
import Test 1.0

Rectangle {
    width: 400; height: 400; visible: true
    MyItem { // 这里最好不要再用MouseArea,否由C++鼠标事件很可能失效
        anchors.fill: parent
    }
    Button { x: 100;  y: 100; text: "Button" }
}

如果想把鼠标事件传递给父对象

Rectangle{
    MouseArea{//现在呆处理item的鼠标pressed事件
    }
    MyItem {id: item
        MouseArea {onPressed: {
            mouse.accepted = false;
    }}
}

参考
http://stackoverflow.com/questions/30281955/catch-mousemoveevent-on-qt5s-qquickitem
http://stackoverflow.com/questions/23986201/mouse-events-not-handled-within-qquickitem-inheritor
http://stackoverflow.com/questions/18864420/handling-mouse-events-on-a-qquickitemhttp://stackoverflow.com/questions/29772736/qquickpainteditem-mousereleaseevent-gets-only-called-after-doubleclick

你可能感兴趣的:(QtQuick)