0

我目前正在学习如何使用 QML 中的 Shapes 来绘制更高级的组件。我正在尝试创建一个如下所示的按钮:

我的自定义按钮

当我尝试在 Shape 组件上应用 MouseArea 时,MouseArea 似乎无法捕获 Shape 上的事件。这是我的代码:

import QtQuick 2.13
import QtQuick.Shapes 1.13

Item
{
    Shape
    {
        id: myShape

        ShapePath {
            id: myButton

            strokeWidth:3.114000082015991
            strokeColor: "#000"
            miterLimit:7
            fillColor: "#ccc"
            capStyle:ShapePath.RoundCap
            PathSvg {
                path: "M392.4,205.9a132.34,132.34,0,0,1,31.7,49.2H575.6a289.67,289.67,0,0,0-12.9-49.2Z"
            }
        }
    }

    MouseArea
    {
        id: myMouseArea
        anchors.fill: myShape
        enabled: true
        hoverEnabled: true

        onEntered: myButton.fillColor = "yellow"
        onExited: myButton.fillColor = "green"
    }
}

所以我的问题是:是否可以首先使 Shape/ShapePath 可点击?如果是,该怎么做?

4

1 回答 1

0

此处提出了类似的问题,但他们只想要一个简单的圆圈。尽管如此,不接受的答案描述了一个可能对您有用的蒙面鼠标区域。它使用图像来定义蒙版区域。它最初来自一个 Qt示例程序

蒙面鼠标区域.cpp

MaskedMouseArea::MaskedMouseArea(QQuickItem *parent)
    : QQuickItem(parent),
      m_pressed(false),
      m_alphaThreshold(0.0),
      m_containsMouse(false)
{
    setAcceptHoverEvents(true);
    setAcceptedMouseButtons(Qt::LeftButton);
}

void MaskedMouseArea::setPressed(bool pressed)
{
    if (m_pressed != pressed) {
    m_pressed = pressed;
    emit pressedChanged();
    }
}

void MaskedMouseArea::setContainsMouse(bool containsMouse)
{
    if (m_containsMouse != containsMouse) {
    m_containsMouse = containsMouse;
    emit containsMouseChanged();
    }
}

void MaskedMouseArea::setMaskSource(const QUrl &source)
{
    if (m_maskSource != source) {
    m_maskSource = source;
    m_maskImage = QImage(QQmlFile::urlToLocalFileOrQrc(source));
    emit maskSourceChanged();
    }
}

void MaskedMouseArea::setAlphaThreshold(qreal threshold)
{
    if (m_alphaThreshold != threshold) {
    m_alphaThreshold = threshold;
    emit alphaThresholdChanged();
    }
}

bool MaskedMouseArea::contains(const QPointF &point) const
{
    if (!QQuickItem::contains(point) || m_maskImage.isNull())
    return false;

    QPoint p = point.toPoint();

    if (p.x() < 0 || p.x() >= m_maskImage.width() ||
    p.y() < 0 || p.y() >= m_maskImage.height())
    return false;

    qreal r = qBound<int>(0, m_alphaThreshold * 255, 255);
    return qAlpha(m_maskImage.pixel(p)) > r;
}

void MaskedMouseArea::mousePressEvent(QMouseEvent *event)
{
    setPressed(true);
    m_pressPoint = event->pos();
    emit pressed();
}

void MaskedMouseArea::mouseReleaseEvent(QMouseEvent *event)
{
    setPressed(false);
    emit released();

    const int threshold = qApp->styleHints()->startDragDistance();
    const bool isClick = (threshold >= qAbs(event->x() - m_pressPoint.x()) &&
                      threshold >= qAbs(event->y() - m_pressPoint.y()));

    if (isClick)
    emit clicked();
}

void MaskedMouseArea::mouseUngrabEvent()
{
    setPressed(false);
    emit canceled();
}

void MaskedMouseArea::hoverEnterEvent(QHoverEvent *event)
{
    Q_UNUSED(event);
    setContainsMouse(true);
}

void MaskedMouseArea::hoverLeaveEvent(QHoverEvent *event)
{
    Q_UNUSED(event);
    setContainsMouse(false);
}

QML 中的用法:

import Example 1.0
MaskedMouseArea {
    id: moonArea
    anchors.fill: parent
    alphaThreshold: 0.4
    maskSource: moon.source
}

注册自定义项:

qmlRegisterType<MaskedMouseArea>("Example", 1, 0, "MaskedMouseArea");
于 2020-07-24T13:46:21.323 回答