Подтвердить что ты не робот

Как включить дочерние мыши наведите курсор в родительском MouseArea с помощью QML?

Я хочу реализовать следующий сценарий в QML.

Scenario


Вот пример/упрощенный делегат для элемента ListView:

Component {
    Item {
         id: container
         MouseArea {
         anchors.fill: parent
         hoverEnabled: true

         onClicked: {
             container.ListView.view.currentIndex = index
             container.forceActiveFocus();
         }
         onEntered: {
             actionList.state = "SHOW";
             myItem.state = "HOVER"
         }
         onExited: {
             actionList.state = "HIDE";
             myItem.state = "NORMAL"
         }
         Rectangle {
             id: myItem
             color: "gray"
             anchors.fill: parent
             Row {
                 id: actionList
                 spacing: 5; anchors.fill: parent
                 Image {
                     id: helpAction
                     source: ""    //Some image address
                     width: 16; height: 16; fillMode: Image.PreserveAspectFit
                     states: [
                         State {
                             name: "NORMAL"
                             PropertyChanges { target: helpAction; opacity: 0.7 }
                         },
                         State {
                             name: "HOVER"
                             PropertyChanges { target: helpAction; opacity: 1.0 }
                         }
                     ]
                     MouseArea {
                         hoverEnabled: true
                         anchors.fill: parent

                         onEntered: {
                             parent.state = "HOVER";
                         }
                         onExited: {
                             parent.state = "NORMAL";
                         }
                     }
                     states: [
                         State {
                             name: "SHOW"
                             PropertyChanges { target: actionList; visible: false }
                         },
                         State {
                             name: "HIDE"
                             PropertyChanges { target: actionList; visible: true }
                         }
                     ]
                 }

                 //Other action buttons...

                 states: [
                     // `NORMAL` and `HOVER` states definition here...
                 ]
             }
         }
    }
}

Но у меня проблема с MouseArea.
Внутренний MouseArea (actionButton) не работает должным образом для события entered. Когда мышь вводит кнопку действия, внешний MouseArea запускает событие exited.

Есть ли ошибка в моем коде? Как правило, как реализовать такой сценарий в QML?

4b9b3361

Ответ 1

Я столкнулся с этой же проблемой и наткнулся на ответ в документации QtQuick 5.0 для MouseArea. Ответ на это на самом деле довольно простой.

Если вы хотите включить дочерние мыши наведите курсор в родительский MouseArea, сделайте дочерний MouseArea дочерний элемент родительского MouseArea:

MouseArea {
    id: parent

    MouseArea {
        id: child
    }
}

Поскольку у меня есть собственный тип Widget, который будет использоваться в качестве родительского представления, я получил свойство default, являющееся дочерними элементами MouseArea:

Item {
    default property alias children: mouseArea.data

    MouseArea {
        id: mouseArea
    }
}

Ответ 2

создавать состояния для каждого состояния элементов в представлении, тогда вы можете использовать такие вещи, как операторы или операторы case для изменения этих свойств. Другими словами, попробуйте не устанавливать свои элементы в работу с MouseArea, а по свойствам. Свойства элементов для работы с заданными свойствами Я надеюсь, что это поможет, если не здесь, например:

EDIT Я добавил, что цвет будет прозрачным. если нет мыши, что бы это ни было. Если бы я использовал изображение, я использовал бы прозрачность, а затем добавил бы группу Behaviors. Но это рабочий

Пример

import QtQuick 2.0
Rectangle {
    width: 360
    height: 360
    property string state1:"OutMouse"
    property string state2: "OutMouse"
    property string state3: "OutMouse"
    property string state4: "OutMouse"
    Rectangle{
        id:blueRec
        width: parent.width
        height: parent.height / 6
        color: state1 === "InMouse" ? "blue" : "green"
        MouseArea{
            anchors.fill: blueRec
            hoverEnabled: true
            onEntered: state1 = "InMouse"
            onExited: {
                if (state1 === state2 || state3 || state4){
                    state1 = "InMouse"
                }
                if(state1 !== state2 || state3 || state4)
                {
                    state1 = "OutMouse"
                }
            }
        }
        Text {
            text: state1=== "InMouse"? qsTr("foo") :"bar"
            anchors.centerIn: blueRec
        }
        Row{
            width: parent.width
            height: parent.height / 4

            spacing: 2
            anchors{
                left: parent.left
                verticalCenter:  blueRec.verticalCenter
                leftMargin: blueRec.width / 12
            }
            Rectangle{
                id: rec1
                height: parent.height;
                width: height
                color: {
                    if  ( state3 === "InMouse")
                        return "gray"
                    if (state1 === "OutMouse")
                        return "transparent"
                    else
                        return "white"}
                MouseArea{
                    id: rec1M
                    anchors.fill: parent
                    hoverEnabled: true
                    onEntered:{
                        state1 = "InMouse"
                        state2 = "InMouse"
                    }
                    onExited: state2 = "OutMouse"
                }
            }

            Rectangle{
                id: rec2
                height: parent.height ;
                width: height
                color: {
                    if  (state3 === "InMouse")
                        return "gray"
                    if (state1 === "OutMouse")
                        return "transparent"
                    else
                        return "white"
                }
                MouseArea{
                    id: rec2M
                    anchors.fill: parent
                    hoverEnabled: true
                    onEntered:{
                        state1 = "InMouse"
                        state3 = "InMouse"
                    }
                    onExited: state3 = "OutMouse"
                }
            }

            Rectangle{
                id: rec3
                height: parent.height;
                width: height
                color:{
                    if  (state4 === "InMouse")
                        return "gray"
                    if (state1 === "OutMouse")
                        return "transparent"
                    else
                        return "white"
                }
                MouseArea{
                    id:  rec3M
                    anchors.fill: parent
                    hoverEnabled: true
                    onEntered:{
                        state4 = "InMouse"
                        state1 = "InMouse"
                    }
                    onExited: state4 = "OutMouse"
                }
            }
        }
    }
}

Ответ 3

Iv'e пробовал несколько вещей, но не представляется возможным одновременно навешивать на два MouseArea. preventStealing и propagateComposedEvents, похоже, работают только при наличии события click. Но из внутреннего MouseArea вы можете вызвать сигнал entered() другого. Что-то вроде этого:

import QtQuick 2.1

Rectangle {
    width: 500
    height: 500

    Rectangle {
        width:300
        height: 300
        color: "red"

        MouseArea {
            id: big
            anchors.fill: parent
            hoverEnabled:true
            onEntered: {
                console.log("ENTERED BIG mousearea");
            }
            onExited: {
                console.log("EXITED BIG mousearea");
            }
        }

        Rectangle {
            anchors.centerIn: parent
            height: 100
            width: 100
            color: "green"

            MouseArea {
                anchors.fill: parent
                hoverEnabled:true
                onEntered: {
                    console.log("ENTERED small mousearea");
                    big.entered();
                }
                onExited: {
                    console.log("EXITED small mousearea");
                    big.exited();
                }
            }
        }
    }
}

Проблема заключается в том, что перед вызовом entered() будет вызываться сигнал exited() из содержащего MouseArea. Поэтому вам может потребоваться "задержать" изменение состояния в exited(), чтобы убедиться, что вы действительно хотите скрыть свои кнопки действий. Другим решением было бы сохранить текущую позицию мыши и скрыть кнопки ТОЛЬКО, если exited() вызывается с помощью мыши на одной из ее границ.

Ответ 4

Попробуйте следующее:

  • добавьте сигнал во внутреннюю область, которая испускается при вводе мыши.
  • Подключите сигнал к внешней области.
  • Сигнал заставляет внешнюю зону входить в зависание.

Выход мыши на обоих будет отменять состояние наведения. Когда вы перемещаете мышь с элементов управления, она должна работать правильно без дополнительного кода