QML两个MouseArea重叠在一起导致下方的MouseArea无法获取到鼠标点击事件

前言

QML两个MouseArea重叠在一起导致下方的MouseArea无法获取到鼠标点击事件

解决方案

当mouseArea与其它mouseArea项目重叠时,可以设置propagateComposedEvents属性为true来传播clicked,doubleClicked和pressedAndHold等事件。但是只有在mouseArea没有接受这些事件的时候,它们才可以继续向下传播。也就是说,当事件已经在一个mouseArea中进行处理,则需要在其事件处理器中设置MouseEvent.acceptd为false,这样该事件才能继续传播。

import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2

Window {
    id:mainWindow
    property int count: 0
    visible: true
    width: 400
    height: 400
    title: qsTr("Hello World")
    Rectangle{
        id:rect_1
        width: 100
        height: 100
        color: "cyan"
        MouseArea{
            anchors.fill: parent
            onClicked: {
                console.log("点击了青色的矩形");
            }
        }
    }
    Rectangle{
        id:rect_2
        x:50
        y:50
        width: 100
        height: 100
        color: "red"
        MouseArea{
            anchors.fill: parent
            propagateComposedEvents: true
            onClicked: {
                console.log("点击了红色的矩形");
                mouse.accepted = false;
            }
        }
    }
}

思考

在QML中处理较为简单,下面介绍如何在Widget中处理这种情况
在这里插入图片描述
有一个自定义的widget重写了void mousePressEvent(QMouseEvent *event)。当鼠标在上面点击时会打印出鼠标的位置。如果在上面在添加一个QPushButton发现如果点击在按钮上面只会执行按钮点击相关的函数。解决方案是自定义一个Button在处理点击事件时新建一个事件发送到父对象的widget中。
MyWidget.cpp

#include "MyWidget.h"
#include "ui_MyWidget.h"
#include <QDebug>
#include <QMouseEvent>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    //设置此属性,qss设置widget背景才能生效
    this->setAttribute(Qt::WA_StyledBackground);
}

MyWidget::~MyWidget()
{
    delete ui;
}

void MyWidget::mousePressEvent(QMouseEvent *event)
{
    qDebug() << QStringLiteral("点击了 x : %1; y : %2").arg(event->x()).arg(event->y());
}

MyWidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

namespace Ui {
class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = nullptr);
    ~MyWidget();
protected:
    void mousePressEvent(QMouseEvent *event) override;

private:
    Ui::MyWidget *ui;
};

#endif // MYWIDGET_H

MyPushButton.cpp

#include "MyPushButton.h"
#include <QMouseEvent>
#include <QPointF>
#include <QCoreApplication>

MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
{

}

void MyPushButton::mousePressEvent(QMouseEvent *event)
{
    if(this->parentWidget())
    {
        //将Button点击的坐标转换为父Widget的坐标后然后新建一个事件发送给父Widget
        QPointF point = mapTo(this->parentWidget(), event->pos());
        //注意这里的 new 不会造成内存泄漏,详见QT帮助文档 postEvent 的解释
        QMouseEvent *event_ = new QMouseEvent(event->type(), point, event->button(), event->buttons(), event->modifiers());
        QCoreApplication::postEvent(this->parentWidget(), event_);
    }
    QPushButton::mousePressEvent(event);
}

MyPushButton.h

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QWidget>
#include <QPushButton>

class MyPushButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyPushButton(QWidget *parent = nullptr);
protected:
    void mousePressEvent(QMouseEvent *event) override;

signals:

public slots:
};

#endif // MYPUSHBUTTON_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->widget->setStyleSheet("#widget{\
                                       background-color:pink\
                                   }");
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    qDebug() << QStringLiteral("按钮被点击了");
}

效果

最后可以发现点击按钮的同时,自定义的widgetmousePress函数也能够正确打印
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值