QML

Личный сайт Go-разработчика из Казани

1// This is a completely valid QML file that you can run using `qmlscene` if you copy the contents 2// into a *.qml file. 3// Comments start with double forward slashes. 4/* Or you 5 can have 6 multi line 7 comments 8 */ 9 10// Import statement syntax is 11// import ${MODULE_NAME} [${VERSION_NUMBER}] [as ${QUALIFIER}] 12import QtQuick 2.15 13import QtQuick.Window 2.15 14import QtQuick.Controls 2.15 as QQC 15import QtQuick.Layouts 1.15 16import Qt.labs.platform 1.1 17 18// Each QML document can contain only one top level type 19Window { 20 // Each object has a special and optional `id` attribute that can be used to refer to the 21 // declared objects. An `id` has to be unique in the same document. 22 id: root 23 width: 400 24 height: 600 25 title: "Learn QML in Y Minutes" 26 27 Item { 28 // Every object that can be declared inherits from QObject and contains at 29 // least one property, which is `objectName`. All the other properties are 30 // added by extending `QObject` type. This is an `Item` type and it contains 31 // the additional `width` and `height` properties and more. 32 objectName: "My Item" 33 // `id`s in the same document can be used anywhere in the same file. 34 // You cannot access an `id` from a different file. 35 width: root.width 36 } 37 38 // Signals are used to communicate that a certain event happened. 39 // Some types have built-in signals 40 Timer { 41 id: timer 42 interval: 500 43 onTriggered: { 44 console.log("Timer triggered!") 45 } 46 } 47 48 QtObject { 49 id: objSignals 50 // You can also declare your own signals. 51 signal clicked() 52 // Signals can also have arguments. 53 signal mousePositionChanged(int x, int y) 54 // The way to react to a signal emission is by adding signal handlers to 55 // the immediate object that the signal belongs to. 56 onClicked: () => { 57 // Do stuff here. 58 console.log("objSignals.clicked() signal is emitted.") 59 } 60 // Signal handlers must explicitly declare the arguments. 61 onMousePositionChanged: (x, y) => { 62 // Do stuff here. 63 console.log("objSignals.mousePositionChanged() signal is emitted. x=", x, "y=", y) 64 } 65 } 66 67 // If you want to declare signal handlers for other objects, you can use 68 // `Connections`. 69 Connections { 70 target: objSignals 71 72 // You can then declare functions with the same name as the signal 73 // handler. 74 function onClicked() { 75 console.log("objSignals.clicked() signal is handled from Connections.") 76 } 77 } 78 79 Item { 80 visible: false 81 82 // An object can support having child objects. You can add child objects 83 // by declaring types as follows: 84 Rectangle { 85 width: 16 86 height: 16 87 color: "red" 88 } 89 } 90 91 Item { 92 id: objProperties 93 // You can also declare your own properties. 94 // Syntax for declaring is 95 // [default] [required] [readonly] property ${TYPE} ${NAME} 96 property color nextColor 97 // Read only properties have to be initialized when declared. 98 readonly property color defaultColor: "red" 99 // Required properties have to be initialized where the reusable type is 100 // used. 101 required property color initialColor 102 103 // NOTE: Although the initial assignment can be done in the same file, 104 // it is not often the use case. 105 initialColor: "green" 106 107 // Properties are type safe and a property can only be assigned a value 108 // that matches the property type. 109 // property int volume: "four" // ERROR! 110 111 Item { 112 // You can create alias properties that hold a reference to another 113 // property. 114 115 property alias parentNextColor: objProperties.nextColor 116 117 // Assignments to alias properties alter the property that it holds 118 // a reference to. 119 parentNextColor: "blue" // Changes objProperties.nextColor 120 // Since `parentNextColor` is an alias to `nextColor`, any changes 121 // to `nextColor` will also be reflected to `parentNextColor`. 122 } 123 } 124 125 Item { 126 // Property assignment values can either be static or binding 127 // expressions. 128 // Static value 129 property int radius: 32 130 // Binding expressions describe a property's relationship to other 131 // properties. When the value of `radius` changes, the expression here 132 // will be re-evaluated. 133 property int diameter: radius * 2 134 135 onDiameterChanged: { 136 console.log("onDiameterChanged:", diameter) 137 } 138 } 139 140 ListView { 141 // Attached properties and signal handlers provide a way to extend an 142 // existing object and provide more information that is otherwise not 143 // immediately available. 144 width: 100 145 height: 30 146 model: 3 147 delegate: Rectangle { 148 // ListView provides an attached property for its children that can 149 // be used to access more information. 150 color: ListView.isCurrentItem ? "green" : "red" 151 } 152 // Attached types can also have signal handlers. 153 // `Component` is attached to every type that's available in QML. 154 Component.onCompleted: { 155 console.log("This signal handler is called after object is created.") 156 } 157 } 158 159 Rectangle { 160 // Since this rectangle is not created by the ListView, the attached 161 // type is not available. 162 color: ListView.isCurrentItem ? "green" : "red" 163 } 164 165 QtObject { 166 id: calculator 167 168 // Objects can also declare methods. Function declarations can annotate 169 // the arguments, or have no arguments at all. 170 function add(a: int, b: int): int { 171 // Semicolon at the end of a line is optional. 172 return a + b 173 } 174 175 function multiply(a: real, b: real): real { 176 return a * b; 177 } 178 } 179 180 MouseArea { 181 anchors.fill: parent 182 onClicked: (mouse) => { 183 console.log("2 + 2 =", calculator.add(2, 2)) 184 } 185 } 186 187 Item { 188 width: 100 189 // Methods can also be used as binding expressions. When `width` 190 // changes, the binding expression will evaluate and call `multiply`. 191 height: calculator.multiply(width, 0.5) 192 opacity: calculateOpacity() 193 194 function calculateOpacity() { 195 // If the function declaration contains references to other 196 // properties, changes to those properties also trigger a binding 197 // evaluation. 198 return height < 50 ? 0.5 : 1 199 } 200 } 201 202 // Each QML file that starts with an upper case name declares a re-usable 203 // component, e.g "RedRectangle.qml". 204 // In addition, reusable components can be declared in-line. 205 component RedRectangle: Rectangle { 206 color: "red" 207 } 208 209 // This inline component can then be used in the same file, or in other 210 // files by prefixing the type name with the file name that it belongs to. 211 // 212 // ${FILE_NAME}.RedRectangle { } 213 // or 214 RedRectangle { 215 } 216 217 // QML also supports enumeration declarations. 218 component MyText: Text { 219 enum TextType { 220 Normal, 221 Heading 222 } 223 224 // Enum types are assigned to integer properties. 225 property int textType: MyText.TextType.Normal 226 227 font.bold: textType == MyText.TextType.Heading 228 font.pixelSize: textType == MyText.TextType.Heading ? 24 : 12 229 } 230 231 // ----- Interactive Area 232 233 QQC.ScrollView { 234 anchors.fill: parent 235 contentWidth: container.implicitWidth 236 contentHeight: container.implicitHeight 237 238 Column { 239 id: container 240 spacing: 6 241 242 Row { 243 spacing: 2 244 245 QQC.Label { 246 width: 200 247 anchors.verticalCenter: parent.verticalCenter 248 text: "Click to start the timer.\nCheck the logs!" 249 wrapMode: QQC.Label.WordWrap 250 } 251 252 QQC.Button { 253 text: timer.running ? "Timer Running" : "Start Timer" 254 onClicked: { 255 timer.start() 256 } 257 } 258 } 259 260 Row { 261 spacing: 2 262 263 QQC.Label { 264 width: 200 265 anchors.verticalCenter: parent.verticalCenter 266 text: "Click to emit objSignals.clicked() signal" 267 wrapMode: QQC.Label.WordWrap 268 } 269 270 QQC.Button { 271 property int emissionCount: 0 272 273 text: "Emitted " + emissionCount + " times." 274 onClicked: { 275 objSignals.clicked() 276 emissionCount++ 277 } 278 } 279 } 280 281 Row { 282 spacing: 2 283 284 QQC.Label { 285 width: 200 286 anchors.verticalCenter: parent.verticalCenter 287 text: "Click to emit objSignals.mousePositionChanged() signal" 288 wrapMode: QQC.Label.WordWrap 289 } 290 291 QQC.Button { 292 property int emissionCount: 0 293 294 text: "Emitted " + emissionCount + " times." 295 onClicked: { 296 objSignals.mousePositionChanged(32, 32) 297 emissionCount++ 298 } 299 } 300 } 301 302 Rectangle { 303 width: 200 304 height: 80 305 color: objProperties.nextColor 306 307 QQC.Label { 308 width: 200 309 anchors.verticalCenter: parent.verticalCenter 310 text: "Click to change nextColor property." 311 wrapMode: QQC.Label.WordWrap 312 } 313 314 TapHandler { 315 onTapped: { 316 colorDialog.open() 317 } 318 } 319 320 ColorDialog { 321 id: colorDialog 322 currentColor: objProperties.initialColor 323 onColorChanged: { 324 objProperties.nextColor = color 325 326 } 327 } 328 } 329 330 Row { 331 spacing: 2 332 333 Rectangle { 334 width: 200 335 height: 80 336 color: "red" 337 radius: radiusSlider.value 338 339 QQC.Label { 340 width: parent.width 341 anchors.centerIn: parent 342 text: "Use slider to change radius" 343 wrapMode: QQC.Label.WordWrap 344 horizontalAlignment: Qt.AlignHCenter 345 } 346 } 347 348 QQC.Slider { 349 id: radiusSlider 350 width: 100 351 anchors.verticalCenter: parent.verticalCenter 352 from: 0 353 to: 80 354 } 355 } 356 } 357 } 358}