2015-01-07 69 views
2

有两种MouseAreas具有两个不同的责任和一个(绿色)定位部分上的其他(红色)的顶部。我想改变光标的形状,只要红色 MA是悬停的(即使它在绿色 MA),我想绿色 MA对新闻和其他事情没有反应。如何改变光标形状在QML当鼠标区域覆盖有另一鼠标区域

两个MA的可能是在不同的文件,所以我不想让他们之间的显式依赖,如设置适当cursorShape在绿色每当containsMouse在红色变化。有没有办法来防止MouseArea处理光标形状的绿色

import QtQuick 2.4 
import QtQuick.Window 2.2 

Window { 
    visible: true 
    width: 200 
    height: 200 

    Rectangle { anchors.fill: parent; color: "yellow"; } 

    MouseArea { 
     width: 150 
     height: 150 
     hoverEnabled: true 
     cursorShape: Qt.OpenHandCursor 
     Rectangle { anchors.fill: parent; color: "red"; } 
     onPositionChanged: console.log("position", mouse.x, mouse.y) 
     onContainsMouseChanged: console.log("containsMouse", containsMouse) 
    } 
    MouseArea { 
     x: 50 
     y: 50 
     width: 150 
     height: 150 
     hoverEnabled: false 
     Rectangle { anchors.fill: parent; color: "green"; } 
     onPressed: console.log("Ahoj!") 
    } 
} 

回答

3

有没有办法通过MouseArea属性或任何其他现成的解决方案。 MouseArea总是设置一些光标形状 - 如果cursorShape属性未指定使用默认值(Qt.ArrowCursor) 您当然可以使用mapToItem()/mapFromItem()来解决此问题(如米奇建议)。但也有其他的可能:

您可以临时更改visiblefalse覆盖鼠标区域。
或者,如果两个MouseArea都是兄弟,则可以使用z属性来获取适合您需要的特定对象层次结构。

2

我不认为这是可能的,至少从QML内部是这样做的。绿色鼠标区域没有hoverEnabled设置为true,所以您不会收到任何位置更改。

处理这个问题的一个更好的方法是使用填充你感兴趣的最大面积较大MouseArea,并使用mapToItem()/mapFromItem()翻译的全球鼠标位置为本地坐标的针锋相对鼠标区域比较:

import QtQuick 2.4 
import QtQuick.Window 2.2 

Window { 
    id: window 
    visible: true 
    width: 200 
    height: 200 

    Rectangle { 
     anchors.fill: parent 
     color: "yellow" 
    } 

    MouseArea { 
     id: globalMouseArea 
     anchors.fill: parent 
     hoverEnabled: true 
    } 

    MouseArea { 
     id: redMouseArea 
     width: 150 
     height: 150 
     cursorShape: containsMouse ? Qt.OpenHandCursor : Qt.ArrowCursor 
     enabled: false 

     readonly property bool containsMouse: { 
      var relativePos = mapFromItem(globalMouseArea, globalMouseArea.mouseX, globalMouseArea.mouseY); 
      return contains(Qt.point(relativePos.x, relativePos.y)); 
     } 

     Rectangle { 
      anchors.fill: parent 
      color: "red" 
     } 
    } 
    Rectangle { 
     id: greenMouseArea 
     x: 50 
     y: 50 
     width: 150 
     height: 150 
     color: containsMouse ? "brown" : "green" 

     readonly property bool containsMouse: { 
      var relativePos = mapFromItem(globalMouseArea, globalMouseArea.mouseX, globalMouseArea.mouseY); 
      return contains(Qt.point(relativePos.x, relativePos.y)); 
     } 

     Connections { 
      target: globalMouseArea 
      onPressed: if (greenMouseArea.containsMouse) greenMouseArea.pressed() 
     } 

     signal pressed 
     onPressed: console.log("Ahoj!") 
    } 
} 

正如您所见,绿色鼠标区域不再是鼠标区域。似乎鼠标区域的堆叠顺序高于另一个鼠标区域将阻止鼠标下方区域的位置更改,即使较高的鼠标区域没有设置为true的hoverEnabled

此外,请注意,如果它不是QTBUG-41452,它会稍微简洁一些。也就是说,你可以缩短containsMouse表达:

readonly property bool containsMouse: contains(mapFromItem(globalMouseArea, globalMouseArea.mouseX, globalMouseArea.mouseY)) 

如果你担心这里的重复代码,那么你可以使用的函数:

import QtQuick 2.4 
import QtQuick.Window 2.2 

Window { 
    id: window 
    visible: true 
    width: 200 
    height: 200 

    Rectangle { 
     anchors.fill: parent 
     color: "yellow" 
    } 

    MouseArea { 
     id: globalMouseArea 
     anchors.fill: parent 
     hoverEnabled: true 
    } 

    function containsMouse(item) { 
     var relativePos = globalMouseArea.mapToItem(item, globalMouseArea.mouseX, globalMouseArea.mouseY); 
     return item.contains(Qt.point(relativePos.x, relativePos.y)); 
    } 

    MouseArea { 
     id: redMouseArea 
     width: 150 
     height: 150 
     cursorShape: window.containsMouse(redMouseArea) ? Qt.OpenHandCursor : Qt.ArrowCursor 
     enabled: false 

     Rectangle { 
      anchors.fill: parent 
      color: "red" 
     } 
    } 
    Rectangle { 
     id: greenMouseArea 
     x: 50 
     y: 50 
     width: 150 
     height: 150 
     color: containsMouse ? "brown" : "green" 

     readonly property bool containsMouse: window.containsMouse(greenMouseArea) 

     Connections { 
      target: globalMouseArea 
      onPressed: if (greenMouseArea.containsMouse) greenMouseArea.pressed() 
     } 

     signal pressed 
     onPressed: console.log("Ahoj!") 
    } 
} 

我使用了一个属性为环保鼠标区域,因为它会另外拨打containsMouse()两次,这是浪费。

+0

这样做也可以强制用户再次实现类似MouseArea的组件。项目堆叠信息也会丢失,因为没有其他类似于绿色的MA没有保护它,并且在这种情况下它应该得到新闻事件。 –

1

您可以像下面一样创建自己的CusorShapeArea。它将帮助您更轻松地控制光标形状。

首先创建C++类CursorShapeArea:

cursorshapearea.h 

#ifndef CURSORSHAPEAREA_H 
#define CURSORSHAPEAREA_H 

#include <QDeclarativeItem> 

class QsltCursorShapeArea : public QDeclarativeItem 
{ 
    Q_OBJECT 

    Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape NOTIFY cursorShapeChanged) 

public: 

    explicit QsltCursorShapeArea(QDeclarativeItem *parent = 0); 

    Qt::CursorShape cursorShape() const; 
    Q_INVOKABLE void setCursorShape(Qt::CursorShape cursorShape); 

private: 
    int m_currentShape; 

signals: 
    void cursorShapeChanged(); 
}; 

#endif // CURSORSHAPEAREA_H 

cursorshapearea.cpp

#include "cursorshapearea.h" 

QsltCursorShapeArea::QsltCursorShapeArea(QDeclarativeItem *parent) : 
    QDeclarativeItem(parent), 
    m_currentShape(-1) 
{ 
} 

Qt::CursorShape QsltCursorShapeArea::cursorShape() const 
{ 
    return cursor().shape(); 
} 

void QsltCursorShapeArea::setCursorShape(Qt::CursorShape cursorShape) 
{ 
    if (m_currentShape == (int) cursorShape) 
    return; 

    setCursor(cursorShape); 
    emit cursorShapeChanged(); 

    m_currentShape = cursorShape; 
} 

然后注册此QML类型:

#include <QtDeclarative> 
#include "cursorshapearea.h" 

int main(int argc, char **argv) 
{ 
... 
    qmlRegisterType<CursorShapeArea>("MyTools", 1, 0, "CursorShapeArea"); 
... 
} 

然后在QML使用它,在你的问题:

import QtQuick 1.1 
import CursorShapeArea 0.1 

Window { 
visible: true 
width: 200 
height: 200 

Rectangle { anchors.fill: parent; color: "yellow"; } 

MouseArea { 
    id: redArea 
    width: 150 
    height: 150 
    hoverEnabled: true 
    //cursorShape: Qt.OpenHandCursor 
    Rectangle { anchors.fill: parent; color: "red"; } 
    onPositionChanged: console.log("position", mouse.x, mouse.y) 
    onContainsMouseChanged: console.log("containsMouse", containsMouse) 
} 
MouseArea { 
    x: 50 
    y: 50 
    width: 150 
    height: 150 
    hoverEnabled: false 
    Rectangle { anchors.fill: parent; color: "green"; } 
    onPressed: console.log("Ahoj!") 
} 
CursorShapeArea { 
    anchors.fill: redArea 
    cursorShape: Qt.OpenHandCursor 
} 
} 
相关问题