2016-07-02 2 views
2

radius: width/2의 사각형을 사용하는 기본 사용자 지정 단추가 있습니다. 이제 버튼에 MouseArea을 추가합니다. 그러나 MouseArea에는 제곱 된 모양이 있습니다. 즉, 둥근 버튼을 약간 벗어나 클릭하면 둥근 버튼 주변의 가상 사각형 모서리에서 클릭 이벤트가 발생합니다. 나는 어떻게 든 MouseArea 라운드도 만들 수 있습니까?QML에서 둥근 마우스 영역을 만드는 방법

import QtQuick 2.7 
    import QtQuick.Window 2.2 

    Window { 
     visible: true 
     width: 640 
     height: 480 
     title: qsTr("TestApp") 

     Rectangle { 
      id: background 
      anchors.fill: parent 
      color: Qt.rgba(0.25, 0.25, 0.25, 1); 


      Rectangle { 
       id: button 
       width: 64 
       height: 64 
       color: "transparent" 
       anchors.centerIn: parent 
       radius: 32 
       border.width: 4 
       border.color: "grey" 

       MouseArea { 
        anchors.fill: parent 
        onPressed: button.color = "red"; 
        onReleased: button.color = "transparent"; 
       } 
      } 

     } 
    } 
+0

'clip : true'를'button'으로 설정하면 작동할까요? 그냥 지금 테스트 할 수 없습니다. – folibis

+0

@folibis : 불행히도 아닙니다. 버튼에'''clip : true''를 추가했지만 문제는 변하지 않았습니다. 고맙습니다. – Varius

답변

9

, PieMenu에서 코드를 훔치는 여기 RoundMouseArea.qml입니다 :

import QtQuick 2.0 

Item { 
    id: roundMouseArea 

    property alias mouseX: mouseArea.mouseX 
    property alias mouseY: mouseArea.mouseY 

    property bool containsMouse: { 
     var x1 = width/2; 
     var y1 = height/2; 
     var x2 = mouseX; 
     var y2 = mouseY; 
     var distanceFromCenter = Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2); 
     var radiusSquared = Math.pow(Math.min(width, height)/2, 2); 
     var isWithinOurRadius = distanceFromCenter < radiusSquared; 
     return isWithinOurRadius; 
    } 

    readonly property bool pressed: containsMouse && mouseArea.pressed 

    signal clicked 

    MouseArea { 
     id: mouseArea 
     anchors.fill: parent 
     hoverEnabled: true 
     acceptedButtons: Qt.LeftButton | Qt.RightButton 
     onClicked: if (roundMouseArea.containsMouse) roundMouseArea.clicked() 
    } 
} 

당신은 다음과 같이 사용할 수 있습니다 :

import QtQuick 2.5 
import QtQuick.Window 2.2 

Window { 
    width: 640 
    height: 480 
    visible: true 

    RoundMouseArea { 
     id: roundMouseArea 
     width: 100 
     height: 100 
     anchors.centerIn: parent 

     onClicked: print("clicked") 

     // Show the boundary of the area and whether or not it's hovered. 
     Rectangle { 
      color: roundMouseArea.pressed ? "red" : (roundMouseArea.containsMouse ? "darkorange" : "transparent") 
      border.color: "darkorange" 
      radius: width/2 
      anchors.fill: parent 
     } 
    } 
} 

round mouse area gif

4

또 다른 옵션이 방법으로 C++/QML입니다 이 example에 설명되어 있습니다. 이 예제는 모든 모양의 마스크를 사용하는 방법을 제공합니다. 사용자의 요구에 맞게 사용자 정의 할 수 있습니다.

코드를 게시는 그대로 :

maskedmousearea.cpp QML에서

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); 
} 

사용법 :

qmlRegisterType<MaskedMouseArea>("Example", 1, 0, "MaskedMouseArea");

:

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

사용자 정의 항목을 등록

관련 문제