QML 객체 속성
모든 QML 객체 유형에는 정의된 속성 집합이 있습니다. 객체 유형의 각 인스턴스는 해당 객체 유형에 대해 정의된 속성 집합으로 생성됩니다. 지정할 수 있는 속성의 종류는 여러 가지가 있으며, 아래에 설명되어 있습니다.
객체 선언의 속성
QML 문서의 객체 선언은 새 유형을 정의합니다. 또한 새로 정의된 유형의 인스턴스가 생성될 경우 인스턴스화될 객체 계층구조를 선언합니다.
QML 객체 유형 속성 유형 집합은 다음과 같습니다:
- ID 속성
- 속성 속성
- 신호 속성
- 시그널 핸들러 속성
- 메서드 속성
- 첨부된 프로퍼티 및 첨부된 시그널 핸들러 어트리뷰트
- 열거 어트리뷰트
이러한 어트리뷰트는 아래에서 자세히 설명합니다.
id 속성
모든 QML 객체 유형에는 정확히 하나의 id 어트리뷰트가 있습니다. 이 속성은 언어 자체에서 제공되며, 어떤 QML 객체 유형에서도 재정의하거나 재정의할 수 없습니다.
객체 인스턴스의 id 속성에 값을 할당하여 해당 객체를 식별하고 다른 객체에서 참조할 수 있도록 할 수 있습니다. id
은 소문자 또는 밑줄로 시작해야 하며 문자, 숫자 및 밑줄 이외의 문자를 포함할 수 없습니다.
아래는 TextInput 객체와 Text 객체입니다. TextInput 객체의 id
값은 "myTextInput"으로 설정되어 있습니다. Text 개체는 text
속성을 TextInput 의 text
속성과 동일한 값을 갖도록 설정하여 myTextInput.text
을 참조합니다. 이제 두 항목 모두 동일한 텍스트를 표시합니다:
import QtQuick Column { width: 200; height: 200 TextInput { id: myTextInput; text: "Hello World" } Text { text: myTextInput.text } }
객체는 선언된 컴포넌트 범위 내 어디에서나 id
로 참조할 수 있습니다. 따라서 id
값은 해당 컴포넌트 범위 내에서 항상 고유해야 합니다. 자세한 내용은 범위 및 명명 해상도를 참조하세요.
객체 인스턴스가 생성되면 해당 ID 속성의 값은 변경할 수 없습니다. id
속성은 일반적인 속성처럼 보이지만 일반적인 property
속성이 아니며 특별한 의미가 적용됩니다(예: 위 예제에서는 myTextInput.id
에 액세스할 수 없습니다).
속성 속성
속성은 정적 값을 할당하거나 동적 표현식에 바인딩할 수 있는 개체의 속성입니다. 프로퍼티의 값은 다른 객체에서 읽을 수 있습니다. 일반적으로 특정 QML 유형에서 특정 속성에 대해 명시적으로 이를 허용하지 않는 한 다른 객체에서도 수정할 수 있습니다.
속성 속성 정의하기
프로퍼티는 C++에서 클래스의 Q_PROPERTY 을 등록한 다음 QML 타입 시스템에 등록하여 타입에 대해 정의할 수 있습니다. 또는 다음과 같은 구문을 사용하여 QML 문서의 객체 선언에 객체 유형의 사용자 지정 속성을 정의할 수 있습니다:
[default] [required] [readonly] property <propertyType> <propertyName>
이러한 방식으로 객체 선언은 특정 값을 외부 객체에 노출하거나 일부 내부 상태를 더 쉽게 유지할 수 있습니다.
속성 이름은 소문자로 시작해야 하며 문자, 숫자 및 밑줄만 포함할 수 있습니다. 자바스크립트 예약어는 유효한 프로퍼티 이름이 아닙니다. default
, required
, readonly
키워드는 선택 사항이며 선언되는 프로퍼티의 의미를 변경합니다. 각 속성의 의미에 대한 자세한 내용은 기본 속성, 필수 속성 및 읽기 전용 속성에 대한 다음 섹션을 참조하세요.
사용자 지정 속성을 선언하면 해당 속성에 대한 값 변경 신호가 암시적으로 생성되고, <PropertyName>Changed라는 관련 신호 핸들러가 생성됩니다(여기서 <PropertyName>은 속성 이름이며 첫 글자는 대문자로 표시됨).
예를 들어, 다음 객체 선언은 Rectangle 기본 유형에서 파생되는 새 유형을 정의합니다. 여기에는 두 개의 새 프로퍼티가 있으며, 새 프로퍼티 중 하나에 대해 시그널 핸들러가 구현되어 있습니다:
Rectangle { property color previousColor property color nextColor onNextColorChanged: console.log("The next color will be: " + nextColor.toString()) }
사용자 정의 프로퍼티 정의의 유효한 유형
enumeration 유형을 제외한 모든 QML 값 유형은 사용자 지정 속성 유형으로 사용할 수 있습니다. 예를 들어, 이들은 모두 유효한 프로퍼티 선언입니다:
(열거형 값은 단순히 정수 값이며 int 유형으로 대신 참조할 수 있습니다.)
일부 값 유형은 QtQuick
모듈에서 제공되므로 모듈을 가져오지 않으면 속성 유형으로 사용할 수 없습니다. 자세한 내용은 QML 값 유형 문서를 참조하세요.
var 값 유형은 목록 및 객체를 포함한 모든 유형의 값을 담을 수 있는 일반 플레이스홀더 유형입니다:
property var someNumber: 1.5 property var someString: "abc" property var someBool: true property var someList: [1, 2, "three", "four"] property var someObject: Rectangle { width: 100; height: 100; color: "red" }
또한 모든 QML 객체 유형을 속성 유형으로 사용할 수 있습니다. 예를 들어
property Item someItem property Rectangle someRectangle
이는 사용자 지정 QML 유형에도 적용됩니다. QML 유형이 ColorfulButton.qml
파일(클라이언트가 가져온 디렉터리)에 정의된 경우 ColorfulButton
유형의 속성도 유효합니다.
속성 속성에 값 할당하기
객체 인스턴스의 속성 값은 두 가지 방법으로 지정할 수 있습니다:
- 초기화 시 값 할당
- 명령형 값 할당
두 경우 모두 값은 정적 값 또는 바인딩 표현식 값일 수 있습니다.
초기화 시 값 할당
초기화 시 프로퍼티에 값을 할당하는 구문은 다음과 같습니다:
<propertyName> : <value>
원하는 경우 초기화 값 할당을 객체 선언의 속성 정의와 결합할 수 있습니다. 이 경우 속성 정의의 구문은 다음과 같습니다:
[default] property <propertyType> <propertyName> : <value>
다음은 속성 값 초기화의 예입니다:
import QtQuick Rectangle { color: "red" property color nextColor: "blue" // combined property declaration and initialization }
명령형 값 할당
명령형 값 할당은 명령형 JavaScript 코드에서 속성 값(정적 값 또는 바인딩 표현식)을 프로퍼티에 할당하는 것입니다. 명령형 값 할당의 구문은 아래와 같이 자바스크립트 할당 연산자만 있으면 됩니다:
[<objectId>.]<propertyName> = value
명령형 값 할당의 예는 다음과 같습니다:
import QtQuick Rectangle { id: rect Component.onCompleted: { rect.color = "red" } }
정적 값과 바인딩 표현식 값
앞서 언급했듯이 프로퍼티에 할당할 수 있는 값에는 정적 값과 바인딩 표현식 값의 두 가지 종류가 있습니다. 후자는 속성 바인딩이라고도 합니다.
종류 | 의미 |
---|---|
정적 값 | 다른 프로퍼티에 의존하지 않는 상수 값입니다. |
바인딩 표현식 | 프로퍼티와 다른 프로퍼티의 관계를 설명하는 자바스크립트 표현식입니다. 이 표현식의 변수를 프로퍼티의 종속성이라고 합니다. QML 엔진은 프로퍼티와 해당 종속성 간의 관계를 강제합니다. 종속성의 값이 변경되면 QML 엔진은 자동으로 바인딩 표현식을 다시 평가하고 새 결과를 프로퍼티에 할당합니다. |
다음은 프로퍼티에 두 가지 유형의 값이 할당되는 예제입니다:
import QtQuick Rectangle { // both of these are static value assignments on initialization width: 400 height: 200 Rectangle { // both of these are binding expression value assignments on initialization width: parent.width / 2 height: parent.height } }
참고: 바인딩 표현식을 필수적으로 할당하려면 Qt.binding()로 전달되는 함수에 바인딩 표현식이 포함되어 있어야 하고, Qt.binding()에서 반환된 값을 프로퍼티에 할당해야 합니다. 반대로 초기화 시 바인딩 표현식을 할당할 때는 Qt.binding()을 사용해서는 안 됩니다. 자세한 내용은 프로퍼티 바인딩을 참조하십시오.
유형 안전
프로퍼티는 타입 안전합니다. 프로퍼티에는 프로퍼티 유형과 일치하는 값만 할당할 수 있습니다.
예를 들어 프로퍼티가 실수인 경우 여기에 문자열을 할당하려고 하면 오류가 발생합니다:
property int volume: "four" // generates an error; the property's object will not be loaded
마찬가지로 런타임 중에 프로퍼티에 잘못된 유형의 값을 할당하면 새 값이 할당되지 않고 오류가 생성됩니다.
일부 속성 유형에는 자연스러운 값 표현이 없으며, 이러한 속성 유형에 대해서는 QML 엔진이 자동으로 문자열을 유형화된 값으로 변환합니다. 예를 들어 color
유형의 속성은 문자열이 아닌 색상을 저장하지만, 오류 보고 없이 "red"
문자열을 색상 속성에 할당할 수 있습니다.
기본적으로 지원되는 속성 유형 목록은 QML 값 유형을 참조하세요. 또한 사용 가능한 모든 QML 객체 유형도 속성 유형으로 사용할 수 있습니다.
특수 속성 유형
개체 목록 속성 속성
list 유형 속성에는 QML 객체 유형 값의 목록을 할당할 수 있습니다. 객체 목록 값을 정의하는 구문은 대괄호로 둘러싸인 쉼표로 구분된 목록입니다:
[ <item 1>, <item 2>, ... ]
예를 들어 Item 유형에는 State 유형 개체 목록을 보유하는 데 사용되는 states 속성이 있습니다. 아래 코드는 이 속성의 값을 3개의 State 객체 목록으로 초기화합니다:
import QtQuick Item { states: [ State { name: "loading" }, State { name: "running" }, State { name: "stopped" } ] }
목록에 단일 항목이 포함된 경우 대괄호는 생략할 수 있습니다:
import QtQuick Item { states: State { name: "running" } }
list 유형 프로퍼티는 다음 구문을 사용하여 객체 선언에 지정할 수 있습니다:
[default] property list<<ObjectType>> propertyName
그리고 다른 속성 선언과 마찬가지로 속성 초기화는 다음 구문을 사용하여 속성 선언과 결합할 수 있습니다:
[default] property list<<ObjectType>> propertyName: <value>
다음은 목록 속성 선언의 예입니다:
import QtQuick Rectangle { // declaration without initialization property list<Rectangle> siblingRects // declaration with initialization property list<Rectangle> childRects: [ Rectangle { color: "red" }, Rectangle { color: "blue"} ] }
반드시 QML 객체 유형 값이 아닌 값의 목록을 저장하기 위해 속성을 선언하려면 var 속성을 대신 선언해야 합니다.
그룹화된 속성
경우에 따라 프로퍼티에는 하위 프로퍼티 속성의 논리적 그룹이 포함되기도 합니다. 이러한 하위 속성 속성은 점 표기법 또는 그룹 표기법을 사용하여 할당할 수 있습니다.
예를 들어 Text 유형에는 font 그룹 속성이 있습니다. 아래에서 첫 번째 Text 개체는 점 표기법을 사용하여 font
값을 초기화하고 두 번째 개체는 그룹 표기법을 사용합니다:
Text { //dot notation font.pixelSize: 12 font.b: true } Text { //group notation font { pixelSize: 12; b: true } }
그룹화된 프로퍼티 유형은 하위 프로퍼티가 있는 유형입니다. 그룹화된 속성 유형이 값 유형이 아닌 객체 유형인 경우 해당 프로퍼티를 포함하는 프로퍼티는 읽기 전용이어야 합니다. 이는 하위 프로퍼티가 속한 객체를 바꿀 수 없도록 하기 위한 것입니다.
속성 별칭
속성 별칭은 다른 속성에 대한 참조를 보유하는 속성입니다. 프로퍼티에 새롭고 고유한 저장 공간을 할당하는 일반적인 프로퍼티 정의와 달리, 프로퍼티 별칭은 새로 선언된 프로퍼티(별칭 프로퍼티)를 기존 프로퍼티(앨리어싱 프로퍼티)에 대한 직접 참조로 연결합니다.
속성 별칭 선언은 속성 유형 대신 alias
키워드가 필요하고 속성 선언의 오른쪽에 유효한 별칭 참조가 있어야 한다는 점을 제외하면 일반 속성 정의와 비슷해 보입니다:
[default] property alias <name>: <alias reference>
일반 프로퍼티와 달리 별칭에는 다음과 같은 제한이 있습니다:
- 별칭이 선언된 타입의 범위 내에 있는 객체 또는 객체의 속성만 참조할 수 있습니다.
- 임의의 JavaScript 표현식을 포함할 수 없습니다.
- 해당 타입의 범위를 벗어나 선언된 객체를 참조할 수 없습니다.
- 별칭 참조는 일반 속성의 선택적 기본값과 달리 선택 사항이 아니며, 별칭을 처음 선언할 때 별칭 참조를 제공해야 합니다.
- 연결된 속성을 참조할 수 없습니다.
- 깊이가 3 이상인 계층 구조 내부의 속성을 참조할 수 없습니다. 다음 코드는 작동하지 않습니다:
property alias color: myItem.myRect.border.color Item { id: myItem property Rectangle myRect }
그러나 최대 2단계 깊이의 속성에 대한 별칭은 작동합니다.
property alias color: rectangle.border.color Rectangle { id: rectangle }
예를 들어 아래는 buttonText
별칭 속성이 있는 Button
유형으로 Text 하위의 text
개체에 연결됩니다:
// Button.qml import QtQuick Rectangle { property alias buttonText: textItem.text width: 100; height: 30; color: "yellow" Text { id: textItem } }
다음 코드는 하위 Text 개체에 대해 정의된 텍스트 문자열을 사용하여 Button
을 만듭니다:
Button { buttonText: "Click Me" }
여기서 buttonText
을 수정하면 textItem.text 값이 직접 수정되며, 다른 값을 변경하여 textItem.text를 업데이트하지는 않습니다. buttonText
이 별칭이 아닌 경우, 속성 바인딩은 양방향이 아니므로 값을 변경해도 실제로 표시되는 텍스트는 전혀 변경되지 않습니다. 즉, textItem.text가 변경되면 buttonText
값은 변경되지만 그 반대의 경우는 변경되지 않습니다.
속성 별칭에 대한 고려 사항
앨리어싱 속성의 이름이 기존 속성과 같을 수 있으므로 기존 속성을 효과적으로 덮어쓸 수 있습니다. 예를 들어 다음 QML 유형에는 기본 제공 Rectangle::color 속성과 이름이 같은 color
별칭 속성이 있습니다:
Rectangle { id: coloredrectangle property alias color: bluerectangle.color color: "red" Rectangle { id: bluerectangle color: "#1234ff" } Component.onCompleted: { console.log (coloredrectangle.color) //prints "#1234ff" setInternalColor() console.log (coloredrectangle.color) //prints "#111111" coloredrectangle.color = "#884646" console.log (coloredrectangle.color) //prints #884646 } //internal function that has access to internal properties function setInternalColor() { color = "#111111" } }
이 유형을 사용하고 color
속성을 참조하는 모든 객체는 일반 Rectangle::color 속성이 아닌 별칭을 참조하게 됩니다. 그러나 내부적으로 사각형은 color
속성을 올바르게 설정하고 별칭이 아닌 실제 정의된 속성을 참조할 수 있습니다.
속성 별칭 및 유형
속성 별칭은 명시적인 유형 사양을 가질 수 없습니다. 속성 별칭의 유형은 해당 별칭이 참조하는 속성 또는 객체의 선언된 유형입니다. 따라서 인라인으로 선언된 추가 속성이 있는 ID를 통해 참조되는 개체에 대한 별칭을 만들면 별칭을 통해 추가 속성에 액세스할 수 없습니다:
// MyItem.qml Item { property alias inner: innerItem Item { id: innerItem property int extraProperty } }
내부 컴포넌트는 Item 일 뿐이므로 이 컴포넌트 외부에서 inner.extraProperty 을 초기화할 수 없습니다:
// main.qml MyItem { inner.extraProperty: 5 // fails }
그러나 내부 객체를 전용 .qml 파일을 사용하여 별도의 컴포넌트로 추출하면 해당 컴포넌트를 대신 인스턴스화하고 별칭을 통해 모든 프로퍼티를 사용할 수 있습니다:
// MainItem.qml Item { // Now you can access inner.extraProperty, as inner is now an ExtraItem property alias inner: innerItem ExtraItem { id: innerItem } } // ExtraItem.qml Item { property int extraProperty }
기본 속성
객체 정의에는 하나의 기본 속성이 있을 수 있습니다. 기본 속성은 특정 속성에 대한 값으로 선언하지 않고 다른 객체의 정의 내에서 객체를 선언하는 경우 값이 할당되는 속성입니다.
선택 사항인 default
키워드로 프로퍼티를 선언하면 기본 프로퍼티로 표시됩니다. 예를 들어 기본 속성이 someText
인 MyLabel.qml 파일이 있다고 가정해 보겠습니다:
// MyLabel.qml import QtQuick Text { default property var someText text: `Hello, ${someText.text}` }
MyLabel
개체 정의에서 someText
값을 다음과 같이 지정할 수 있습니다:
MyLabel { Text { text: "world!" } }
이는 다음과 같은 효과를 가져옵니다:
MyLabel { someText: Text { text: "world!" } }
그러나 someText
속성이 기본 속성으로 표시되었으므로 Text 개체를 이 속성에 명시적으로 할당할 필요는 없습니다.
children 속성에 명시적으로 추가하지 않고도 Item 기반 유형에 자식 개체를 추가할 수 있음을 알 수 있습니다. 이는 Item 의 기본 속성은 data
속성이며 Item 에 대해 이 목록에 추가된 모든 항목은 자동으로 children 목록에 추가되기 때문입니다.
기본 속성은 항목의 하위 항목을 재할당할 때 유용하게 사용할 수 있습니다. 예를 들어
기본 속성 별칭을 inner.children
으로 설정하면 외부 항목의 하위 항목으로 할당된 모든 객체가 자동으로 내부 항목의 하위 항목으로 재할당됩니다.
경고: 요소의 기본 목록 속성 값을 암시적으로 또는 명시적으로 설정할 수 있습니다. 단일 요소의 정의 내에서 이 두 가지 방법을 혼용하면 목록 내 요소의 순서가 정의되지 않으므로 혼용해서는 안 됩니다.
Item { // Use either implicit or explicit assignement to the default list property but not both! Rectangle { width: 40 } // implicit data: [ Rectangle { width: 100 } ] // explicit }
필수 속성
객체 선언은 required
키워드를 사용하여 필요에 따라 속성을 정의할 수 있습니다. 구문은 다음과 같습니다.
required property <propertyType> <propertyName>
이름에서 알 수 있듯이 필수 속성은 객체의 인스턴스가 생성될 때 설정해야 합니다. 이 규칙을 위반하면 정적으로 감지할 수 있는 경우 QML 애플리케이션이 시작되지 않습니다. 동적으로 인스턴스화된 QML 컴포넌트(예: Qt.createComponent())의 경우 이 규칙을 위반하면 경고와 함께 null 반환값이 발생합니다.
다음을 사용하여 기존 프로퍼티를 필수로 만들 수 있습니다.
required <propertyName>
다음 예제는 색상 속성을 항상 지정해야 하는 사용자 정의 사각형 컴포넌트를 만드는 방법을 보여줍니다.
// ColorRectangle.qml Rectangle { required color }
참고: QML에서 필수 프로퍼티에 초기 값을 할당할 수 없으며, 이는 필수 프로퍼티의 의도된 용도에 직접적으로 위배됩니다.
필수 속성은 모델-뷰-대리인 코드에서 특별한 역할을 합니다: 뷰의 델리게이트에 뷰 모델의 역할 이름과 이름이 일치하는 필수 속성이 있는 경우 해당 속성은 모델의 해당 값으로 초기화됩니다. 자세한 내용은 Qt Quick 의 모델 및 보기 페이지를 참조하세요.
C++에서 필수 속성을 초기화하는 방법은 QQmlComponent::createWithInitialProperties, QQmlApplicationEngine::setInitialProperties 및 QQuickView::setInitialProperties 을 참조하세요.
읽기 전용 속성
객체 선언은 다음 구문과 함께 readonly
키워드를 사용하여 읽기 전용 속성을 정의할 수 있습니다:
readonly property <propertyType> <propertyName> : <value>
읽기 전용 프로퍼티에는 초기화 시 정적 값 또는 바인딩 표현식을 할당해야 합니다. 읽기 전용 속성이 초기화된 후에는 더 이상 정적 값이나 바인딩 표현식을 변경할 수 없습니다.
예를 들어 아래 Component.onCompleted
블록의 코드는 유효하지 않습니다:
Item { readonly property int someNumber: 10 Component.onCompleted: someNumber = 20 // TypeError: Cannot assign to read-only property }
참고: 읽기 전용 프로퍼티는 기본 프로퍼티가 될 수 없습니다.
속성 수정자 개체
속성에는 속성 값 수정자 개체를 연결할 수 있습니다. 특정 속성과 연결된 속성 수정자 유형의 인스턴스를 선언하는 구문은 다음과 같습니다:
<PropertyModifierTypeName> on <propertyName> { // attributes of the object instance }
이를 일반적으로 "on" 구문이라고 합니다.
위의 구문은 실제로는 기존 프로퍼티에 작용하는 객체를 인스턴스화하는 객체 선언이라는 점에 유의해야 합니다.
특정 속성 수정자 유형은 특정 속성 유형에만 적용될 수 있지만 언어에 의해 강제되지는 않습니다. 예를 들어 QtQuick
에서 제공하는 NumberAnimation
유형은 숫자형(예: int
또는 real
) 프로퍼티에만 애니메이션을 적용합니다. 숫자가 아닌 속성과 함께 NumberAnimation
을 사용하려고 하면 오류가 발생하지 않지만 숫자가 아닌 속성은 애니메이션이 적용되지 않습니다. 특정 속성 유형과 연결된 속성 수정자 유형의 동작은 해당 구현에 의해 정의됩니다.
신호 속성
신호는 프로퍼티가 변경되었거나 애니메이션이 시작 또는 중지되었거나 이미지가 다운로드된 경우와 같이 어떤 이벤트가 발생했음을 객체에서 알려주는 알림입니다. 예를 들어 MouseArea 유형에는 사용자가 마우스 영역을 클릭할 때 발생하는 clicked 신호가 있습니다.
특정 신호가 발생할 때마다 시그널 핸들러를 통해 객체에 알림을 보낼 수 있습니다. 신호 핸들러는 <신호> 구문으로 선언되며, 여기서 <신호>는 신호의 이름이며 첫 글자는 대문자로 표시됩니다. 신호 핸들러는 신호를 방출하는 객체의 정의 내에서 선언되어야 하며, 핸들러에는 신호 핸들러가 호출될 때 실행될 자바스크립트 코드 블록이 포함되어야 합니다.
예를 들어, 아래의 onClicked 신호 핸들러는 MouseArea 객체 정의 내에 선언되어 있으며 MouseArea 을 클릭하면 호출되어 콘솔 메시지를 출력합니다:
import QtQuick Item { width: 100; height: 100 MouseArea { anchors.fill: parent onClicked: { console.log("Click!") } } }
시그널 어트리뷰트 정의하기
신호는 C++에서 클래스의 Q_SIGNAL 을 등록한 다음 QML 타입 시스템에 등록하여 타입에 대해 정의할 수 있습니다. 또는 다음 구문을 사용하여 QML 문서의 객체 선언에서 객체 유형에 대한 사용자 지정 신호를 정의할 수 있습니다:
signal <signalName>[([<parameterName>: <parameterType>[, ...]])]
동일한 유형 블록에 동일한 이름을 가진 두 개의 시그널 또는 메서드를 선언하려고 하면 오류가 발생합니다. 그러나 새 신호는 해당 유형에 있는 기존 신호의 이름을 재사용할 수 있습니다. (이 경우 기존 신호가 숨겨져 액세스할 수 없게 될 수 있으므로 주의해야 합니다.)
다음은 세 가지 신호 선언의 예입니다:
import QtQuick Item { signal clicked signal hovered() signal actionPerformed(action: string, actionResult: int) }
속성 스타일 구문으로 신호 매개변수를 지정할 수도 있습니다:
signal actionCanceled(string action)
메서드 선언과 일관성을 유지하려면 콜론을 사용한 타입 선언을 선호해야 합니다.
신호에 매개 변수가 없는 경우 "()" 괄호는 선택 사항입니다. 매개 변수를 사용하는 경우 위의 actionPerformed
신호에 대한 string
및 int
인수의 경우와 같이 매개 변수 유형을 선언해야 합니다. 허용되는 매개변수 유형은 이 페이지의 속성 속성 정의에 나열된 것과 동일합니다.
신호를 내보내려면 메서드로 호출합니다. 신호가 전송되면 관련 신호 핸들러가 호출되며, 핸들러는 정의된 신호 인수 이름을 사용하여 각 인수에 액세스할 수 있습니다.
속성 변경 신호
QML 유형은 앞서 속성 속성 섹션에서 설명한 대로 속성 값이 변경될 때마다 발생하는 내장 속성 변경 시그널도 제공합니다. 이러한 신호가 유용한 이유와 사용 방법에 대한 자세한 내용은 속성 변경 신호 핸들러에 대한 다음 섹션을 참조하세요.
시그널 핸들러 속성
시그널 핸들러는 특별한 종류의 메서드 어트리뷰트로, 관련 신호가 발생할 때마다 메서드 구현이 QML 엔진에 의해 호출됩니다. QML에서 객체 정의에 신호를 추가하면 기본적으로 빈 구현이 있는 객체 정의에 연결된 신호 핸들러가 자동으로 추가됩니다. 클라이언트는 프로그램 로직을 구현하기 위해 구현을 제공할 수 있습니다.
아래 그림과 같이 SquareButton.qml
파일에 정의가 제공되고 activated
및 deactivated
신호가 있는 다음 SquareButton
유형을 예로 들어 보겠습니다:
// SquareButton.qml Rectangle { id: root signal activated(xPosition: real, yPosition: real) signal deactivated property int side: 100 width: side; height: side MouseArea { anchors.fill: parent onReleased: root.deactivated() onPressed: mouse => root.activated(mouse.x, mouse.y) } }
이러한 신호는 클라이언트가 신호 처리기에 대한 구현을 제공하는 동일한 디렉터리의 다른 QML 파일에 있는 SquareButton
객체에서 수신할 수 있습니다:
// myapplication.qml SquareButton { onDeactivated: console.log("Deactivated!") onActivated: (xPosition, yPosition) => { console.log(`Activated at ${xPosition}, ${yPosition}`) } }
신호 처리기는 신호가 이미 매개변수 유형을 지정하고 있기 때문에 매개변수 유형을 선언할 필요가 없습니다. 위에 표시된 화살표 함수 구문은 타입 어노테이션을 지원하지 않습니다.
시그널 사용에 대한 자세한 내용은 시그널 및 핸들러 이벤트 시스템을 참조하세요.
프로퍼티 변경 신호 핸들러
프로퍼티 변경 신호에 대한 시그널 핸들러는 <프로퍼티>에서 <프로퍼티>는 프로 퍼티의 이름이며 첫 글자를 대문자로 하는 on<프로퍼티>Changed 구문 형식을 취합니다. 예를 들어 TextInput 유형 문서에는 textChanged
신호가 문서화되어 있지 않지만 TextInput 에 text 프로퍼티가 있다는 사실을 통해 이 신호를 암시적으로 사용할 수 있으므로 이 프로퍼티가 변경될 때마다 호출되는 onTextChanged
신호 핸들러를 작성할 수 있습니다:
import QtQuick TextInput { text: "Change this!" onTextChanged: console.log(`Text has changed to: ${text}`) }
메서드 속성
객체 타입의 메서드는 일부 처리를 수행하거나 추가 이벤트를 트리거하기 위해 호출할 수 있는 함수입니다. 메서드는 신호에 연결하여 신호가 발신될 때마다 자동으로 호출되도록 할 수 있습니다. 자세한 내용은 시그널 및 핸들러 이벤트 시스템을 참조하세요.
메소드 속성 정의하기
메서드는 클래스의 함수에 태그를 지정한 다음 QML 타입 시스템에 Q_INVOKABLE 또는 클래스의 Q_SLOT 로 등록하여 C++에서 타입에 대해 정의할 수 있습니다. 또는 다음 구문을 사용하여 QML 문서의 객체 선언에 사용자 정의 메서드를 추가할 수도 있습니다:
function <functionName>([<parameterName>[: <parameterType>][, ...]]) [: <returnType>] { <body> }
메서드는 재사용 가능한 독립형 JavaScript 코드 블록을 정의하기 위해 QML 유형에 추가할 수 있습니다. 이러한 메서드는 내부적으로 또는 외부 객체에서 호출할 수 있습니다.
시그널과 달리 메서드 매개변수 유형은 기본적으로 var
유형으로 선언되므로 선언할 필요가 없습니다. 그러나 qmlcachegen이 더 성능이 좋은 코드를 생성하고 유지보수성을 향상시키기 위해서는 선언해야 합니다.
같은 타입 블록에 같은 이름의 메서드나 시그널을 두 개 선언하려고 하면 오류가 발생합니다. 그러나 새 메서드는 해당 유형에서 기존 메서드의 이름을 재사용할 수 있습니다. (이 경우 기존 메서드가 숨겨져 액세스할 수 없게 될 수 있으므로 주의해야 합니다.)
아래는 height
값을 할당할 때 호출되는 calculateHeight()
메서드가 있는 Rectangle 입니다:
import QtQuick Rectangle { id: rect function calculateHeight(): real { return rect.width / 2; } width: 100 height: calculateHeight() }
메서드에 매개 변수가 있는 경우 메서드 내에서 이름으로 액세스할 수 있습니다. 아래에서 MouseArea 을 클릭하면 moveTo()
메서드가 호출되고, 이 메서드는 수신된 newX
및 newY
매개변수를 참조하여 텍스트의 위치를 변경할 수 있습니다:
import QtQuick Item { width: 200; height: 200 MouseArea { anchors.fill: parent onClicked: mouse => label.moveTo(mouse.x, mouse.y) } Text { id: label function moveTo(newX: real, newY: real) { label.x = newX; label.y = newY; } text: "Move me!" } }
첨부된 프로퍼티 및 첨부된 시그널 핸들러
첨부 프로 퍼티와 첨부 신호 핸들러는 객체에 다른 방법으로는 사용할 수 없는 추가 프로퍼티나 신호 핸들러로 객체에 주석을 달 수 있는 메커니즘입니다. 특히 객체가 개별 객체와 특별히 관련된 프로퍼티나 신호에 액세스할 수 있도록 해줍니다.
QML 타입 구현은 특정 프로퍼티와 시그널을 사용하여 C++에서 첨부 타입을 생성하도록 선택할 수 있습니다. 그런 다음 이 유형의 인스턴스를 생성하고 런타임에 특정 객체에 첨부하여 해당 객체가 첨부 유형의 속성 및 신호에 액세스할 수 있도록 할 수 있습니다. 이러한 프로퍼티와 각 신호 핸들러 앞에 어태치먼트 유형의 이름을 붙여서 액세스할 수 있습니다.
첨부된 프로퍼티 및 핸들러에 대한 참조는 다음과 같은 구문 형식을 사용합니다:
<AttachingType>.<propertyName> <AttachingType>.on<SignalName>
예를 들어 ListView 유형에는 ListView 의 각 델리게이트 개체에서 사용할 수 있는 ListView.isCurrentItem 속성이 첨부되어 있습니다. 이 속성은 각 개별 델리게이트 개체에서 뷰에서 현재 선택된 항목인지 여부를 확인하는 데 사용할 수 있습니다:
import QtQuick ListView { width: 240; height: 320 model: 3 delegate: Rectangle { width: 100; height: 30 color: ListView.isCurrentItem ? "red" : "yellow" } }
이 경우 첨부 유형의 이름은 ListView
이고 해당 속성은 isCurrentItem
이므로 첨부된 속성을 ListView.isCurrentItem
이라고 합니다.
첨부된 신호 처리기도 같은 방식으로 참조됩니다. 예를 들어 Component.onCompleted 첨부된 시그널 핸들러는 일반적으로 컴포넌트의 생성 프로세스가 완료되었을 때 일부 자바스크립트 코드를 실행하는 데 사용됩니다. 아래 예시에서는 ListModel 컴포넌트가 완전히 생성되면 Component.onCompleted
시그널 핸들러가 자동으로 호출되어 모델을 채웁니다:
import QtQuick ListView { width: 240; height: 320 model: ListModel { id: listModel Component.onCompleted: { for (let i = 0; i < 10; i++) { append({ Name: `Item ${i}` }) } } } delegate: Text { text: index } }
첨부 유형의 이름은 Component
이고 해당 유형에는 completed 신호가 있으므로 첨부된 신호 처리기는 Component.onCompleted
로 참조됩니다.
첨부된 프로퍼티 및 시그널 핸들러 액세스에 대한 참고 사항
흔히 발생하는 오류는 첨부된 속성 및 신호 처리기가 이러한 속성이 첨부된 객체의 자식에서 직접 액세스할 수 있다고 가정하는 것입니다. 이는 사실이 아닙니다. 첨부 유형의 인스턴스는 특정 객체에만 첨부되며, 객체와 그 모든 자식에는 첨부되지 않습니다.
예를 들어, 아래는 첨부 속성과 관련된 이전 예제의 수정된 버전입니다. 이번에는 델리게이트가 Item 이고 색상이 지정된 Rectangle 이 해당 항목의 자식입니다:
import QtQuick ListView { width: 240; height: 320 model: 3 delegate: Item { width: 100; height: 30 Rectangle { width: 100; height: 30 color: ListView.isCurrentItem ? "red" : "yellow" // WRONG! This won't work. } } }
ListView.isCurrentItem
은 루트 델리게이트 객체에만 첨부되고 그 하위 객체에는 첨부되지 않기 때문에 예상대로 작동하지 않습니다. Rectangle 은 델리게이트 자체가 아니라 델리게이트의 자식이기 때문에 isCurrentItem
첨부 프로퍼티에 ListView.isCurrentItem
로 액세스할 수 없습니다. 따라서 대신 사각형은 루트 델리게이트를 통해 isCurrentItem
에 액세스해야 합니다:
ListView { delegate: Item { id: delegateItem width: 100; height: 30 Rectangle { width: 100; height: 30 color: delegateItem.ListView.isCurrentItem ? "red" : "yellow" // correct } } }
이제 delegateItem.ListView.isCurrentItem
는 델리게이트의 isCurrentItem
첨부 프로퍼티를 올바르게 참조합니다.
열거형 속성
열거형은 명명된 선택의 고정된 집합을 제공합니다. 열거형은 QML에서 enum
키워드를 사용하여 선언할 수 있습니다:
// MyText.qml Text { enum TextType { Normal, Heading } }
위에 표시된 것처럼 열거형 유형(예: TextType
)과 값(예: Normal
)은 대문자로 시작해야 합니다.
값은 <Type>.<EnumerationType>.<Value>
또는 <Type>.<Value>
을 통해 참조됩니다.
// MyText.qml Text { enum TextType { Normal, Heading } property int textType: MyText.TextType.Normal font.bold: textType === MyText.TextType.Heading font.pixelSize: textType === MyText.TextType.Heading ? 24 : 12 }
QML에서 열거형 사용에 대한 자세한 내용은 QML 값 유형 enumeration 설명서를 참조하십시오.
QML에서 열거형을 선언하는 기능은 Qt 5.10에 도입되었습니다.
© 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.