{"id":15209335,"url":"https://github.com/Furkanzmc/QML-Coding-Guide","last_synced_at":"2025-10-03T01:31:43.294Z","repository":{"id":43648065,"uuid":"146772699","full_name":"Furkanzmc/QML-Coding-Guide","owner":"Furkanzmc","description":"A collection of good practices when writing QML code - https://doc.qt.io/qt/qtqml-index.html","archived":false,"fork":false,"pushed_at":"2022-04-18T21:23:53.000Z","size":65,"stargazers_count":545,"open_issues_count":4,"forks_count":82,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-01-19T23:41:09.105Z","etag":null,"topics":["qml","qt"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Furkanzmc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-30T15:51:25.000Z","updated_at":"2025-01-15T09:22:42.000Z","dependencies_parsed_at":"2022-09-21T13:40:43.250Z","dependency_job_id":null,"html_url":"https://github.com/Furkanzmc/QML-Coding-Guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Furkanzmc%2FQML-Coding-Guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Furkanzmc%2FQML-Coding-Guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Furkanzmc%2FQML-Coding-Guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Furkanzmc%2FQML-Coding-Guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Furkanzmc","download_url":"https://codeload.github.com/Furkanzmc/QML-Coding-Guide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235059234,"owners_count":18929279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["qml","qt"],"created_at":"2024-09-28T07:23:21.188Z","updated_at":"2025-10-03T01:31:38.033Z","avatar_url":"https://github.com/Furkanzmc.png","language":null,"funding_links":[],"categories":["Uncategorized","X11/Wayland"],"sub_categories":["Uncategorized"],"readme":"# Introduction\n\nThe content that you see here is mostly based on my experience working with QML\nin a large project with a diverse team of developers and designers. I update\nthe document as my opinions about certain things become validated by real life\nexperience.\n\nYou may not agree with some of the ideas laid out here, in those cases please\ncreate an issue to discuss and update accordingly. I'll keep updating this guide\nas I learn new things. Contributions are vital to this document because it needs\nto reflect tried and validated ideas of more people to make sense in a general\nsense. It's likely that I may not have done a good job at explaining a concept.\nI would appreciate any contributions to improve it.\n\nPlease don't hesitate to raise issues and submit PRs. Even the tiniest\ncontribution matters.\n\n# Table of Contents\n\n- [Code Style](#code-style)\n    - [CS-1: Signal Handler Ordering](#cs-1-signal-handler-ordering)\n    - [CS-2: Property Initialization Order](#cs-2-property-initialization-order)\n    - [CS-3: Function Ordering](#cs-3-function-ordering)\n    - [CS-4: Animations](#cs-4-animations)\n    - [CS-5: Specifying IDs for Objects](#cs-5-specifying-ids-for-objects)\n    - [CS-6: Property Assignments](#cs-6-property-assignments)\n    - [CS-7: Import Statements](#cs-7-import-statements)\n    - [Full Example](#full-example)\n- [Bindings](#bindings)\n    - [B-1: Prefer Bindings over Imperative Assignments](#b-1-prefer-bindings-over-imperative-assignments)\n    - [B-2: Making `Connections`](#b-2-making-connections)\n    - [B-3: Use `Binding` Object](#b-3-use-binding-object)\n    - [B-4: KISS It](#b-4-kiss-it)\n    - [B-5: Be Lazy](#b-5-be-lazy)\n    - [B-6: Avoid Unnecessary Re-Evaluations](#b-6-avoid-unnecessary-re-evaluations)\n- [C++ Integration](#c-integration)\n    - [CI-1: Avoid Context Properties](#ci-1-avoid-context-properties)\n    - [CI-2: Use Singleton for Common API Access](#ci-2-use-singleton-for-common-api-access)\n    - [CI-3: Prefer Instantiated Types Over Singletons For Data](#ci-3-prefer-instantiated-types-over-singletons-for-data)\n    - [CI-4: Watch Out for Object Ownership Rules](#ci-4-watch-out-for-object-ownership-rules)\n- [Performance and Memory](#performance-and-memory)\n    - [PM-1: Reduce the Number of Implicit Types](#pm-1-reduce-the-number-of-implicit-types)\n- [Signal Handling](#signal-handling)\n    - [SH-1: Try to Avoid Using connect Function in Models](#sh-1-try-to-avoid-using-connect-function-in-models)\n    - [SH-2: When to use Functions and Signals](#sh-2-when-to-use-functions-and-signals)\n- [JavaScript](#javascript)\n    - [JS-1: Use Arrow Functions](#js-1-use-arrow-functions)\n    - [JS-2: Use the Modern Way of Declaring Variables](#js-2-use-the-modern-way-of-declaring-variables)\n- [States and Transitions](#states-and-transitions)\n    - [ST-1: Don't Define Top Level States](#st-1-dont-define-top-level-states)\n- [Visual Items](#visual-items)\n    - [VI-1: Distinguish Between Different Types of Sizes](#vi-1-distinguish-between-different-types-of-sizes)\n    - [VI-2: Be Careful with a Transparent `Rectangle`](#vi-2-be-careful-with-a-transparent-rectangle)\n\n\n# Code Style\n\nThis section provides details about how to format the order of properties, signals,\nand functions to make things easy on the eyes and quickly switch to related code block.\n\n[QML object attributes](https://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html)\nare always structured in the following order:\n\n- id\n- Property declarations\n- Signal declarations\n- Property initializations\n- Attached properties and signal handlers\n- States\n- Transitions\n- Signal handlers\n- Child objects\n  + Visual Items\n  + Qt provided non-visual items\n  + Custom non-visual items\n- `QtObject` for encapsulating private members[1](https://bugreports.qt.io/browse/QTBUG-11984)\n- JavaScript functions\n\nThe main purpose for this order is to make sure that the most intrinsic properties of a type is\nalways the most visible one in order to make the interface easier to digest at a first glance.\nAlthough it could be argued that the JavaScript functions are also part of the interface, the ideal\nis to have no functions at all.\n\n## CS-1: Signal Handler Ordering\n\nWhen handling the signals attached to an `Item`, make sure to always leave\n`Component.onCompleted` to the last line.\n\n```qml\n// Wrong\nItem {\n    Component.onCompleted: {\n    }\n    onSomethingHappened: {\n    }\n}\n\n// Correct\nItem {\n    onSomethingHappened: {\n    }\n    Component.onCompleted: {\n    }\n}\n```\n\nThis is because it mentally makes for a better picture because\n`Component.onCompleted` is expected to be fired when the components construction\nis complete.\n\n------\n\nIf there are multiple signal handlers in an `Item`, then the ones with least amount\nof lines may be placed at the top. As the implementation lines increases, the handler\nalso moves down. The only exception to this is `Component.onCompleted` signal, it\nis always placed at the bottom.\n\n```qml\n// Wrong\nItem {\n    onOtherEvent: {\n        // Line 1\n        // Line 2\n        // Line 3\n        // Line 4\n    }\n    onSomethingHappened: {\n        // Line 1\n        // Line 2\n    }\n}\n\n// Correct\nItem {\n    onSomethingHappened: {\n        // Line 1\n        // Line 2\n    }\n    onOtherEvent: {\n        // Line 1\n        // Line 2\n        // Line 3\n        // Line 4\n    }\n}\n```\n\n## CS-2: Property Initialization Order\n\nThe first property assignment must always be the `id` of the component. If you\nwant to declare custom properties for a component, the declarations are always\nabove the first property assignment.\n\n```qml\n// Wrong\nItem {\n    someProperty: false\n    property int otherProperty: -1\n    id: myItem\n}\n\n// Correct\nItem {\n    id: myItem\n\n    property int otherProperty: -1\n\n    someProperty: false\n}\n```\n\nThere's also a bit of predefined order for property assignments. The order goes\nas follows:\n\n- id\n- x\n- y\n- width\n- height\n- anchors\n\nThe goal here is to put the most obvious and defining properties at the top for\neasy access and visibility. For example, for an `Image` you may decide to also\nput `sourceSize` above `anchors`.\n\n------\n\nIf there are also property assignments along with signal handlers, make sure to\nalways put property assignments above the signal handlers.\n\n```qml\n// Wrong\nItem {\n    onOtherEvent: {\n    }\n    someProperty: true\n    onSomethingHappened: {\n    }\n    x: 23\n    y: 32\n}\n\n// Correct\nItem {\n    x: 23\n    y: 32\n    someProperty: true\n    onOtherEvent: {\n    }\n    onSomethingHappened: {\n    }\n}\n```\n\nIt is usually harder to see the property assignments If they are mixed with\nsignal handlers. That's why we are putting the assignments above the signal\nhandlers.\n\n### CS-3: Function Ordering\n\nAlthough there are no private and public functions in QML, you can provide a\nsimilar mechanism by wrapping the properties and functions that are only supposed\nto be used internally in `QtObject `.\n\nPublic function implementations are always put at the very bottom of the file. Even though we\nprioritize putting the public declarations at the top of the file for other types, I encourage you\nto put the public functions at the bottom because if the number of lines get larger for a function,\nit significantly reduces the readability of the QML document. Ideally, you shouldn't have any\nfunctions at all and strive to rely on declarative properties of your component as much as\npossible.\n\n```qml\n// Wrong\nItem {\n\n    function someFunction() {\n    }\n\n    someProperty: true\n}\n\n// Correct\nItem {\n    someProperty: true\n    onOtherEvent: {\n    }\n    onSomethingHappened: {\n    }\n\n    function someFunction() {\n    }\n}\n```\n\n### CS-4: Animations\n\nWhen using any subclass of `Animation`, especially nested ones like\n`SequentialAnimation`, try to reduce the number of properties in one line.\nMore than 2-3 assignments on the same line becomes harder to reason with after\na while. Or maybe you can keep the one line assignments to whatever line length\nconvention you have set up for your project.\n\nSince animations are harder to imagine in your mind, you will benefit from\nkeeping the animations as simple as possible.\n\n```qml\n// Bad\nNumberAnimation { target: root; property: \"opacity\"; duration: root.animationDuration; from: 0; to: 1 }\n\n// Depends on your convention. The line does not exceed 80 characters.\nPropertyAction { target: root; property: \"visible\"; value: true }\n\n// Good.\nSequentialAnimation {\n    PropertyAction {\n        target: root\n        property: \"visible\"\n        value: true\n    }\n\n    NumberAnimation {\n        target: root\n        property: \"opacity\"\n        duration: root.animationDuration\n        from: 0\n        to: 1\n    }\n}\n```\n\n### CS-5: Specifying IDs for Objects\n\nIf an object does not need to be accessed for a functionality, avoid setting the `id` property.\nThis way you'll be less likely to run into duplicate `id` problem. Also, having an id for an object\nputs additional cognitive stress because it now means that there's additional relationships that we\nneed to care for.\n\nIf you want to mark the type with a descriptor but you don't intend to reference\nthe type, you can use `objectName` instead or just plain old comments.\n\nMake sure that the top most component in the file always has `root` as its `id`.\nQt will make unqualified name look up deprecated in QML 3, so it's better to\nstart giving IDs to your components now and use qualified look up.\n\nSee [QTBUG-71578](https://bugreports.qt.io/browse/QTBUG-71578) and\n[QTBUG-76016](https://bugreports.qt.io/browse/QTBUG-76016) for more details\non this.\n\n### CS-6: Property Assignments\n\nWhen assigning grouped properties, always prefer the dot notation If you are only\naltering just one property. Otherwise, always use the group notation.\n\n```qml\nImage {\n    anchors.left: parent.left // Dot notation\n    sourceSize { // Group notation\n        width: 32\n        height: 32\n    }\n}\n```\n\nWhen you are assigning the component to a `Loader`'s `sourceComponent` in different\nplaces in the same file, consider using the same implementation. For example, in\nthe following example there are two instances of the same component. If both of\nthose `SomeSpecialComponent` are meant to be identical it is a better idea to\nwrap `SomeSpecialComponent` in a `Component`.\n\n```qml\n// BEGIN bad.\nLoader {\n    id: loaderOne\n    sourceComponent: SomeSpecialComponent {\n        text: \"Some Component\"\n    }\n}\n\nLoader {\n    id: loaderTwo\n    sourceComponent: SomeSpecialComponent {\n        text: \"Some Component\"\n    }\n}\n// END bad.\n\n// BEGIN good.\nLoader {\n    id: loaderOne\n    sourceComponent: specialComponent\n}\n\nLoader {\n    id: loaderTwo\n    sourceComponent: specialComponent\n}\n\nComponent {\n    id: specialComponent\n\n    SomeSpecialComponent {\n        text: \"Some Component\"\n    }\n}\n// END good.\n```\n\nThis ensures that whenever you make a change to `specialComponent` it will take\neffect in all of the `Loader`s. In the bad example, you would have to duplicate\nthe same change.\n\nWhen in a similar situation without the use of `Loader`, you can use inline\ncomponents.\n\n```qml\ncomponent SomeSpecialComponent: Rectangle {\n\n}\n```\n\n### CS-7: Import Statements\n\nAs a general rule, you should always prefer C++ over JavaScript to do heavy lifting. If there are\ncases where you justify having a separate JavaScript file, keep these in mind.\n\nIf you are importing a JavaScript file, make sure to not include the same\nmodule in both the QML file and the JavaScript file. JavaScript files share the\nimports from the QML file so you can take advantage of that. If the JavaScript\nfile is meant as a library, this does not apply.\n\nIf you are not making use of the imported module in the QML file, consider moving\nthe import statement to the JavaScript file. But note that once you import something\nin the JavaScript file, the imports will no longer be shared. For the complete\nrules see [here](https://doc.qt.io/qt-5/qtqml-javascript-imports.html#imports-within-javascript-resources).\n\n`Qt.include()` is [deprecated](https://doc.qt.io/qt-6/qml-qtqml-qt-obsolete.html#include-method)\nand should not be used.\n\nAs a general rule, you should avoid having unused import statements.\n\n#### Import Order\n\nWhen importing other modules, use the following order;\n\n- Qt modules\n- Third party modules\n- Local C++ module imports\n- QML folder imports\n\n### Full Example\n\n```qml\n// First Qt imports\nimport QtQuick 2.15\nimport QtQuick.Controls 2.15\n// Then custom imports\nimport my.library 1.0\n\nItem {\n    id: root\n\n    // ----- Property Declarations\n\n    // Required properties should be at the top.\n    required property int radius: 0\n\n    property int radius: 0\n    property color borderColor: \"blue\"\n\n    // ----- Signal declarations\n\n    signal clicked()\n    signal doubleClicked()\n\n    // ----- In this section, we group the size and position information together.\n\n    x: 0\n    y: 0\n    z: 0\n    width: 100\n    height: 100\n    anchors.top: parent.top // If a single assignment, dot notation can be used.\n    // If the item is an image, sourceSize is also set here.\n    // sourceSize: Qt.size(12, 12)\n\n    // ----- Then comes the other properties. There's no predefined order to these.\n\n    // Do not use empty lines to separate the assignments. Empty lines are reserved\n    // for separating type declarations.\n    enabled: true\n    layer.enabled: true\n\n    // ----- Then attached properties and attached signal handlers.\n\n    Layout.fillWidth: true\n    Drag.active: false\n    Drag.onActiveChanged: {\n\n    }\n\n    // ----- States and transitions.\n\n    states: [\n        State {\n\n        }\n    ]\n    transitions: [\n        Transitions {\n\n        }\n    ]\n\n    // ----- Signal handlers\n\n    onWidthChanged: { // Always use curly braces.\n\n    }\n    // onCompleted and onDestruction signal handlers are always the last in\n    // the order.\n    Component.onCompleted: {\n\n    }\n    Component.onDestruction: {\n\n    }\n\n    // ----- Visual children.\n\n    Rectangle {\n        height: 50\n        anchors: { // For multiple assignments, use group notation.\n            top: parent.top\n            left: parent.left\n            right: parent.right\n        }\n        color: \"red\"\n        layer: {\n            enabled: true\n            samples: 4\n        }\n    }\n\n    Rectangle {\n        width: parent.width\n        height: 1\n        color: \"green\"\n    }\n\n    // ----- Qt provided non-visual children\n\n    Timer {\n\n    }\n\n    // ----- Custom non-visual children\n\n    MyCustomNonVisualType {\n\n    }\n\n    QtObject {\n        id: privates\n\n        property int diameter: 0\n    }\n\n    // ----- JavaScript functions\n\n    function collapse() {\n\n    }\n\n    function setCollapsed(value: bool) {\n        if (value === true) {\n        }\n        else {\n        }\n    }\n}\n```\n\n# Bindings\n\nBindings are a powerful tool when used responsibly. Bindings are evaluated\nwhenever a property it depends on changes and this may result in poor performance\nor unexpected behaviors. Even when the binding is simple, its consequence can be\nexpensive. For instance, a binding can cause the position of an item to change\nand every other item that depends on the position of that item or is anchored to\nit will also update its position.\n\nSo consider the following rules when you are using bindings.\n\n## B-1: Prefer Bindings over Imperative Assignments\n\nSee the related section on [Qt Documentation](https://doc.qt.io/qt-5/qtquick-bestpractices.html#prefer-declarative-bindings-over-imperative-assignments).\n\nThe official documentation explains things well, but it is also important to\nunderstand the performance complications of bindings and understand where the\nbottlenecks can be.\n\nIf you suspect that the performance issue you are having is related to\nexcessive evaluations of bindings, then use the QML profiler to confirm your\nsuspicion and then opt-in to use imperative option.\n\nRefer to the [official documentation](https://doc.qt.io/qtcreator/creator-qml-performance-monitor.html)\non how to use QML profiler.\n\n## B-2: Making `Connections`\n\nA `Connections` object is used to handle signals from arbitrary `QObject` derived\nclasses in QML. One thing to keep in mind when using connections is the default\nvalue of `target` property of the `Connections` is its parent if not explicitly\nset to something else. If you are setting the target after dynamically creating\na QML object, you might want to set the `target` to `null` otherwise you might\nget signals that are not meant to be handled.\n\nAlso note that using a `Connections` object will incur a slight performance/memory penalty since\nit's another allocation that has to be done. If you are concerned about this you can use\n`QtObject.connect` method, but [be careful](#sh-1-try-to-avoid-using-connect-function-in-models) of\nthe pitfalls of this solution.\n\n```qml\n// Bad\nItem {\n    id: root\n    onSomethingHappened: {\n        // Set the target of the Connections.\n    }\n\n    Connections {\n        // Notice that target is not set so it's implicitly set to root.\n        onWidthChanged: {\n            // Do something. But since Item also has a width property we may\n            // handle the change for root until the target is set explicitly.\n        }\n    }\n}\n\n// Good\nItem {\n    id: root\n    onSomethingHappened: {\n        // Set the target of the Connections.\n    }\n\n    Connections {\n        target: null // Good. Now we won't have the same problem.\n        onWidthChanged: {\n            // Do something. Only handles the changes for the intended target.\n        }\n    }\n}\n```\n\n## B-3: Use `Binding` Object\n\n`Binding`'s `when` property can be used to enable or disable a binding expression\ndepending on a condition. If the binding that you are using is complex and does\nnot need to be executed every time a property changes, this is a good idea to\nreduce the binding execution count.\n\nUsing the same example above, we can rewrite it as follows using a `Binding` object.\n\n```qml\nRectangle {\n    id: root\n\n    Binding on color {\n        when: mouseArea.pressed\n        value: mouseArea.pressed ? \"red\" : \"yellow\"\n    }\n\n    MouseArea {\n        id: mouseArea\n        anchors.fill: parent\n    }\n}\n```\n\nAgain, this is a really simple example to get the point out. In a real life\nsituation, you would not get more benefit from using `Binding` object in this\ncase unless the binding expression is expensive (e.g It changes the item's\n`anchor` which causes a whole chain reaction and causes other items to be\nrepositioned.).\n\n## B-4: KISS It\n\nRemoved. No longer applies. Keeping the record to not mess with item numbers.\n\n### Justification for Removal\n\nThe QML engine changed a lot since I first wrote this guide. While it is still a good idea to keep\nthe bindings simple (ie Don't call any expensive functions in a binding), it'd be incorrect to\nsuggest there would be certain optimizations. The advice about avoiding `var` properties still\napply, and you should strive to use the most precise type possible.\n\n### Previous Content\n\n~You are probably already familiar with the [KISS principle](https://en.wikipedia.org/wiki/KISS_principle).\nQML supports optimization of binding expressions. Optimized bindings do not require\na JavaScript environment hence it runs faster. The basic requirement for optimization\nof bindings is that the type  information of every symbol accessed must be known at\ncompile time.~\n\n~So, avoid accessing `var` properties. You can see the full list of prerequisites\nof optimized bindings [here](https://doc.qt.io/qt-5/qtquick-performance.html#bindings).~\n\n## B-5: Be Lazy\n\nRemoved. No longer applies. Keeping the record to not mess with item numbers.\n\n### Justification for Removal\n\nDeclarative is better than imperative in QML. This promotes an imperative approach, and doesn't\nprovide a great value. If you are in need of disabling or enabling bindings, prefer\n[Binding](#b-1-prefer-bindings-over-imperative-assignments) objects instead. Or use a boolean flag\nto enable a binding, e.g `visible: privates.bindingEnabled ? root.count \u003e 0 : false`.\n\n### Previous Content\n\n~There may be cases where you don't need the binding immediately but when a certain\ncondition is met. By lazily creating a binding, you can avoid unnecessary executions.\nTo create a binding during runtime, you can use `Qt.binding()`.~\n\n```qml\nItem {\n    property int edgePosition: 0\n\n    Component.onCompleted: {\n        if (checkForSomeCondition() == true) {\n            // bind to the result of the binding expression passed to Qt.binding()\n            edgePosition = Qt.binding(function() { return x + width })\n        }\n    }\n}\n```\n\n~You can also use `Qt.callLater` to reduce the redundant calls to a function.~\n\n## B-6: Avoid Unnecessary Re-Evaluations\n\nIf you have a loop or process where you update the value of the property, you may\nwant to use a temporary local variable where you accumulate those changes and only\nreport the last value to the property. This way you can avoid triggering re-evaluation\nof binding expressions during the intermediate stages of accumulation.\n\nHere's a bad example straight from Qt documentation:\n\n```qml\nimport QtQuick 2.3\n\nItem {\n    id: root\n\n    property int accumulatedValue: 0\n\n    width: 200\n    height: 200\n    Component.onCompleted: {\n        const someData = [ 1, 2, 3, 4, 5, 20 ];\n        for (let i = 0; i \u003c someData.length; ++i) {\n            accumulatedValue = accumulatedValue + someData[i];\n        }\n    }\n\n    Text {\n        anchors.fill: parent\n        text: root.accumulatedValue.toString()\n        onTextChanged: console.log(\"text binding re-evaluated\")\n    }\n}\n```\n\nAnd here is the proper way of doing it:\n\n```qml\nimport QtQuick 2.3\n\nItem {\n    id: root\n\n    property int accumulatedValue: 0\n\n    width: 200\n    height: 200\n    Component.onCompleted: {\n        const someData = [ 1, 2, 3, 4, 5, 20 ];\n        let temp = accumulatedValue;\n        for (let i = 0; i \u003c someData.length; ++i) {\n            temp = temp + someData[i];\n        }\n\n        accumulatedValue = temp;\n    }\n\n    Text {\n        anchors.fill: parent\n        text: root.accumulatedValue.toString()\n        onTextChanged: console.log(\"text binding re-evaluated\")\n    }\n}\n```\n\nAlso note that `list` type doesn't have a change signal associated with adding/moving/removing\nelements from it. If you are using a `list` type to store sequential data, make sure that the\nplaces where this property is used does not do expensive things (e.g populating a view).\n\n# C++ Integration\n\nQML can be extended with C++ by exposing the `QObject` classes using the `Q_OBJECT`\nmacro or custom data types using `Q_GADGET` macro.\nIt always should be preferred to use C++ to add functionality to a QML application.\nBut it is important to know which is the best way to expose your C++ classes, and\nit depends on your use case.\n\n## CI-1: Avoid Context Properties\n\nContext properties are registered using\n\n```cpp\nrootContext()-\u003esetContextProperty(\"someProperty\", QVariant());\n```\n\nContext properties always takes in a `QVariant`, which means that whenever you access the property\nit is re-evaluated because in between each access the property may be changed as\n`setContextProperty()` can be used at any moment in time.\n\nContext properties are expensive to access, and hard to reason with. When you are writing QML code,\nyou should strive to reduce the use of contextual variables (A variable that doesn't exist in the\nimmediate scope, but the one above it.) and global state. Each QML document should be able to run\nwith QML scene provided that the required properties are set.\n\nSee [QTBUG-73064](https://bugreports.qt.io/browse/QTBUG-73064).\n\n## CI-2: Use Singleton for Common API Access\n\nThere are bound to be cases where you have to provide a single instance for a\nfunctionality or common data access. In this situation, resort to using a singleton\nas it will have a better performance and be easier to read. Singletons are also\na good option to expose enums to QML.\n\n```cpp\nclass MySingletonClass : public QObject\n{\npublic:\n    static QObject *singletonProvider(QQmlEngine *qmlEngine, QJSEngine *jsEngine)\n    {\n        if (m_Instance == nullptr) {\n            m_Instance = new MySingletonClass(qmlEngine);\n        }\n\n        Q_UNUSED(jsEngine);\n        return m_Instance;\n    }\n};\n\n// In main.cpp\nqmlRegisterSingletonType\u003cSingletonTest\u003e(\"MyNameSpace\", 1, 0, \"MySingletonClass\",\n                                        MySingletonClass::singletonProvider);\n```\n\nYou should strive to not use singletons for shared data access. Reusable components are especially\na bad place to access singletons. Ideally, all QML documents should rely on the customization\nthrough properties to change its content.\n\nLet's imagine a scenario where we are creating a paint app where we can change the currently\nselected color on the palette. We only have one instance of the palette, and the data from this is\naccessed throughout our C++ code. So we decided that it makes sense to expose it as a singleton to\nQML side.\n\n```qml\n// ColorViewer.qml\nRow {\n    id: root\n\n    Rectangle {\n        color: Palette.selectedColor\n    }\n\n    Text {\n        text: Palette.selectedColorName\n    }\n}\n```\n\nWith this code, we bind our component to `Palette` singleton. Who ever wants to use our `ColorViewer`\nthey won't be able to change it so they can show some other selected color.\n\n```qml\n// ColorViewer_2.qml\nRow {\n    id: root\n\n    property alias selectedColor: colorIndicator.color\n    property alias selectedColorName: colorLabel.color\n\n    Rectangle {\n        id: colorIndicator\n        color: Palette.selectedColor\n    }\n\n    Text {\n        id: colorLabel\n        text: Palette.selectedColorName\n    }\n}\n```\n\nThis would allow the users of this component to set the color and the name from outside, but we\nstill have a dependency on the singleton.\n\n```qml\n// ColorViewer_3.qml\nRow {\n    id: root\n\n    property alias selectedColor: colorIndicator.color\n    property alias selectedColorName: colorLabel.color\n\n    Rectangle {\n        id: colorIndicator\n    }\n\n    Text {\n        id: colorLabel\n    }\n}\n```\n\nThis version allows you to de-couple from the singleton, enable it to be resuable in any context\nthat wants to show a selected color, and you could easily run this through `qmlscene` and inspect\nits behavior.\n\n## CI-3: Prefer Instantiated Types Over Singletons For Data\n\nInstantiated types are exposed to QML using:\n\n```cpp\n// In main.cpp\nqmlRegisterType\u003cColorModel\u003e(\"MyNameSpace\", 1, 0, \"ColorModel\");\n```\n\nInstantiated types have the benefit of having everything available to you to understand and digest\nin the same document. They are easier to change at run-time without creating side effects, and easy\nto reason with because when looking at a document, you don't need to worry about any global state\nbut the state of the type that you are dealing with at hand.\n\n```qml\n// ColorsWindow.qml\nWindow {\n    id: root\n\n    Column {\n        Repeater {\n            model: Palette.selectedColors\n            delegate: ColorViewer {\n                required property color color\n                required property string colorName\n\n                selectedColor: color\n                selectedColorName: colorName\n            }\n        }\n    }\n}\n```\n\nThe code above is a perfectly valid QML code. We'll get our model from the singleton, and display it\nwith the reusable component we created in CI-2. However, there's still a problem here. `ColorsWindow`\nis now bound to the model from `Palette` singleton. And If I wanted to have the user select two\ndifferent sets of colors, I would need to create another file with the same contents and use that.\nNow we have 2 components doing basically the same thing. And those two components need to be\nmaintained.\n\nThis also makes it hard to prototype. If I wanted to see two different versions of this window with\ndifferent colors at the same time, I can't do it because I'm using a singleton. Or, If I wanted to\npop up a new window that shows the users the variants of a color set, I can't do it because the data\nis bound to the singleton.\n\nA better approach here is to either use an instantiated type or expect the model as a property.\n\n```qml\n// ColorsWindow.qml\nWindow {\n    id: root\n\n    property PaletteColorsModel model\n\n    Column {\n        Repeater {\n            model: root.model\n            // Alternatively\n            model: PaletteColorsModel { }\n            delegate: ColorViewer {\n                required property color color\n                required property string colorName\n\n                selectedColor: color\n                selectedColorName: colorName\n            }\n        }\n    }\n}\n```\n\nNow, I can have the same window up at the same time with different color sets because they are not\nbound to a singleton. During prototyping, I can provide a dummy data easily by adding\n`PaletteColorElement` types to the model, or by requesting test dataset with something like:\n\n```qml\nPaletteColorsModel {\n    testData: \"prototype_1\"\n}\n```\n\nThis test data could be auto-generated, or it could be provided by a JSON file. The beauty is that\nI'm no longer bound to a singleton, that I have the freedom to instantiate as many of these windows\nas I want.\n\nThere may be cases where you actually truly want the data to be the same every where. In these\ncases, you should still provide an instantiated type instead of a singleton. You can still access\nthe same resource in the C++ implementation of your model and provide that to QML. And you would\nstill retain the freedom of making your data easily pluggable in different context and it would\nincrease the re-usability of your code.\n\n```cpp\nclass PaletteColorsModel\n{\n    explicit PaletteColorsModel(QObject* parent = nullptr)\n    {\n        initializeModel(MyColorPaletteSingleton::instance().selectedColors());\n    }\n};\n```\n\n## CI-4: Watch Out for Object Ownership Rules\n\nWhen you are exposing data to QML from C++, you are likely to pass around custom\ndata types as well. It is important to realize the implications of ownership when\nyou are passing data to QML. Otherwise you might end up scratching your head trying\nto figure out why your app crashes.\n\nIf you are exposing custom data type, prefer to set the parent of that data to the\nC++ class that transmits it to QML. This way, when the C++ class gets destroyed\nthe custom data type also gets destroyed and you won't have to worry about releasing\nmemory manually.\n\nThere might also be cases where you expose data from a singleton class without a\nparent and the data gets destroyed because QML object that receives it will take\nownership and destroy it. And you will end up accessing data that doesn't exist.\nOwnership is **not** transferred as the result of a property access. For data\nownership rules see [here](https://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership).\n\nTo learn more about the real life implications of this read [this blog post](https://www.embeddeduse.com/2018/04/02/qml-engine-deletes-c-objects-still-in-use/).\n\n# Performance and Memory\n\nMost applications are not likely to have memory limitations. But in case you are\nworking on a memory limited hardware or you just really care about memory allocations,\nfollow these steps to reduce your memory usage.\n\n## PM-1: Reduce the Number of Implicit Types\n\nIf a type defines custom properties, that type becomes an implicit type to the JS\nengine and additional type information has to be stored.\n\n```qml\nRectangle { } // Explicit type because it doesn't contain any custom properties\n\nRectangle {\n    // The deceleration of this property makes this Rectangle an implicit type.\n    property int meaningOfLife: 42\n}\n```\n\nYou should follow the advice from the [official documentation](http://doc.qt.io/qt-5/qtquick-performance.html#avoid-defining-multiple-identical-implicit-types)\nand split the type into its own component If it's used in more than one place.\nBut sometimes, that might not make sense for your case. If you are using a lot of\ncustom properties in your QML file, consider wrapping the custom properties of\ntypes in a `QtObject`. Obviously, JS engine will still need to allocate memory\nfor those types, but you already gain the memory efficiency by avoiding the\nimplicit types. Additionally, wrapping the properties in a `QtObject` uses less\nmemory than scattering those properties to different types.\n\nConsider the following example:\n\n```qml\nWindow {\n    Rectangle { id: r1 } // Explicit type. Memory 64b, 1 allocation.\n\n    // Implicit type. Memory 128b, 3 allocations.\n    Rectangle { id: r2; property string nameTwo: \"\" }\n\n    QtObject { // Implicit type. Memory 128b, 3 allocations.\n        id: privates\n        property string name: \"\"\n    }\n}\n```\n\nIn this example, the introduction of a custom property to added additional 64b\nof memory and 2 more allocations. Along with `privates`, memory usage adds up to\n256b. The total memory usage is 320b.\n\nYou can use the QML profiler to see the allocations and memory usage for each\ntype. If we change that example to the following, you'll see that both memory\nusage and number of allocations are reduced.\n\n```qml\nWindow {\n    Rectangle { id: r1 } // Explicit type. Memory 64b, 1 allocation.\n\n    Rectangle { id: r2 } // Explicit type. Memory 64b, 1 allocation.\n\n    QtObject { // Implicit type. Memory 160b, 4 allocations.\n        id: privates\n\n        property string name: \"\"\n        property string nameTwo: \"\"\n    }\n}\n```\n\nIn the second example, total memory usage is 288b. This is really a minute\ndifference in this context, but as the number of components increase in a\nproject with memory constrained hardware, it can start to make a difference.\n\n# Signal Handling\n\nSignals are a very powerful mechanism in Qt/QML. And the fact that you can\nconnect to signals from C++ makes it even better. But in some situations, If you\ndon't handle them correctly you might end up scratching your head.\n\n## SH-1: Try to Avoid Using connect Function in Models\n\nYou can have signals in the QML side, and the C++ side. Here's an example for\nboth cases.\n\nQML Example.\n\n```qml\n// MyButton.qml\nimport QtQuick.Controls 2.3\n\nButton {\n    id: root\n\n    signal rightClicked()\n}\n```\n\nC++ Example:\n\n```cpp\nclass MyButton\n{\n    Q_OBJECT\n\nsignals:\n    void rightClicked();\n};\n```\n\nThe way you connect to signals is using the syntax\n\n```qml\nitem.somethingChanged.connect(function() {})\n```\n\nWhen this method is used, you create a function that is connected to the\n`somethingChanged` signal.\n\nConsider the following example:\n\n```qml\n// MyItem.qml\nItem {\n    id: root\n\n    property QtObject customObject\n\n    objectName: \"my_item_is_alive\"\n    onCustomObjectChanged: {\n        customObject.somethingChanged.connect(() =\u003e {\n            console.log(root.objectName)\n        })\n    }\n}\n```\n\nThis is a perfectly legal code. And it would most likely work in most scenarios.\nBut, if the life time of the `customObject` is not managed in `MyItem`, meaning\nif the `customObject` can keep on living when the `MyItem` instance is destroyed,\nyou run into problems.\n\nThe connection is created in the context of `MyItem`, and the function naturally\nhas access to its enclosing context. So, as long as we have the instance of\n`MyItem`, whenever `somethingChanged` is emitted we'd get a log saying\n`my_item_is_alive`.\n\nHere's a quote directly from [Qt documentation](https://doc.qt.io/qt-5/qml-qtquick-listview.html):\n\n\u003e Delegates are instantiated as needed and may be destroyed at any time. They\n\u003e are parented to `ListView`'s `contentItem`, not to the view itself. State\n\u003e should never be stored in a delegate.\n\nSo you might be making use of an external object to store state. But what If\n`MyItem` is used in a `ListView`, and it went out of view and it was destroyed\nby `ListView`?\n\nLet's examine what happens with a more concrete example.\n\n```qml\nApplicationWindow {\n    id: root\n\n    property list\u003cQtObject\u003e myObjects: [\n        QtObject {\n            signal somethingHappened()\n        },\n        QtObject {\n            signal somethingHappened()\n        },\n        QtObject {\n            signal somethingHappened()\n        },\n        QtObject {\n            signal somethingHappened()\n        },\n        QtObject {\n            signal somethingHappened()\n        },\n        QtObject {\n            signal somethingHappened()\n        },\n        QtObject {\n            signal somethingHappened()\n        },\n        QtObject {\n            signal somethingHappened()\n        }\n    ]\n\n    width: 640\n    height: 480\n\n    ListView {\n        anchors {\n            top: parent.top\n            left: parent.left\n            right: parent.right\n            bottom: btn.top\n        }\n        // Low enough we can resize the window to destroy buttons.\n        cacheBuffer: 1\n        model: root.myObjects.length\n        delegate: Button {\n            id: self\n\n            readonly property string name: \"Button #\" + index\n\n            text: \"Button \" + index\n            onClicked: {\n                root.myObjects[index].somethingHappened()\n            }\n            Component.onCompleted: {\n                root.myObjects[index].somethingHappened.connect(() =\u003e {\n                    // When the button is destroyed, this will cause the following\n                    // error: TypeError: Type error\n                    console.log(self.name)\n                })\n            }\n            Component.onDestruction: {\n                console.log(\"Destroyed #\", index)\n            }\n        }\n    }\n\n    Button {\n        id: btn\n        anchors {\n            bottom: parent.bottom\n            horizontalCenter: parent.horizontalCenter\n        }\n        text: \"Emit Last Signal\"\n        onClicked: {\n            root.myObjects[root.myObjects.length - 1].somethingHappened()\n        }\n    }\n}\n```\n\nIn this example, once one of the buttons is destroyed we still have the object\ninstance. And then object instance still contains the connection we made in\n`Component.onCompleted`. So, when we click on `btn`, we get an error:\n`TypeError: Type error`. But once we expand the window so that the button is\ncreated again, we don't get that error. That is, we don't get that error for the\nnewly created button. But the previous connection still exists and still causes\nerror. But now that a new one is created, we end up with two connections on the\nsame object.\n\nThis is obviously not ideal and should be avoided. But how do you do it?\n\nThe simplest and most elegant solution (That I have found) is to simply use a\n`Connections` object and handle the signal there. So, If we change the code to\nthis:\n\n```qml\ndelegate: Button {\n    id: self\n\n    readonly property string name: \"Button #\" + index\n\n    text: \"Button \" + index\n    onClicked: {\n        root.myObjects[index].somethingHappened()\n    }\n\n    Connections {\n        target: root.myObjects[index]\n        onSomethingHappened: {\n            console.log(self.name)\n        }\n    }\n}\n```\n\nNow, whenever the delegate is destroyed so is the connection. This method can\nbe used even for multiple objects. You can simply put the `Connections` in a\n`Component` and use `createObject` to instantiate it for a specific object.\n\n```qml\nItem {\n    id: root\n    onObjectAdded: {\n        cmp.createObject(root, {\"target\": newObject})\n    }\n\n    Component {\n        id: cmp\n\n        Connections {\n            target: root.myObjects[index]\n            onSomethingHappened: {\n                console.log(self.name)\n            }\n        }\n    }\n}\n```\n\n## SH-2: When to use Functions and Signals\n\nWhen coming from imperative programming, it might be very tempting to use signals\nvery similar to functions. Resist this temptation. Especially when communicating\nbetween the C++ layer of your application, misusing signals can be very confusing\ndown the line.\n\nLet's first clearly define what a signal should be doing. Here's how\n[Qt](https://doc.qt.io/qt-5/signalsandslots.html#signals) defines it.\n\n\u003e Signals are emitted by an object when its internal state has changed in some\n\u003e way that might be interesting to the object's client or owner. \n\nThis means that whatever happens in the signal handler is a reaction to an\ninternal state change of an object. The signal handler should not be changing\nsomething else in the same object.\n\nSee the following example. We have a `ColorPicker` component that we want to use\nto show the user a message when the color is picked. As far as component design\ngoes, the fact that the customer sees a message is not `ColorPicker`'s job.\nIts job is to present a dialog and change the color it represents.\n\n```qml\n// ColorPicker.qml\nRectangle {\n    id: root\n\n    signal colorPicked()\n\n    ColorDialog {\n        onColorChanged: {\n            root.color = color\n            root.colorPicked()\n        }\n    }\n}\n\n// main.qml\nWindow {\n    ColorPicker {\n        onColorPicked: {\n            label.text = \"Color Changed\"\n        }\n    }\n\n    Label {\n        id: label\n    }\n}\n```\n\nThe above example is pretty straightforward, the signal handler only reacts to\na change and does something with that information after which the `ColorPicker`\nobject is not affected.\n\n```qml\n// ColorPicker.qml\nRectangle {\n    id: root\n\n    signal colorPicked(color pickedColor)\n\n    ColorDialog {\n        onColorChanged: {\n            root.colorPicked(color)\n        }\n    }\n}\n\n// main.qml\nWindow {\n    ColorPicker {\n        onColorPicked: {\n            color = pickedColor\n            label.text = \"Color Changed\"\n        }\n    }\n\n    Label {\n        id: label\n    }\n}\n```\n\nIn this example, the signal handler not only reacts to an internal state but it\nalso changes it. This is a very simple example, and it'll be easy to spot an\nerror. However complex your application is, you will always benefit from\nmaking the distinction clear. Otherwise what you think to be a function at first\nglance might end up being a signal and it loses its semantics of an internal\nstate change.\n\nHere's a general principle to follow:\n\n1. When communicating up, use signals.\n2. When communicating down, use functions.\n\n### Communicating with C++ Using Signals\n\nWhen you have a model that you use in the QML side, it's very possible that you\nare going to run into cases where something that happens in the QML side needs\nto trigger an action in the C++ side.\n\nIn these cases, prefer not to invoke any C++ signals from QML side. Instead,\nuse a function call or better a property assignment. The C++ object then should\nmake the decision whether to fire a signal or not.\n\nIf you are using a C++ type instantiated in QML, the same rules apply. You should\nnot be emitting signals from QML side.\n\n# JavaScript\n\nIt is the prevalent advice that you should avoid using JavaScript as much as possible\nin your QML code and have the C++ side handle all the logic. This is a sound advice\nand should be followed, but there are cases where you can't avoid having JavaScript\ncode for your UI. In those cases, follow these guidelines to ensure a good use of\nJavaScript in QML.\n\n## JS-1: Use Arrow Functions\n\nArrow functions were introduced in ES6. Its syntax is pretty close to C++ lambdas\nand they have a pretty neat feature that makes them most comfortable to use\nwhen you are using the `connect()` function to create a binding. If there's no\nblock within the arrow function, it has an implicit return statement.\n\nLet's compare the arrow function version with the old way.\n\n```qml\nItem {\n    property int value: -1\n\n    Component.onCompelted: {\n        // Arrow function\n        root.value = Qt.binding(() =\u003e root.someOtherValue)\n        // The old way.\n        root.value = Qt.binding(function() { return root.someOtherValue })\n    }\n}\n```\n\nThe arrow function version is easier on the eyes and cleaner to write.\nFor more information about arrow functions, head over to the [MDN Blog](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n\n## JS-2: Use the Modern Way of Declaring Variables\n\nWith ES6, there are 3 ways of delcaring a variable: `var`, `let`, and `const`.\n\nYou should leverage `let` and `const` in your codebase and avoid using `var`.\n`let` and `const` enables a scope based naming wheras `var` only knows about one\nscope.\n\n```qml\nItem {\n    onClicked: {\n        const value = 32;\n        let valueTwo = 42;\n        {\n            // Valid assignment since we are in a different scope.\n            const value = 32;\n            let valueTwo = 42;\n        }\n    }\n}\n```\n\nMuch like in C++, prefer using `const` If you don't want the variable to be assigned.\nBut keep in mind that `const` variables in JavaScript are not immutable. It just\nmeans they can't be reassigned, but their contents can be changed.\n\n```javascript\nconst value = 32;\nvalue = 42; // ERROR!\n\nconst obj = {value: 32};\nobj.value = 42; // Valid.\n```\n\nSee the MDN posts on [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const)\nand [let](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)\n\n# States and Transitions\n\nStates and transitions are a powerful way to create dynamic UIs. Here are some things to keep in\nmind when you are using them in your projects.\n\n## ST-1: Don't Define Top Level States\n\nDefining states at the top-level of a reusable component can cause breakages if the user of your\ncomponents also define their own states for their specific use case. \n\n```qml\n// MyButton.qml\nRectangle {\n    id: root\n\n    property alias text: lb.text\n    property alias hovered: ma.containsMouse\n\n    color: \"red\"\n    states: [\n        State {\n            when: ma.containsMouse\n\n            PropertyChanges {\n                target: root\n                color: \"yellow\"\n            }\n        }\n    ]\n\n    MouseArea {\n        id: ma\n        anchors.fill: parent\n        hoverEnabled: true\n    }\n\n    Label {\n        id: lb\n        anchors.centerIn: parent\n    }\n}\n\n// MyItem.qml\nItem {\n    MyButton {\n        id: btn\n        text: \"Not Hovering\"\n        // The states of the original component are not actually overwritten.\n        // The new state is added to the existing states.\n        states: [\n            State {\n                when: btn.hovered\n\n                PropertyChanges {\n                    target: btn\n                    text: \"Hovering\"\n                }\n            }\n        ]\n    }\n}\n```\nWhen you assign a new value to `states` or any other `QQmlListProperty`, the new value does not\noverwrite the existing one but adds to it. In the example above, the new state is added to the\nexisting list of states that we already have in `MyButton.qml`. Since we can only have one active\nstate in an item, our hover state will be messed up.\n\nIn order to avoid this problem, create your top-level state in a separate item or use a\n`StateGroup`.\n\n```qml\nRectangle {\n    id: root\n\n    property alias text: lb.text\n    property alias hovered: ma.containsMouse\n\n    color: \"red\"\n\n    MouseArea {\n        id: ma\n        anchors.fill: parent\n        hoverEnabled: true\n    }\n\n    Label {\n        id: lb\n        anchors.centerIn: parent\n    }\n\n    // A State group or\n    StateGroup {\n        states: [\n            State {\n                when: ma.containsMouse\n\n                PropertyChanges {\n                    target: root\n                    color: \"yellow\"\n                }\n            }\n        ]\n    }\n\n    // another item\n    Item {\n        states: [\n            State {\n                when: ma.containsMouse\n\n                PropertyChanges {\n                    target: root\n                    color: \"yellow\"\n                }\n            }\n        ]\n    }\n}\n```\n\nWith this change, the button will both change its color and text when the mouse is hovered above it.\n\n\n# Visual Items\n\nVisual items are at the core of QML, anything that you see in the window (or don't see because of\ntransparency) are visual items. Having a good understanding of the visual items, their relationship\nto each other, sizing, and positioning will help you create a more robust UI for your application.\n\n## VI-1: Distinguish Between Different Types of Sizes\n\nWhen thinking about geometry, we think in terms of `x`, `y`, `width` and `height`. This defines\nwhere our items shows up in the scene and how big it is. `x` and `y` are pretty straightforward but\nwe can't really say the same about the size information in QML.\n\nThere's 2 different types of size information that you get from various visual items:\n\n1. Explicit size: `width`, `height`\n2. Implicit size: `implicitWidth`, `implicitHeight`\n\nA good understanding of these different types is important to building a reusable library of\ncomponents.\n\n### Explicit Size\n\nIt's in the name. This is the size that you explicitly assign to an `Item`. By default, `Item`s do\nnot have an explicit size and its size will always be `Qt.size(0, 0)`.\n\n```qml\n// No explicit size is set. You won't see this in your window.\nRectangle {\n    color: \"red\"\n}\n\n// Explicit size is set. You'll see a yellow rectangle.\nRectangle {\n    width: 100\n    height: 100\n    color: \"yellow\"\n}\n```\n\n### Implicit Size\n\nImplicit size refers to the size that an `Item` occupies by default to display itself properly.\nThis size is not set automatically for any `Item`. You, as a component designer, need to make a\ndecision about this size and set it to your component.\n\nThe other thing to note is that [Qt internally\nknows](https://github.com/qt/qtdeclarative/blob/dev/src/quick/items/qquickitem.h#L418) if it has an\nexplicit size or not. So, when an explicit size is not set, it will use the implicit size.\n\n```qml\n// Even though there's no explicit size, it will have a size of Qt.size(100, 100)\nRectangle {\n    implicitWidth: 100\n    implicitHeight: 100\n    color: \"red\"\n}\n```\n\n-----\n\nWhenever you are building a reusable component, never set an explicit size within the component but\ninstead choose to provide a sensible implicit size. This way, the user of your components can freely\nmanipulate its size and when they need to return to a default size, they can always default to the\nimplicit size so they don't have to store a different default size for the component. This feature\nis also very useful if you want to implement a resize-to-fit feature.\n\nWhen a user is using your component, they may not bother to set a size for it.\n\n```qml\nCheckBox {\n    text: \"Check Me Out\"\n}\n```\n\nIn the example above, the check box would only be visible If there was a sensible implicit size for\nit. This implicit size needs to take into account its visual components (the box, the label etc.) so\nthat we can see the component properly. If this is not provided, it's difficult for the user of your\ncomponent to set a proper size for it.\n\n## VI-2: Be Careful with a Transparent `Rectangle`\n\n`Rectangle` should never be used with a transparent color except when you need to draw a border.\nThis is especially true if you are using a `Rectangle` as part of a delegate that's supposed to be\ncreated in a batch.\n\nDrawing transparent/translucent content takes more time because translucency requires blending.\nOpaque content is optimized better by the renderer.\n\nIn order to avoid paying the penalty, look for ways that you can defer the use of a transparent\n`Rectangle`. Maybe you can show it on hover, or during certain events and set it to invisible when\nit's no longer needed. Alternatively, you can put the `Rectangles` in an asynchronous `Loader`.\n\nHere's a sample QML code to demonstrate the difference between using an opaque rectangle and a\ntransparent one when it comes to the creation time of these components.\n\n```qml\nWindow {\n    visible: true\n\n    Row {\n        Button {\n            text: \"Rect\"\n            onClicked: {\n                console.time(\"Rect\")\n                rprect.model = rprect.model + 10000\n                console.timeEnd(\"Rect\")\n            }\n        }\n\n        Button {\n            text: \"Transparent\"\n            onClicked: {\n                console.time(\"Transparent\")\n                rptrans.model = rptrans.model + 10000\n                console.timeEnd(\"Transparent\")\n            }\n        }\n\n        Button {\n            text: \"Transparent Loader\"\n            onClicked: {\n                console.time(\"Transparent Loader\")\n                rploader.model = rploader.model + 10000\n                console.timeEnd(\"Transparent Loader\")\n            }\n        }\n\n        Button {\n            text: \"Translucent\"\n            onClicked: {\n                console.time(\"Translucent\")\n                rptransl.model = rptransl.model + 10000\n                console.timeEnd(\"Translucent\")\n            }\n        }\n\n        Button {\n            text: \"Reset\"\n            onClicked: {\n                rprect.model = 0\n                rptrans.model = 0\n                rptransl.model = 0\n                rploader.model = 0\n            }\n        }\n    }\n\n    Repeater {\n        id: rptrans\n        model: 0\n        delegate: Rectangle {\n            width: 10\n            height: 10\n            color: \"transparent\"\n        }\n    }\n\n    Repeater {\n        id: rptransl\n        model: 0\n        delegate: Rectangle {\n            width: 10\n            height: 10\n            opacity: 0.5\n            color: \"red\"\n        }\n    }\n\n    Repeater {\n        id: rprect\n        model: 0\n        delegate: Rectangle {\n            width: 10\n            height: 10\n            color: \"red\"\n        }\n    }\n\n    Repeater {\n        id: rploader\n        model: 0\n        // This will speed things up. You can defer the creation of the rectangle to when it makes\n        // sense and since it's asynchronous it won't block the UI thread.\n        delegate: Loader {\n            asynchronous: true\n            sourceComponent: Rectangle {\n                width: 10\n                height: 10\n                opacity: 0.5\n                color: \"transparent\"\n            }\n        }\n    }\n}\n```\n\nWhen you run this example for the first time and create solid rectangles, you'll notice that the\ncreation is pretty fast. If you close it and run it again, but this time create transparent or\ntranslucent ones you'll see that the time reported does not actually differ that much from the\nsolid rectangle.\n\nThe real problem starts presenting itself when you are creating new transparent items when there's\nalready rectangles on the scene. Try creating first the solid ones and then the transparent ones.\nYou'll see that the time difference is very noticeable.\n\nPlease note that this will not matter that much when you are drawing a few rectangles here and\nthere. The problem will present itself when you are using translucency in the context of a delegate\nbecause there can potentially be creating thousands of these rectangles.\n\nSee also: [Translucent vs Opaque](https://doc.qt.io/qt-5/qtquick-performance.html#translucent-vs-opaque)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FFurkanzmc%2FQML-Coding-Guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FFurkanzmc%2FQML-Coding-Guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FFurkanzmc%2FQML-Coding-Guide/lists"}