Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
definetypes.qdoc
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3/*!
4\page qtqml-documents-definetypes.html
5\title Defining Object Types through QML Documents
6\brief Description of how a QML document is a reusable type definition
7
8One of the core features of QML is that it enables QML object types to be
9easily defined in a lightweight manner through QML documents to suit the needs
10of individual QML applications. The standard \l {Qt Quick} module provides
11various types like \l Rectangle, \l Text and \l Image for building a QML
12application; beyond these, you can easily define your own QML types to be
13reused within your application. This ability to create your own types forms the
14building blocks of any QML application.
15
16
17\section1 Defining an Object Type with a QML File
18
19\section2 Naming Custom QML Object Types
20
21To create an object type, a QML document should be placed into a text file
22named as \e <TypeName>.qml where \e <TypeName> is the desired name of the type.
23The type name has the following requirements:
24
25\list
26 \li It must be comprised of alphanumeric characters or underscores.
27 \li It must begin with an uppercase letter.
28\endlist
29
30This document is then automatically recognized by the engine as a definition of
31a QML type. Additionally, a type defined in this manner is automatically made
32available to other QML files within the same local directory as the engine
33searches within the immediate directory when resolving QML type names.
34
35\note The QML engine does not automatically search remote directories this way.
36You have to add a qmldir file if your documents are loaded over the network. See
37\l{Importing QML Document Directories}.
38
39\section2 Custom QML Type Definition
40
41For example, below is a document that declares a \l Rectangle with a child \l
42MouseArea. The document has been saved to file named \c SquareButton.qml:
43
44\qml
45// SquareButton.qml
46import QtQuick 2.0
47
48Rectangle {
49 property int side: 100
50 width: side; height: side
51 color: "red"
52
53 MouseArea {
54 anchors.fill: parent
55 onClicked: console.log("Button clicked!")
56 }
57}
58\endqml
59
60Since the file is named \c SquareButton.qml, \b {this can now be used as a type
61named \c SquareButton by any other QML file within the same directory}. For
62example, if there was a \c myapplication.qml file in the same directory, it
63could refer to the \c SquareButton type:
64
65\qml
66// myapplication.qml
67import QtQuick 2.0
68
69SquareButton {}
70\endqml
71
72\image documents-definetypes-simple.png {The square button type in
73 myapplication.qml inherits properties defined in SquareButton.qml.}
74
75This creates a 100 x 100 red \l Rectangle with an inner \l MouseArea, as
76defined in \c SquareButton.qml. When this \c myapplication.qml document is
77loaded by the engine, it loads the SquareButton.qml document as a component and
78instantiates it to create a \c SquareButton object.
79
80The \c SquareButton type encapsulates the tree of QML objects declared in \c
81SquareButton.qml. When the QML engine instantiates a \c SquareButton object
82from this type, it is instantiating an object from the \l Rectangle tree
83declared in \c SquareButton.qml.
84
85\note the letter case of the file name is significant on some (notably UNIX)
86filesystems. It is recommended the file name case matches the case of the
87desired QML type name exactly - for example, \c Box.qml and not \c BoX.qml -
88regardless of the platform to which the QML type will be deployed.
89
90\section2 Inline Components
91
92Sometimes, it can be inconvenient to create a new file for a type, for
93instance when reusing a small delegate in multiple views. If you don't actually
94need to expose the type, but only need to create an instance,
95\l{QtQml::Component}{Component} is an option.
96But if you want to declare properties with the component types, or if you
97want to use it in multiple files, \c Component is not an option. In that case,
98you can use \e {inline components}. Inline components declare a new component
99inside of a file. The syntax for that is
100\code
101component <component name> : BaseType {
102 // declare properties and bindings here
103}
104\endcode
105
106Inside the file which declares the inline component, the type can be referenced
107simply by its name.
108
109\snippet qml/qml-documents/Images.qml document
110
111In other files, it has to be prefixed with the name of its containing component.
112
113\snippet qml/qml-documents/LabeledImageBox.qml document
114
115\note Inline components don't share their scope with the component they are
116declared in. In the following example, when \c A.MyInlineComponent in file
117B.qml gets created, a ReferenceError will occur, as \c root does not exist as
118an id in B.qml.
119It is therefore advisable not to reference objects in an inline component
120which are not part of it.
121
122\snippet qml/qml-documents/A.qml document
123\snippet qml/qml-documents/B.qml document
124
125\note Inline components cannot be nested.
126
127\section2 Importing Types Defined Outside the Current Directory
128
129If \c SquareButton.qml was not in the same directory as \c myapplication.qml,
130the \c SquareButton type would need to be specifically made available through
131an \e import statement in \c myapplication.qml. It could be imported from a
132relative path on the file system, or as an installed module; see \l {QML
133Modules}{module} for more details.
134
135
136\section1 Accessible Attributes of Custom Types
137
138The \b {root object} definition in a .qml file \b {defines the attributes that
139are available for a QML type}. All properties, signals and methods that belong
140to this root object - whether they are custom declared, or come from the QML
141type of the root object - are externally accessible and can be read and
142modified for objects of this type.
143
144For example, the root object type in the \c SquareButton.qml file above is \l
145Rectangle. This means any properties defined by the \l Rectangle type can be
146modified for a \c SquareButton object. The code below defines three \c
147SquareButton objects with customized values for some of the properties of the
148root \l Rectangle object of the \c SquareButton type:
149
150\qml
151// application.qml
152import QtQuick 2.0
153
154Column {
155 SquareButton { side: 50 }
156 SquareButton { x: 50; color: "blue" }
157 SquareButton { radius: 10 }
158}
159\endqml
160
161\image documents-definetypes-attributes.png {Column containing three square
162 buttons with different color and size properties}
163
164The attributes that are accessible to objects of the custom QML type include
165any \l{Defining Property Attributes}{custom properties}, \l{Defining Method
166Attributes}{methods} and \l{Defining Signal Attributes}{signals} that have
167additionally been defined for an object. For example, suppose the \l Rectangle
168in \c SquareButton.qml had been defined as follows, with additional properties,
169methods and signals:
170
171\qml
172// SquareButton.qml
173import QtQuick 2.0
174
175Rectangle {
176 id: root
177
178 property bool pressed: mouseArea.pressed
179
180 signal buttonClicked(real xPos, real yPos)
181
182 function randomizeColor() {
183 root.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
184 }
185
186 property int side: 100
187 width: side; height: side
188 color: "red"
189
190 MouseArea {
191 id: mouseArea
192 anchors.fill: parent
193 onClicked: (mouse)=> root.buttonClicked(mouse.x, mouse.y)
194 }
195}
196\endqml
197
198Any \c SquareButton object could make use of the \c pressed property, \c
199buttonClicked signal and \c randomizeColor() method that have been added to the
200root \l Rectangle:
201
202\qml
203// application.qml
204import QtQuick 2.0
205
206SquareButton {
207 id: squareButton
208
209 onButtonClicked: (xPos, yPos)=> {
210 console.log("Clicked", xPos, yPos)
211 randomizeColor()
212 }
213
214 Text { text: squareButton.pressed ? "Down" : "Up" }
215}
216\endqml
217
218Note that any of the \c id values defined in \c SquareButton.qml are not
219accessible to \c SquareButton objects, as id values are only accessible from
220within the component scope in which a component is declared. The \c
221SquareButton object definition above cannot refer to \c mouseArea in order to
222refer to the \l MouseArea child, and if it had an \c id of \c root rather than
223\c squareButton, this would not conflict with the \c id of the same value for
224the root object defined in \c SquareButton.qml as the two would be declared
225within separate scopes.
226*/