[펌] Qt QML Scope and Naming Resolution
[원문] https://doc.qt.io/qt-5.6/qtqml-documents-scope.html
범위 및 이름 지정 해상도
자바 스크립트 범위
QML의 범위 확장은 JavaScript의 자연스러운 범위를 방해하지 않습니다. JavaScript 프로그래머는 함수, 속성 바인딩 또는 가져온 JavaScript 파일을 QML로 프로그래밍 할 때 기존 지식을 재사용 할 수 있습니다.
다음 예제에서, addConstant()
메소드는 프로그래머가 QML 객체 a
및 b
속성 의 값에 관계없이 예상 한 것처럼 전달 된 매개 변수에 13을 추가 합니다.
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은 JavaScript의 일반적인 범위 지정 규칙이 바인딩에도 적용된다는 점을 존중합니다. 이렇게 완전히 악의적 인 바인딩은 QML 객체의 a
속성에 12를 할당 합니다.
QtObject { property int a a: { var a = 12; a; } }
된 지역 변수와 충돌하지 않습니다.
형식 이름 및 가져온 JavaScript 파일
QML 문서 에는 문서에 표시되는 유형 이름과 JavaScript 파일을 정의하는 import 문이 포함됩니다. 첨부 된 속성 및 열거 형 값에 액세스 할 때 JavaScript 코드에서 QML 선언 자체에서 사용하는 것 외에도 형식 이름이 사용됩니다 .
가져 오기의 효과는 중첩 된 인라인 구성 요소의 경우에도 모든 속성 바인딩 및 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은보다 구조화되고 객체 지향적 인 JavaScript 접근 방식을 도입하므로 결과적으로 JavaScript this
속성을 사용할 필요가 없습니다 .
범위 객체와의 상호 작용으로 인해 바인딩에서 연결된 속성에 액세스 할 때주의해야 합니다. 개념적으로 첨부 된 속성은 해당 개체의 하위 집합에만 영향을 미치더라도 모든 개체에 있습니다. 결과적으로 규정되지 않은 연결된 속성 읽기는 항상 프로그래머가 의도 한 것이 아닌 범위 개체의 연결된 속성으로 해석됩니다.
예를 들어 PathView 형식은 경로의 위치에 따라 보간 된 값 속성을 대리자에 연결합니다. 으로 PathView는 만 의미있는 대리인의 루트 객체에 대한 이러한 속성을 첨부 아래 그림과 같이, 그들에 액세스하는 모든 하위 개체를 명시 적으로, 루트 개체를 한정해야합니다.
PathView { delegate: Component { Rectangle { id: root Image { scale: root.PathView.scale } } } }
이미지 오브젝트가 루트 접두사를 생략하면 실수로 설정되지 않은 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 프로그래머에 의해 명시 적으로 지정되므로 다른 속성 이름보다 항상 우선 순위가 높습니다 ( JavaScript Scope 의 경우 제외 ). 예를 들어, 이전 예에서 바인딩의 범위 객체 에 titletype
속성이있는 경우에는 titletype
id가 여전히 우선합니다.
구성 요소 인스턴스 계층 구조
QML에서 구성 요소 인스턴스는 구성 요소 범위를 연결하여 범위 계층을 형성합니다. 구성 요소 인스턴스는 조상의 구성 요소 범위에 직접 액세스 할 수 있습니다.
이를 증명하는 가장 쉬운 방법은 구성 요소 범위가 외부 구성 요소의 하위로 암시 적으로 범위가 지정된 인라인 하위 구성 요소를 사용하는 것입니다.
Item { property color defaultColor: "blue" ListView { delegate: Component { Rectangle { color: defaultColor } } } }
구성 요소 인스턴스 계층 구조를 사용하면 대리자 구성 요소의 인스턴스 defaultColor
에서 해당 Item
유형 의 속성에 액세스 할 수 있습니다 . 물론, 위임 구성 요소에는 defaultColor
우선 순위 가 부여 된 속성이있었습니다 .
구성 요소 인스턴스 범위 계층 구조는 라인 외부 구성 요소까지 확장됩니다. 다음 예제에서 TitlePage.qml
구성 요소는 두 개의 TitleText
인스턴스를 만듭니다 . 짝수 불구하고 TitleText
유형이 별도의 파일에, 그것은 여전히 액세스가 title
그것이 내에서 사용하는 경우 속성을 TitlePage
. 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
은 Displayable의 출력 텍스트 제목과 Person 객체의 경의 제목 모두에 부여됩니다.
재정의 된 속성은 참조되는 범위에 따라 결정됩니다. Person 구성 요소의 범위 또는 Person 구성 요소의 인스턴스를 참조하는 외부 범위에서 title
Person.qml 내에 선언 된 속성으로 확인됩니다. 이 fullName
함수는 title
Person 내부에 선언 된 속성 을 참조합니다 .
그러나 Displayable 구성 요소 내부는 Displayable.qml에 title
선언 된 속성을 참조합니다. getTitle () 및 setTitle () 함수 및 text
Text 객체 의 속성에 대한 바인딩 은 모두 title
Displayable 구성 요소에 선언 된 속성을 참조 합니다.
동일한 이름을 공유 함에도 불구하고 두 속성은 완전히 별개입니다. 하나의 속성에 대한 onChanged 신호 처리기는 동일한 이름을 가진 다른 속성에 대한 변경에 의해 트리거되지 않습니다. 두 속성 중 하나의 별칭은 둘 중 하나를 참조하지만 둘 다 참조하지는 않습니다.
자바 스크립트 전역 객체
QML은 혼동을 막기 위해 전역 객체의 속성과 충돌하는 유형, ID 및 속성 이름을 허용하지 않습니다. 프로그래머 Math.min(10, 9)
는 항상 예상대로 작동 할 것이라고 확신 할 수 있습니다 !
자세한 내용은 JavaScript 호스트 환경 을 참조하십시오.