범위 및 명명 해상도
QML 속성 바인딩, 인라인 함수, 가져온 JavaScript 파일은 모두 JavaScript 스코프에서 실행됩니다. 범위는 표현식이 액세스할 수 있는 변수와 두 개 이상의 이름이 충돌할 때 우선권을 갖는 변수를 제어합니다.
JavaScript의 내장된 범위 메커니즘은 매우 간단하기 때문에 QML은 이를 QML 언어 확장에 더 자연스럽게 맞도록 개선했습니다.
자바스크립트 범위
QML의 범위 확장은 JavaScript의 자연스러운 범위를 방해하지 않습니다. JavaScript 프로그래머는 함수, 속성 바인딩 또는 가져온 JavaScript 파일을 QML에서 프로그래밍할 때 기존 지식을 재사용할 수 있습니다.
다음 예제에서 addConstant()
메서드는 QML 객체의 a
및 b
속성 값에 관계없이 프로그래머가 예상하는 대로 전달된 매개변수에 13을 추가합니다.
QtObject { property int a: 3 property int b: 9 function addConstant(b) { var a = 13; return b + a; } }
QML은 자바스크립트의 일반적인 범위 지정 규칙을 존중하며 이는 바인딩에도 적용됩니다. 이 완전히 사악하고 혐오스러운 바인딩은 QML 객체의 a
프로퍼티에 12를 할당합니다.
QtObject { property int a a: { var a = 12; a; } }
QML의 모든 JavaScript 표현식, 함수 또는 파일에는 고유한 변수 객체가 있습니다. 한 파일에서 선언된 지역 변수는 다른 파일에서 선언된 지역 변수와 충돌하지 않습니다.
유형 이름 및 가져온 JavaScript 파일
QML 문서에는 문서에 표시되는 유형 이름과 JavaScript 파일을 정의하는 임포트 문이 포함되어 있습니다. 유형 이름은 QML 선언 자체에서 사용되는 것 외에도 첨부된 프로퍼티 및 열거형 값에 액세스할 때 JavaScript 코드에서 사용됩니다.
가져오기의 효과는 중첩된 인라인 컴포넌트의 프로퍼티를 포함하여 QML 문서의 모든 프로퍼티 바인딩과 JavaScript 함수에 적용됩니다. 다음 예제는 일부 열거형 값에 액세스하고 임포트된 JavaScript 함수를 호출하는 간단한 QML 파일을 보여줍니다.
import QtQuick 2.0 import "code.js" as Code ListView { snapMode: ListView.SnapToItem delegate: Component { Text { elide: Text.ElideMiddle text: "A really, really long string that will require eliding." color: Code.defaultColor() } } }
바인딩 범위 객체
속성 바인딩이 있는 객체를 바인딩의 범위 객체라고 합니다. 다음 예제에서 Item 객체는 바인딩의 범위 객체입니다.
Item { anchors.left: parent.left }
바인딩은 자격 조건 없이 범위 개체의 프로퍼티에 액세스할 수 있습니다. 이전 예제에서 바인딩은 어떤 형태의 개체 접두사도 없이 Item 의 parent
프로퍼티에 직접 액세스합니다. QML은 자바스크립트에 보다 구조화된 객체 지향 접근 방식을 도입하므로 자바스크립트 this
프로퍼티를 사용할 필요가 없습니다.
바인딩에서 연결된 프로퍼티에 액세스할 때는 범위 객체와의 상호 작용으로 인해 주의해야 합니다. 개념적으로 연결된 프로퍼티는 일부 객체에만 영향을 미치더라도 모든 객체에 존재합니다. 따라서 자격이 없는 첨부 프로퍼티 읽기는 항상 프로그래머가 의도한 것과는 다르게 스코프 객체의 첨부 프로퍼티로 해석됩니다.
예를 들어 PathView 유형은 경로 내 위치에 따라 보간된 값 프로퍼티를 델리게이트에 첨부합니다. PathView 는 델리게이트의 루트 객체에만 이러한 속성을 의미 있게 첨부하므로, 해당 속성에 액세스하는 모든 하위 객체는 아래 그림과 같이 루트 객체를 명시적으로 한정해야 합니다.
PathView { delegate: Component { Rectangle { id: root Image { scale: root.PathView.scale } } } }
Image 객체가 root
접두사를 생략하면 실수로 설정되지 않은 PathView.scale
첨부 프로퍼티에 액세스하게 됩니다.
컴포넌트 범위
QML 문서의 각 QML 컴포넌트는 논리적 범위를 정의합니다. 각 문서에는 하나 이상의 루트 컴포넌트가 있지만 다른 인라인 하위 컴포넌트도 있을 수 있습니다. 컴포넌트 범위는 컴포넌트 내의 객체 ID와 컴포넌트의 루트 객체 속성의 합입니다.
Item { property string title Text { id: titletype text: "<b>" + title + "</b>" font.pixelSize: 22 anchors.top: parent.top } Text { text: titletype.text font.pixelSize: 18 anchors.bottom: parent.bottom } }
위의 예는 상단에 서식 있는 텍스트 제목 문자열을 표시하고 하단에 동일한 텍스트의 작은 사본을 표시하는 간단한 QML 컴포넌트를 보여줍니다. 첫 번째 Text
유형은 표시할 텍스트를 형성할 때 컴포넌트의 title
프로퍼티에 직접 액세스합니다. 루트 유형의 프로퍼티에 직접 액세스할 수 있기 때문에 컴포넌트 전체에 데이터를 배포하는 것이 간단합니다.
두 번째 Text
유형은 ID를 사용하여 첫 번째 텍스트에 직접 액세스합니다. ID는 QML 프로그래머가 명시적으로 지정하므로 항상 다른 속성 이름보다 우선합니다( 자바스크립트 범위의 속성 이름 제외). 예를 들어, 이전 예제에서 바인딩의 범위 객체에 titletype
프로퍼티가 있는 경우 titletype
ID가 여전히 우선합니다.
컴포넌트 인스턴스 계층 구조
QML에서 컴포넌트 인스턴스는 컴포넌트 스코프를 서로 연결하여 스코프 계층 구조를 형성합니다. 컴포넌트 인스턴스는 상위 컴포넌트 범위에 직접 액세스할 수 있습니다.
이를 가장 쉽게 설명하는 방법은 컴포넌트 범위가 암시적으로 외부 컴포넌트의 자식으로 범위가 지정되는 인라인 하위 컴포넌트를 사용하는 것입니다.
Item {
property color defaultColor: "blue"
ListView {
delegate: Component {
Rectangle {
color: defaultColor
}
}
}
}
컴포넌트 인스턴스 계층 구조는 델리게이트 컴포넌트의 인스턴스가 Item
유형의 defaultColor
프로퍼티에 액세스할 수 있도록 합니다. 물론 델리게이트 컴포넌트에 defaultColor
라는 프로퍼티가 있었다면 이 프로퍼티가 우선시되었을 것입니다.
컴포넌트 인스턴스 범위 계층 구조는 아웃 오브 라인 컴포넌트에도 확장됩니다. 다음 예제에서 TitlePage.qml
컴포넌트는 TitleText
인스턴스 두 개를 생성합니다. TitleText
유형은 별도의 파일에 있지만 TitlePage
내에서 사용될 때 title
프로퍼티에 액세스할 수 있습니다. QML은 동적 범위 지정 언어이므로 사용되는 위치에 따라 title
프로퍼티의 해석이 달라질 수 있습니다.
// TitlePage.qml import QtQuick 2.0 Item { property string title TitleText { size: 22 anchors.top: parent.top } TitleText { size: 18 anchors.bottom: parent.bottom } } // TitleText.qml import QtQuick 2.0 Text { property int size text: "<b>" + title + "</b>" font.pixelSize: size }
동적 범위 지정은 매우 강력하지만 QML 코드의 동작을 예측하기 어려워지는 것을 방지하기 위해 신중하게 사용해야 합니다. 일반적으로 두 컴포넌트가 이미 다른 방식으로 긴밀하게 결합되어 있는 경우에만 사용해야 합니다. 재사용 가능한 컴포넌트를 빌드할 때는 다음과 같은 프로퍼티 인터페이스를 사용하는 것이 좋습니다:
// TitlePage.qml import QtQuick 2.0 Item { id: root property string title TitleText { title: root.title size: 22 anchors.top: parent.top } TitleText { title: root.title size: 18 anchors.bottom: parent.bottom } } // TitleText.qml import QtQuick 2.0 Text { property string title property int size text: "<b>" + title + "</b>" font.pixelSize: size }
재정의된 프로퍼티
QML에서는 객체 선언에 정의된 프로퍼티 이름을 첫 번째 객체 선언을 확장하는 다른 객체 선언에 정의된 프로퍼티로 재정의할 수 있습니다. 예를 들어
// Displayable.qml import QtQuick 2.0 Item { property string title property string detail Text { text: "<b>" + title + "</b><br>" + detail } function getTitle() { return title } function setTitle(newTitle) { title = newTitle } } // Person.qml import QtQuick 2.0 Displayable { property string title property string firstName property string lastName function fullName() { return title + " " + firstName + " " + lastName } }
여기서 title
이라는 이름은 표시 가능에 대한 출력 텍스트의 제목과 Person 개체의 경칭 제목 모두에 지정됩니다.
재정의된 속성은 참조되는 범위에 따라 확인됩니다. Person 컴포넌트의 범위 내부 또는 Person 컴포넌트의 인스턴스를 참조하는 외부 범위에서 title
은 Person.qml 안에 선언된 프로퍼티로 확인됩니다. fullName
함수는 Person 내부에 선언된 title
속성을 참조합니다.
그러나 Displayable 컴포넌트 내부에서 title
은 Displayable.qml에 선언된 프로퍼티를 참조합니다. getTitle() 및 setTitle() 함수와 Text 객체의 text
속성에 대한 바인딩은 모두 Displayable 컴포넌트에서 선언된 title
속성을 참조합니다.
같은 이름을 공유하지만 두 프로퍼티는 완전히 분리되어 있습니다. 프로퍼티 중 하나에 대한 onChanged 신호 핸들러는 같은 이름의 다른 프로퍼티가 변경되어도 트리거되지 않습니다. 두 프로퍼티의 별칭은 둘 중 하나만 참조할 뿐 둘 다 참조하지는 않습니다.
자바스크립트 전역 객체
QML은 혼란을 방지하기 위해 글로벌 객체의 프로퍼티와 충돌하는 유형, ID 및 프로퍼티 이름을 허용하지 않습니다. 프로그래머는 Math.min(10, 9)
이 항상 예상대로 작동한다는 확신을 가질 수 있습니다!
자세한 내용은 자바스크립트 호스트 환경을 참조하세요.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.