728x90

이전 예제로 TimeTimer를 만들어보면서 다른 Window를 Open 해보고 QML/C++ 간에 Signal과 Property를 통해 데이터를 연동하거나 신호를 주고받기도 하였습니다.

 

 

[Qt] QML(5) - TimeTimer 프로그램 만들기

QML으로 간단하게 TimeTimer라는 프로그램을 제작하면서 다른 기능도 사용해 보겠습니다. 이 예제를 진행하면서 만들어볼 간단한 프로그램은 TimeTimer입니다. TimeTimer는 위와 같이 생긴 시계인데 예

1d1cblog.tistory.com

이번에는 동적으로 다른 qml을 Load해서 사용할 수 있는 Loader에 대해 알아보려 합니다.

 

UI는 간단하게 아래처럼 구성되어 있습니다. 왼쪽에는 버튼들이 있고 버튼들을 클릭할 때마다 그에 맞는 qml 파일을 Loader가 Load 할 수 있게 되어 있습니다.

main.qml입니다. Loader에 source에 qml 파일을 지정해주고 있습니다.

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.15

Window {
    id:windows
    width: 480
    height: 300
    visible: true
    title: qsTr("Hello World")

    RowLayout {
        spacing:0
        Rectangle {
            border.width: 1
            Layout.preferredWidth : windows.width/4
            Layout.preferredHeight : windows.height

            ColumnLayout {
                anchors.centerIn: parent
                spacing : 20
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml1"
                    onClicked: {
                        mainLoader.source = "Item1.qml"
                    }
                }
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml2"
                    onClicked: {
                        mainLoader.source = "Item2.qml"
                    }
                }
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml3"
                    onClicked: {
                        mainLoader.source = "Item3.qml"
                    }
                }
            }
        }

        Rectangle {
            Layout.preferredWidth : windows.width*3/4
            Layout.preferredHeight : windows.height

            Loader {
                anchors.fill: parent
                id:mainLoader
                source : "Item1.qml"
            }
        }
    }
}

Item.qml입니다.

import QtQuick 2.15

Item {
    id:item1
    anchors.fill : parent
    Text {
        anchors.centerIn: parent
        text:"Item 1"
    }
}

여기서 Binding을 사용해 보겠습니다. Binding을 하면 다른 Item의 Property 값을 경신해 줄 수 있다고 보면 됩니다. 

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.15

Window {
    id:windows
    width: 480
    height: 300
    visible: true
    title: qsTr("Hello World")

    RowLayout {
        spacing:0
        Rectangle {
            border.width: 1
            Layout.preferredWidth : windows.width/4
            Layout.preferredHeight : windows.height

            ColumnLayout {
                anchors.centerIn: parent
                spacing : 20
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml1"
                    onClicked: {
                        mainLoader.source = "Item1.qml"
                    }
                }
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml2"
                    onClicked: {
                        mainLoader.source = "Item2.qml"
                    }
                }
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml3"
                    id:button3
                    onClicked: {
                        mainLoader.source = "Item3.qml"
                    }
                }
            }
        }

        Rectangle {
            Layout.preferredWidth : windows.width*3/4
            Layout.preferredHeight : windows.height - 30

            ColumnLayout {
                anchors.fill : parent
                Loader {
                    Layout.preferredWidth: parent.width
                    Layout.preferredHeight : parent.height - 30
                    id:mainLoader
                    source: "Item1.qml"
                }

                TextField {
                    id:colorInput
                    text:"white"
                    Layout.preferredWidth: parent.width
                    Layout.preferredHeight : 30
                }
            }
        }
    }

    Binding {
        target:mainLoader.item
        property: "backColor"
        value : colorInput.text
    }
}

여기서 Binding은 target(갱신할 대상)에 mainLoader의 item의 backColor Property를 지정하고 있습니다. 여기서 이 property에 넣어줄 값은 TextField가 가지고 있는 text 값입니다. 이렇게 설정해 주면 TextField의 값을 변경할 때마다 매번 set 해주지 않아도 됩니다.

만약 binding을 사용하지 않고 TextField의 Signal을 이용한다면 Loader의 source가 바뀔 때는 제대로 적용이 되지 않습니다.

TextField {
    id:colorInput
    text:"white"
    Layout.preferredWidth: parent.width
    Layout.preferredHeight : 30
    onTextChanged: {
        mainLoader.item.backColor = text
    }
}

다음으로 connections입니다. qml item 간에 signal을 받아 처리하게 됩니다. main.qml에 아래 Connection을 추가하면 item에서 Signal을 발생시키면 function을 호출하게 됩니다.

 

Signal을 발생시킬 Item에 signal을 선언하고 원하는 때에 signal을 발생시킵니다.

import QtQuick 2.15
Item {
    property color backColor : "white"
    signal emit_ChangeColor(color backColor)

    id:item1
    anchors.fill : parent
    Rectangle {
        anchors.fill: parent
        color: backColor

        Text {
            anchors.centerIn: parent
            text:"Item 1"
        }

        onColorChanged: {
            item1.emit_ChangeColor(backColor)
        }
    }
}

signal을 받을 쪽에서는 connection을 아래와 같이 넣습니다. signal을 받을 대상(target)과 그 대상에서 보내주는 시그널을 받았을 때 실행할 함수(on<Signal>)을 넣어줍니다.

Connections {
    target: mainLoader.item
    function onEmit_ChangeColor(backColor) {
        console.log(backColor)
    }
}

main.qml의 전체 코드입니다.

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.15

Window {
    id:windows
    width: 480
    height: 300
    visible: true
    title: qsTr("Hello World")

    RowLayout {
        spacing:0
        Rectangle {
            border.width: 1
            Layout.preferredWidth : windows.width/4
            Layout.preferredHeight : windows.height

            ColumnLayout {
                anchors.centerIn: parent
                spacing : 20
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml1"
                    onClicked: {
                        mainLoader.source = "Item1.qml"
                    }
                }
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml2"
                    onClicked: {
                        mainLoader.source = "Item2.qml"
                    }
                }
                Button {
                    Layout.preferredHeight: windows.height/4
                    text:"Load\nQml3"
                    id:button3
                    onClicked: {
                        mainLoader.source = "Item3.qml"
                    }
                }
            }
        }

        Rectangle {
            Layout.preferredWidth : windows.width*3/4
            Layout.preferredHeight : windows.height - 30

            ColumnLayout {
                anchors.fill : parent
                Loader {
                    Layout.preferredWidth: parent.width
                    Layout.preferredHeight : parent.height - 30
                    id:mainLoader
                    source: "Item1.qml"
                }

                TextField {
                    id:colorInput
                    text:"white"
                    Layout.preferredWidth: parent.width
                    Layout.preferredHeight : 30
                }
            }
        }
    }

    Connections {
        target: mainLoader.item
        function onEmit_ChangeColor(backColor) {
            console.log(backColor)
        }
    }

    Binding {
        target:mainLoader.item
        property: "backColor"
        value : colorInput.text
    }
}

 

728x90

+ Recent posts