본문 바로가기
Development Solutions/Qt & QML

How to propagate QML mouse click events to child MouseArea (QML 마우스 클릭 이벤트를 하위 MouseArea가 전파 받는 방법)

by Dev Diary Hub 2024. 5. 20.
반응형

How to propagate QML mouse click events to child MouseArea

QML 마우스 클릭 이벤트를 하위 MouseArea가 전파 받는 방법

 

(추천) [초급] 6가지 프로젝트로 다지는 Qt 사용법 (+REST API)

https://inf.run/vLaL3

 

[초급] 6가지 프로젝트로 다지는 Qt 사용법 (REST API) | 코드브릿지 - 인프런

코드브릿지 | 6가지 프로젝트로 다지는 Qt QML과 C++ 실전 강의입니다. 다양한 형태의 UI 개발과 REST API 통신까지 아우르는 연습을 통해 실무 기본기를 닦아보세요!, 코딩테스트에만 쓰는 C++😂 다양

www.inflearn.com

 

(KOR)

 

QML에서 propagateComposedEvents 속성을 사용하면 이벤트가 부모와 자식 요소 모두에서 처리될 수 있도록 하여 이벤트 전파를 제어할 수 있습니다. 이 속성은 일반적으로 복잡한 사용자 인터페이스를 구현할 때 유용합니다. 예를 들어, 하위 MouseArea가 이벤트를 처리하면서도 상위 MouseArea가 해당 이벤트를 인식하고 추가 작업을 수행해야 할 경우에 사용됩니다.

 

아래 예제에서는 propagateComposedEvents 속성을 이용하여 부모 MouseArea가 자식 MouseArea에게 마우스 클릭 이벤트를 전파합니다.

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: "propagateComposedEvents Example"

    Rectangle {
        width: parent.width
        height: parent.height
        color: "lightgrey"

        // Parent MouseArea
        MouseArea {
            id: parentMouseArea
            anchors.fill: parent
            propagateComposedEvents: true // Enable event propagation
            onClicked: {
                console.log("Parent MouseArea clicked at:", mouse.x, mouse.y)
            }

            // Child Rectangle
            Rectangle {
                id: childRectangle
                width: 200
                height: 200
                color: "lightblue"
                anchors.centerIn: parent

                // Child MouseArea
                MouseArea {
                    id: childMouseArea
                    anchors.fill: parent
                    propagateComposedEvents: true // Enable event propagation
                    onClicked: {
                        console.log("Child MouseArea clicked at:", mouse.x, mouse.y)
                    }
                }
            }
        }
    }
}

 

위 코드에서, ApplicationWindow 내에 Rectangle이 있고, 이 Rectangle은 전체 창을 채웁니다. 이 Rectangle 안에는 MouseArea가 정의되어 있으며, 이 MouseArea는 propagateComposedEvents 속성을 true로 설정하여 자식 요소의 이벤트를 부모 요소로 전파할 수 있도록 합니다.

 

또한, Rectangle 안에 또 다른 Rectangle (childRectangle)이 있으며, 이 Rectangle은 부모 Rectangle의 중앙에 배치됩니다. 자식 Rectangle에는 또 다른 MouseArea가 있으며, 이 MouseArea 역시 propagateComposedEvents 속성을 true로 설정하여 이벤트를 부모에게 전파합니다.

 

MouseArea에는 onClicked 핸들러가 정의되어 있어 클릭 이벤트가 발생했을 콘솔에 메시지를 출력합니다. 이렇게 하면, 자식 MouseArea 클릭하면 자식의 클릭 이벤트가 처리된 부모 MouseArea 이벤트가 전파되어 부모의 클릭 이벤트도 처리됩니다.

반응형

추가 예제: 이벤트 전파와 중지


아래 예제는 자식 요소에서 특정 조건에 따라 이벤트 전파를 중지시키는 방법을 보여줍니다.

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: "Conditional Event Propagation Example"

    Rectangle {
        width: parent.width
        height: parent.height
        color: "lightgrey"

        // Parent MouseArea
        MouseArea {
            id: parentMouseArea
            anchors.fill: parent
            propagateComposedEvents: true
            onClicked: {
                console.log("Parent MouseArea clicked at:", mouse.x, mouse.y)
            }

            // Child Rectangle
            Rectangle {
                id: childRectangle
                width: 200
                height: 200
                color: "lightblue"
                anchors.centerIn: parent

                // Child MouseArea
                MouseArea {
                    id: childMouseArea
                    anchors.fill: parent
                    propagateComposedEvents: true
                    onClicked: {
                        console.log("Child MouseArea clicked at:", mouse.x, mouse.y)
                        if (mouse.x > width / 2) {
                            console.log("Stopping event propagation from Child MouseArea")
                            event.accepted = true // Stop propagation
                        }
                    }
                }
            }
        }
    }
}



위 코드에서 자식 `MouseArea`의 클릭 이벤트 핸들러에서 `mouse.x`가 `width / 2`보다 큰 경우 이벤트 전파를 중지하도록 조건을 추가했습니다. `event.accepted = true`를 설정하여 이벤트가 부모로 전파되지 않도록 합니다.

이 예제를 실행하면 다음과 같은 동작을 확인할 수 있습니다:

1. 자식 `MouseArea`의 왼쪽 절반을 클릭하면:
   - "Child MouseArea clicked at:" 메시지가 콘솔에 출력됩니다.
   - "Parent MouseArea clicked at:" 메시지가 이어서 콘솔에 출력됩니다.

2. 자식 `MouseArea`의 오른쪽 절반을 클릭하면:
   - "Child MouseArea clicked at:" 메시지가 콘솔에 출력됩니다.
   - "Stopping event propagation from Child MouseArea" 메시지가 콘솔에 출력됩니다.
   - 부모 `MouseArea`의 메시지는 출력되지 않습니다.

이렇게 하면 특정 조건에 따라 이벤트 전파를 제어할 수 있어 더욱 세밀한 이벤트 처리가 가능합니다.

 

(추천) [초급] 6가지 프로젝트로 다지는 Qt 사용법 (+REST API)

https://inf.run/vLaL3 

 

[초급] 6가지 프로젝트로 다지는 Qt 사용법 (REST API) | 코드브릿지 - 인프런

코드브릿지 | 6가지 프로젝트로 다지는 Qt QML과 C++ 실전 강의입니다. 다양한 형태의 UI 개발과 REST API 통신까지 아우르는 연습을 통해 실무 기본기를 닦아보세요!, 코딩테스트에만 쓰는 C++😂 다양

www.inflearn.com

 

 

 

[Eng]

 

In QML, the `propagateComposedEvents` property allows you to control event propagation by allowing events to be handled by both parent and child elements. This property is typically useful when implementing complex user interfaces. This is used, for example, when a child `MouseArea` is handling an event, but the parent `MouseArea` needs to recognize that event and perform additional actions.

The following example shows how to use `propagateComposedEvents` to handle mouse click events on both parent and child elements.

### Example code

```qml
import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
     visible: true
     width: 640
     height: 480
     title: "propagateComposedEvents Example"

     Rectangle {
         width: parent.width
         height: parent.height
         color: "lightgrey"

         // ParentMouseArea
         MouseArea {
             id: parentMouseArea
             anchors.fill: parent
             propagateComposedEvents: true // Enable event propagation
             onClicked: {
                 console.log("Parent MouseArea clicked at:", mouse.x, mouse.y)
             }

             // Child Rectangle
             Rectangle {
                 id: childRectangle
                 width: 200
                 height: 200
                 color: "lightblue"
                 anchors.centerIn: parent

                 //Child MouseArea
                 MouseArea {
                     id: childMouseArea
                     anchors.fill: parent
                     propagateComposedEvents: true // Enable event propagation
                     onClicked: {
                         console.log("Child MouseArea clicked at:", mouse.x, mouse.y)
                     }
                 }
             }
         }
     }
}
```

### explanation

In the code above, there is a `Rectangle` within an `ApplicationWindow`, and this `Rectangle` fills the entire window. Inside this `Rectangle`, a `MouseArea` is defined, which sets the `propagateComposedEvents` property to `true`, allowing events from child elements to propagate to the parent element.

Additionally, inside the `Rectangle` there is another `Rectangle` (childRectangle`), which is centered on the parent `Rectangle`. The child `Rectangle` has another `MouseArea`, which also propagates events to its parent by setting the `propagateComposedEvents` property to `true`.

Each `MouseArea` has an `onClicked` handler defined, which prints a message to the console when a click event occurs. This way, when a child `MouseArea` is clicked, the child's click event is handled and then the event is propagated to the parent `MouseArea`, which also handles the parent's click event.

### Execution result

If you run the example above, you can see the following behavior:

1. When you click on the child `MouseArea` (lightblue area):
    - The message "Child MouseArea clicked at:" is printed to the console.
    - The message “Parent MouseArea clicked at:” is subsequently printed to the console.

2. When you click on the parent `MouseArea` (lightgrey area):
    - The message "Parent MouseArea clicked at:" is printed to the console.

Like this, you can use the `propagateComposedEvents` property to cause events from a child `MouseArea` to propagate to the parent `MouseArea`. This allows you to create a flexible structure that can handle events on both parent and child elements when implementing complex user interfaces.

### Additional examples: Propagating and stopping events

The following example shows how to stop event propagation based on certain conditions in child elements.

```qml
import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
     visible: true
     width: 640
     height: 480
     title: "Conditional Event Propagation Example"

     Rectangle {
         width: parent.width
         height: parent.height
         color: "lightgrey"

         // ParentMouseArea
         MouseArea {
             id: parentMouseArea
             anchors.fill: parent
             propagateComposedEvents: true
             onClicked: {
                 console.log("Parent MouseArea clicked at:", mouse.x, mouse.y)
             }

             // Child Rectangle
             Rectangle {
                 id: childRectangle
                 width: 200
                 height: 200
                 color: "lightblue"
                 anchors.centerIn: parent

                 //Child MouseArea
                 MouseArea {
                     id: childMouseArea
                     anchors.fill: parent
                     propagateComposedEvents: true
                     onClicked: {
                         console.log("Child MouseArea clicked at:", mouse.x, mouse.y)
                         if (mouse.x > width / 2) {
                             console.log("Stopping event propagation from Child MouseArea")
                             event.accepted = true // Stop propagation
                         }
                     }
                 }
             }
         }
     }
}
```

### explanation

In the code above, in the click event handler of the child `MouseArea`, I added a condition to stop event propagation if `mouse.x` is greater than `width / 2`. Set `event.accepted = true` to prevent the event from propagating to the parent.

If you run this example, you will see the following behavior:

1. When you click on the left half of the child `MouseArea`:
    - The message "Child MouseArea clicked at:" is printed to the console.
    - The message “Parent MouseArea clicked at:” is subsequently printed to the console.

2. When you click on the right half of the child `MouseArea`:
    - The message "Child MouseArea clicked at:" is printed to the console.
    - The message “Stopping event propagation from Child MouseArea” is displayed on the console.
    - Messages from the parent `MouseArea` are not displayed.

This allows for more granular event processing by allowing you to control event propagation based on specific conditions.

반응형