QML鼠标事件传递(鼠标穿透)

 

import QtQuick 2.12
import QtQuick.Window 2.12
 
Window {
    visible: true
    width: 640
    height: 480
 
    MouseArea{
        anchors.fill: parent
        onClicked: console.log("~root clicked")
        onDoubleClicked: console.log("~root double")
        onPressAndHold: console.log("~root hold")
    }
 
    //item的层级在root之上(因为他写在mousearea的后面,又是同级的)
    Rectangle{
        width: 200
        height: 200
        color: "green"
 
        MouseArea{
            anchors.fill: parent
            //是否传递到被覆盖的MouseArea
            propagateComposedEvents: true
            onClicked: {
                console.log("item clicked")
                //组合事件可以不写处理程序,或者accepted为false
                mouse.accepted = false
            }
            onDoubleClicked: console.log("item double")
            //onPressAndHold: console.log("item hold")
        }
    }
}

import QtQuick 2.12
import QtQuick.Window 2.12
 
Window {
    visible: true
    width: 640
    height: 480
 
    MouseArea{
        anchors.fill: parent
        onPressed: console.log("~root pressed")
        onReleased: console.log("~root released")
    }
 
    //item的层级在root之上(因为他写在mousearea的后面,又是同级的)
    Rectangle{
        width: 200
        height: 200
        color: "green"
 
        MouseArea{
            anchors.fill: parent
            //是否传递到被覆盖的MouseArea
            //propagateComposedEvents: true
            onPressed: {
                console.log("item pressed")
                mouse.accepted=false
            }
            onReleased: {
                console.log("item released")
                mouse.accepted=true
            }
        }
    }
}

#pragma once
#include <QCoreApplication>
#include <QHoverEvent>
// quick-private
#include <QtQuick/private/qquickmousearea_p.h>
 
// 转发hover事件
// 这里继承QQuickMouseArea重写接口转发,也可以用事件过滤转发
class MyMouseArea : public QQuickMouseArea
{
    Q_OBJECT
    Q_PROPERTY(QQuickMouseArea *forwardTo READ getForwardTo WRITE setForwardTo NOTIFY forwardToChanged)
public:
    using QQuickMouseArea::QQuickMouseArea;
 
    QQuickMouseArea *getForwardTo() const {
        return forwardTo;
    }
    void setForwardTo(QQuickMouseArea *forward) {
        if (forwardTo != forward) {
            forwardTo = forward;
            emit forwardToChanged();
        }
    }
 
protected:
    void hoverEnterEvent(QHoverEvent *event) override {
        QQuickMouseArea::hoverEnterEvent(event);
        doForward(event);
    }
    void hoverMoveEvent(QHoverEvent *event) override {
        QQuickMouseArea::hoverMoveEvent(event);
        doForward(event);
    }
    void hoverLeaveEvent(QHoverEvent *event) override {
        QQuickMouseArea::hoverLeaveEvent(event);
        doForward(event);
    }
    void doForward(QHoverEvent *event) {
        if (!forwardTo) {
            return;
        }
        // TODO 这里没有处理交叠部分,而是直接转发了
        QHoverEvent hover{event->type(),
                          mapToItem(forwardTo, event->posF()),
                          mapToItem(forwardTo, event->oldPosF()),
                          event->modifiers()};
        // 使用send多个MouseArea之间移动时保持一定的处理顺序
        QCoreApplication::sendEvent(forwardTo, &hover);
        // QCoreApplication::sendEvent(forwardTo, event);
    }
 
signals:
    void forwardToChanged();
 
private:
    // 事件转发到对应的MouseArea
    QQuickMouseArea *forwardTo{nullptr};
};

import QtQuick 2.12
import QtQuick.Window 2.12
 
Window {
    visible: true
    width: 640
    height: 480
 
    MouseArea{
        anchors.fill: parent
        onPressed: console.log("~root pressed")
        onClicked: console.log("~root clicked")
    }
 
    //item的层级在root之上(因为他写在mousearea的后面,又是同级的)
    Rectangle{
        width: 200
        height: 200
        color: "green"
 
        MouseArea{
            anchors.fill: parent
            //是否传递到被覆盖的MouseArea
            //propagateComposedEvents: true
            onPressed: mouse.accepted=false
        }
    }
}

import QtQuick 2.12
import QtQuick.Window 2.12
 
Window {
    visible: true
    width: 640
    height: 480
 
    MouseArea{
        anchors.fill: parent
        onPressed: console.log("~root pressed")
        onClicked: console.log("~root clicked")
    }
 
    Rectangle{
        width: 200
        height: 200
        color: "green"
 
        MouseArea{
            anchors.fill: parent
            //是否传递到被覆盖的MouseArea
            propagateComposedEvents: true
            onPressed: {
                console.log("item pressed")
                mouse.accepted=true
            }
            /*onClicked: {
                console.log("item clicked")
                mouse.accepted=false
            }*/
        }
    }
    MouseArea{
        anchors.fill: parent
        onPressed: {
            console.log("surface pressed")
            mouse.accepted=false
        }
        onClicked: {
            console.log("surface clicked")
            mouse.accepted=false
        }
    }
}

#pragma once
#include <QQuickItem>
#include <QEvent>
#include <QCursor>
#include <QDebug>
 
// 过滤点击事件
class MouseItem : public QQuickItem
{
    Q_OBJECT
public:
    explicit MouseItem(QQuickItem *parent = nullptr)
        : QQuickItem(parent) {
        setAcceptedMouseButtons(Qt::AllButtons);
        // 只过滤点击事件就别设置 cursorShape
        // setCursor(QCursor(Qt::PointingHandCursor));
        // unsetCursor();
    }
    void mousePressEvent(QMouseEvent *event) override {
        qDebug()<<"press"<<event->pos();
        event->ignore();
    }
    void mouseReleaseEvent(QMouseEvent *event) override {
        // press ignore 后不会进入该 release 了
        qDebug()<<"release"<<event->pos();
        event->ignore();
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值