이전 예제로 TimeTimer를 만들어보면서 다른 Window를 Open 해보고 QML/C++ 간에 Signal과 Property를 통해 데이터를 연동하거나 신호를 주고받기도 하였습니다.
이번에는 동적으로 다른 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
}
}
'Programming > Qt' 카테고리의 다른 글
[Qt] QML(8) - SoundEffect, ComboBox ListModel 적용 (0) | 2023.04.20 |
---|---|
[Qt] QML(7) - ListView/Model C++ 로 처리하기 (0) | 2023.04.19 |
[Qt] QML(5) - TimeTimer 프로그램 만들기 (0) | 2023.04.17 |
[Qt] QML(4) - QML/C++ 통합하기(Q_PROPERTY, Q_INVOKABLE, SIGNAL) (0) | 2023.04.13 |
[Qt] QML(3) - Control Object (0) | 2023.04.12 |