<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[QML Guide]]></title><description><![CDATA[A QtQuick guide made for beginners and experts alike.]]></description><link>https://qml.guide/</link><image><url>https://qml.guide/favicon.png</url><title>QML Guide</title><link>https://qml.guide/</link></image><generator>Ghost 1.25</generator><lastBuildDate>Tue, 05 Jul 2022 17:44:26 GMT</lastBuildDate><atom:link href="https://qml.guide/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Generating Code with QFace - Part 1]]></title><description><![CDATA[QFace provides a set of IDL parsers which can help you convert easy-to-read interface definitions into compiling code!]]></description><link>https://qml.guide/generating-code-with-qface/</link><guid isPermaLink="false">5c749104a3e4a206320acde4</guid><category><![CDATA[qface]]></category><category><![CDATA[qt]]></category><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Thu, 28 Feb 2019 02:00:28 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1474183725112-79b6800d89a0?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1474183725112-79b6800d89a0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Generating Code with QFace - Part 1"><p><a href="https://qface.readthedocs.io/en/latest/">QFace</a> provides a set of IDL parsers which can help you convert easy-to-read interface definitions into compiling code!</p>
<p>It was written by a Qt/QML developer so it provides many useful features that are Qt-compatible. It was also recently ingested into the <a href="https://doc-snapshots.qt.io/qtivi/idl-syntax.html">Qt Infotainment package</a></p>
<h1 id="idlinterfacedescriptionlanguage">IDL - Interface Description Language</h1>
<p>An <a href="https://en.wikipedia.org/wiki/Interface_description_language">IDL</a> helps you describe code in a language independent way.</p>
<p>We can refer to the &quot;meta-language&quot; that QFace provides as <em>QFace</em></p>
<h2 id="letsdescribe">Let's Describe!</h2>
<p>Let's think about <em>describing</em> a Human Resources service that manages Employees.</p>
<p>We can call this service – the <code>EmployeeService</code>.</p>
<p>Let's define an object, or struct, called <code>Employee</code> that encapsulates one individual that works for this company. This struct can define the employee's <em>name</em>, <em>age</em>, and <em>role</em>. An employee's <code>Role</code> can be a list of positions within the company, i.e. Engineers, Managers, or Executives.</p>
<p>This <code>EmployeeService</code> might have a list of employees, or <code>employeeList</code>, which can be a list of type <code>Employee</code>.</p>
<p>This <code>EmployeeService</code> may also have two operations, one to <em>hire</em> and one to <em>fire</em> an employee.  Let's call these methods <em>hireEmployee(..)</em> and <em>fireEmployee(..)</em>; respectively.  Both methods take a parameter of type <code>Employee</code>.</p>
<p>We can also create a signal that can be emitted whenever a new employee is hired, <code>employeeHired(..)</code>. We can pass more context into this signal, e.g. the <code>Employee</code> that was hired.</p>
<p>Let's write this scenario as a <em>QFace</em> file:</p>
<pre><code class="language-qml">module qml.guide.example 1.0

interface EmployeeService {
    int employeeCount
    list&lt;Employee&gt; employeeList
    
    void hireEmployee(Employee employee)
    void fireEmployee(Employee employee)
    
    signal employeeHired(Employee employee)
}

struct Employee {
    string firstName
    string lastName
    int age
    Role role
}

enum Role {
    Unknown,
    SoftwareEngineer,
    HardwareEngineer,
    QualityEngineer,
    ProjectManager,
    Manager,
    Executive
}

</code></pre>
<p>An important thing to remember at this stage is that the file above <em>does</em> follow <em>QFace</em> language rules, so every keyword (module, interface, struct, enum) is provided by <em>QFace</em>.  The collection of the possible keywords that <em>QFace</em> provides will be referred to as the <strong>grammar</strong> of <em>QFace</em>.</p>
<p>Please read about the <strong>grammar</strong> that <em>QFace</em> supports <a href="https://qface.readthedocs.io/en/latest/grammar.html">here</a>.</p>
<h1 id="gettingstartedwiththeqfacegenerators">Getting started with the QFace generators</h1>
<p><em>QFace</em> generators are written in <code>python3</code>.</p>
<p>Start by using pip (python package manager) to install qface and its dependencies:</p>
<pre><code class="language-bash">python3 -m pip install qface
</code></pre>
<p>Once qface is done installing, check the version:</p>
<pre><code class="language-bash">$ python3 -m pip freeze | grep qface
qface==2.0.0
</code></pre>
<p><em>I have noticed some API changes between 1.X and 2.0, so please keep that in mind if the version of qface you are using is newer than this tutorial</em></p>
<h2 id="letscode">Let's code!</h2>
<p>Save the above <code>EmployeeService</code> and friends example to a file called <code>qml.guide.example.qface</code>. Notice how we try to keep the file name the same as the module name. This simplifies searching for right module when you have hundreds of <em>QFace</em> documents.</p>
<p><strong>qml.guide.example.qface</strong> should look like this:</p>
<pre><code class="language-qml">module qml.guide.example 1.0

interface EmployeeService {
    int employeeCount
    list&lt;Employee&gt; employeeList
    
    void hireEmployee(Employee employee)
    void fireEmployee(Employee employee)
    
    signal employeeHired(Employee employee)
}

struct Employee {
    string firstName
    string lastName
    int age
    Role role
}

enum Role {
    Unknown,
    SoftwareEngineer,
    HardwareEngineer,
    QualityEngineer,
    ProjectManager,
    Manager,
    Executive
}
</code></pre>
<h3 id="bigpicture">Big Picture</h3>
<p><img src="https://qml.guide/content/images/2019/02/qface_concept.jpg" alt="Generating Code with QFace - Part 1"></p>
<p>This quasi-architecture-flow diagram is straight from the <a href="https://qface.readthedocs.io/en/latest/usage.html">QFace manual</a>. As you can see, we need to take our <em>QFace Document (Interface Definition)</em> which describes an <code>EmployeeService</code>, and feed that into <em>Your Generator</em> which uses the <em>QFace (Generator Library)</em> to finally produce <em>Your Code</em>.</p>
<h3 id="yourgenerator">Your Generator</h3>
<p>Let's continue our escapade by writing the <em>Your Generator</em> part of the diagram above. We need to write a python3 script that uses the qface package we just downloaded from pip.</p>
<p>Open a new file and name it <code>generator.py</code>:</p>
<pre><code class="language-python">#!/usr/bin/env python3

from qface.generator import FileSystem, Generator

print(&quot;My QFace Generator goes here!&quot;)
</code></pre>
<p>Run it and make sure you have no errors. This confirms if pip installed the qface package correctly:</p>
<pre><code class="language-bash">python3 generator.py
</code></pre>
<p>You can also set the script to executable so you can forever omit the <code>python3</code> prefix to your command (offtopic: works because of the <a href="https://stackoverflow.com/questions/7670303/purpose-of-usr-bin-python3/7670338">shebang</a>):</p>
<pre><code class="language-bash">chmod u+x generator.py
./generator.py
</code></pre>
<p>Now that we know qface is installed correctly, let's continue writing our generator. The contents of this generator are inspired by the <a href="https://qface.readthedocs.io/en/latest/usage.html">QFace manual</a>:</p>
<pre><code class="language-python">#!/usr/bin/env python3

from qface.generator import FileSystem, Generator

def generate(input, output):
    # parse the interface files
    system = FileSystem.parse(input)
    # ...

# call the generation function
generate('qml.guide.example.qface', 'generated_code_output')
</code></pre>
<p>What's going on here?</p>
<p><img src="https://qml.guide/content/images/2019/02/qface-01.jpg" alt="Generating Code with QFace - Part 1"></p>
<p>Let's start from the last line:</p>
<pre><code class="language-python">generate('qml.guide.example.qface', 'generated_code_output')
</code></pre>
<p>We are sending in our QFace document from above, and a folder name of where our final code output will be placed.</p>
<p>Inside the <code>generate</code> method, we are using <code>qface.FileSystem</code> to parse the QFace document and produce a variable called <code>system</code> which is of type <a href="https://qface.readthedocs.io/en/latest/api.html#qface.idl.domain.System">System</a>. This variable (shown in the diagram as <code>ctx</code>) is a python object that holds the <em>grammar</em> of our QFace document.</p>
<p>By reading the <a href="https://qface.readthedocs.io/en/latest/api.html#qface.idl.domain.System">API documentation</a> of System, we can see it has a property called <code>modules</code>.</p>
<p>We can use python's <code>pprint</code> package to print out the <code>modules</code> property to see what's inside:</p>
<pre><code class="language-python">#!/usr/bin/env python3

from qface.generator import FileSystem, Generator
from pprint import pprint

def generate(input, output):
    # parse the interface files
    system = FileSystem.parse(input)
    pprint(system.modules)

# call the generation function
generate('qml.guide.example.qface', 'generated_code_output')
</code></pre>
<p>You should see something like this:</p>
<pre><code class="language-bash">qface uses language profile: EProfile.FULL
odict_values([&lt;&lt;class 'qface.idl.domain.Module'&gt; name=qml.guide.example&gt;])
</code></pre>
<p>Notice our module name is displayed, <em>qml.guide.examples</em>.</p>
<p>It is now easy to see the type hierarchy present inside the <code>System</code> type:</p>
<ul>
<li>System</li>
<li>-&gt; Module(s)</li>
<li>-&gt;-&gt; Interface(s)</li>
<li>-&gt;-&gt; Struct(s)</li>
<li>-&gt;-&gt; Enum(s)</li>
</ul>
<p>All of these types are stored as lists of dictionaries (maps) so we can easily iterate through them and print out the grammar of our QFace document:</p>
<pre><code class="language-python">#!/usr/bin/env python3

from qface.generator import FileSystem, Generator
from pprint import pprint

def generate(input, output):
    # parse the interface files
    system = FileSystem.parse(input)
    
    for module in system.modules:
        print(&quot;module.name = &quot; + module.name)

        for interface in module.interfaces:
            print(&quot;interface.name = &quot; + interface.name)

        for struct in module.structs:
            print(&quot;struct.name = &quot; + struct.name)

        for enum in module.enums:
            print(&quot;enum.name = &quot; + enum.name)

# call the generation function
generate('qml.guide.example.qface', 'generated_code_output')
</code></pre>
<p>Run this and you will see familiar names:</p>
<pre><code class="language-bash">$ ./generator.py

qface uses language profile: EProfile.FULL
module.name = qml.guide.example
interface.name = EmployeeService
struct.name = Employee
enum.name = Role
</code></pre>
<p>Success! Our generator has reached it's first milestone. Sit back and reflect on what just happened.</p>
<p>We took a seemingly unknown IDL and turned it into grammatically significant types: modules (as a collection of interfaces, structs, and enums).</p>
<p>Just imagine the potential of evolving a simple generator like this to something grander!</p>
<p>Stay tuned for the next post in this series!</p>
</div>]]></content:encoded></item><item><title><![CDATA[Enums in Qt QML]]></title><description><![CDATA[<div class="kg-card-markdown"><p>An enumerated type, or enum, is a data type consisting of a set of named values called elements, members, enumeral, or enumerators of the type.</p>
<p>Enums are incredibly useful when portraying status, options, or modes that are exclusive within a grouping. A common enum that is seen in QML is</p></div>]]></description><link>https://qml.guide/enums-in-qt-qml/</link><guid isPermaLink="false">5a603e24e6209c23cfc4cbc9</guid><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Thu, 18 Jan 2018 07:42:45 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1507142668116-61c4c50fe057?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ%3D%3D&amp;s=39a0182f29e065d262f8571678a8b82a" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1507142668116-61c4c50fe057?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ%3D%3D&s=39a0182f29e065d262f8571678a8b82a" alt="Enums in Qt QML"><p>An enumerated type, or enum, is a data type consisting of a set of named values called elements, members, enumeral, or enumerators of the type.</p>
<p>Enums are incredibly useful when portraying status, options, or modes that are exclusive within a grouping. A common enum that is seen in QML is the <em>Status</em> enum which is present in the <a href="http://doc.qt.io/qt-5/qml-qtquick-image.html#status-prop">Image</a>, <a href="http://doc.qt.io/qt-5/qml-qtquick-loader.html#status-prop">Loader</a>, and may other elements. A common groupong of <em>Status</em> has the following values:</p>
<pre><code>Null
Ready
Loading
Error
</code></pre>
<p>These enums can be used to track the status of an object. In the case of the <em>Loader</em> element, we can check the status of the file or component being loaded:</p>
<pre><code>Loader {
    source: &quot;SampleSource.qml&quot;
    onStatusChanged: {
        if (status == Loader.Error) {
            console.warn(&quot;Error loading&quot;, source, sourceComponent.errorString());
        }
    }
}
</code></pre>
<h2 id="creatingyourownenums">Creating your own enums</h2>
<p>Enums are easy to create in Qt. Simply use the C++ <code>enum</code> identifier and use the <code>Q_ENUM</code> macro to generate Qt-specific helper code.</p>
<p>I have found the best practice to exposing enums is to create a class for each enum you need. This way, each enum is not specifically associated to the class that is using it.</p>
<p>Let's create a new enum for <em>Status</em> similar to what we saw above. Create a new C++ class called <em>StatusClass</em>.  We'll explain why we add the <em>Class</em> word at the end of the class name later.</p>
<p><em>statusclass.h</em></p>
<pre><code>#pragma once

#include &lt;QObject&gt;

class StatusClass : public QObject
{
    Q_OBJECT
public:
    explicit StatusClass(QObject *parent = nullptr);

};
</code></pre>
<p><em>statusclass.cpp</em></p>
<pre><code>#include &quot;statusclass.h&quot;

StatusClass::StatusClass()
{

}
</code></pre>
<p>By default, this class inherits <code>QObject</code> and has the <code>Q_OBJECT</code> macro to generate relevant MOC data for a <code>QObject</code>.</p>
<p>Since this is an enum class, we don't need to expansive feature set of the <code>Q_OBJECT</code> macro. Let's use <code>Q_GADGET</code> instead. Note that using <code>Q_GADGET</code> doesn't allow us to emit signals; but since this is an enum class we don't expect to emit any signals.</p>
<p>A <code>Q_GADGET</code> version of the class looks like this:</p>
<p><em>statusclass.h</em></p>
<pre><code>#pragma once

#include &lt;QObject&gt;

class StatusClass
{
    Q_GADGET
public:
    explicit StatusClass();
};
</code></pre>
<p>Now, let's add our C++ <code>enum</code>:</p>
<p><em>statusclass.h</em></p>
<pre><code>#pragma once

#include &lt;QObject&gt;

class StatusClass
{
    Q_GADGET
public:
    explicit StatusClass();

    enum Value {
        Null,
        Ready,
        Loading,
        Error
    };
};
</code></pre>
<p>In order to generate the Qt-specific helpers for this enum, we need to use the <code>Q_ENUM</code> macro. Be careful not to confuse this with the older, deprecated <code>Q_ENUMS</code> macro. You can read about the differences on <a href="https://woboq.com/blog/q_enum.html">woboq</a>.</p>
<p><em>statusclass.h</em></p>
<pre><code>#pragma once

#include &lt;QObject&gt;

class StatusClass
{
    Q_GADGET
public:
    explicit StatusClass();

    enum Value {
        Null,
        Ready,
        Loading,
        Error
    };
    Q_ENUM(Value)
};
</code></pre>
<p>Great! Now, we're ready to use the <em>Status</em> enum in QML.</p>
<p>Let's register the <em>StatusClass</em> type in <em>main.cpp</em>. We use <code>qmlRegisterUncreatableType</code> as we do not want instances of the <em>StatusClass</em> to be created in QML as it is simply a wrapper to a C++ <code>enum</code>.</p>
<p><em>main.cpp</em></p>
<pre><code>qmlRegisterUncreatableType&lt;StatusClass&gt;(&quot;qml.guide&quot;, 1, 0, &quot;StatusClass&quot;, &quot;Not creatable as it is an enum type&quot;);
</code></pre>
<p>The last argument is a simple <em>reason</em> as to why the type is uncreatable.  A warning will be logged if a user tries to instantiate this class:</p>
<blockquote>
<p>qrc:/main.qml:16 Not creatable as it is an enum type</p>
</blockquote>
<p>Now you can reference these enum values in QML:</p>
<p><em>main.qml</em></p>
<pre><code>import QtQuick 2.9
import QtQuick.Window 2.2

import qml.guide 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr(&quot;Hello World&quot;)

    Component.onCompleted: {
        console.log(StatusClass.Ready);
    }
}
</code></pre>
<p>You will see the integer <em>1</em> printed in your log.</p>
<p>Why did we use <em>Class</em> at the end of the enum name? Let's clarify.<br>
We created a class called <em>StatusClass</em> that wraps an enum called <em>Value</em>.</p>
<p>Our goal was to create an enum that can be exposed to both Qt and QML. We protected the instantiation of <em>StatusClass</em> from QML by using <code>qmlRegisterUncreatableType</code>. To protect the instantiation of an element in C++, we need to make the constructor private.</p>
<p><em>statusclass.h</em></p>
<pre><code>#pragma once

#include &lt;QObject&gt;

class StatusClass
{
    Q_GADGET
public:
    enum Value {
        Null,
        Ready,
        Loading,
        Error
    };
    Q_ENUM(Value)

private:
    explicit StatusClass();
};
</code></pre>
<p>To use this class in C++, we would have to reference the class name and the Value enum name, e.g. <code>void setStatus(StatusClass::Value status)</code></p>
<p>This requires us to reference <code>Value</code> to get the actual enum type. We can avoid this by using <code>typedef</code> to expose <code>StatusClass::Value</code> as <code>Status</code>:</p>
<pre><code>typedef StatusClass::Value Status;
</code></pre>
<p>Now, our method signature can be <code>void setStatus(Status status)</code>.<br>
Much cleaner, isn't it?</p>
<p>For this <code>typedef</code> to work properly with QML, we must register both <em>StatusClass</em> and <em>Status</em>. This ensures the &quot;Status&quot; type is registered to the metatype system which allows us to assign a type of <em>StatusClass</em> to a type of <em>Status</em> via QML.</p>
<pre><code>qRegisterMetaType&lt;Status&gt;(&quot;Status&quot;);
qmlRegisterUncreatableType&lt;StatusClass&gt;(&quot;qml.guide&quot;, 1, 0, &quot;Status&quot;, &quot;Not creatable as it is an enum type&quot;);
</code></pre>
<p>Voila! You have exposed an enum from Qt to QML, and also protected the enum for proper use in C++.</p>
<p>See the examples above in the <a href="https://github.com/ndesai/qml.guide/tree/master/examples/QtQmlEnums">qml.guide GitHub repository</a>.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Live Reloading or Hot Reloading with QML]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Live reloading or hot reloading is all the <em>rage</em> these days. One of the best examples of hot reloading is <a href="https://facebook.github.io/react-native/">React Native</a>.</p>
<p>Check out a video of it here:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/2uQzVi-KFuc" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe>
<p>Live reloading is extremely useful to quickly develop and iterate over the user interface aspect of an application.</p>
<p>The majority of</p></div>]]></description><link>https://qml.guide/live-reloading-hot-reloading-qml/</link><guid isPermaLink="false">5a4c3df3e6209c23cfc4cbc3</guid><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Fri, 05 Jan 2018 07:27:50 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1501526029524-a8ea952b15be?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=53786c01ffd40c6f4c10a5a413f5c5b5" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1501526029524-a8ea952b15be?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=53786c01ffd40c6f4c10a5a413f5c5b5" alt="Live Reloading or Hot Reloading with QML"><p>Live reloading or hot reloading is all the <em>rage</em> these days. One of the best examples of hot reloading is <a href="https://facebook.github.io/react-native/">React Native</a>.</p>
<p>Check out a video of it here:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/2uQzVi-KFuc" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe>
<p>Live reloading is extremely useful to quickly develop and iterate over the user interface aspect of an application.</p>
<p>The majority of Qt / QML developers I have met (myself included, until recently) underestimate the capability of hot reloading QML applications. We are so accustomed to <em>building</em> and <em>running</em> an application, even for the slighest of changes (width, height, color, and other static data).</p>
<p>There are many solutions to the <em>hot reloading</em> problem in Qt + QML. They all have their own advantages and disadvantages. I prefer to use a combination of all the below to accomplish a variety of UI tasks for a project:</p>
<h3 id="terrarium">Terrarium</h3>
<p>Terrarium is a live reloader documented <a href="https://github.com/penk/terrarium-app">here</a>.</p>
<p><em><strong>Advantages:</strong></em></p>
<ul>
<li>Quick prototyping with a built-in editor.</li>
<li>Great for QML interviews.</li>
</ul>
<p><em><strong>Disadvantages:</strong></em></p>
<ul>
<li>Not useful for projects as it can only read from the <code>TextEdit</code> element that is built-in to the application.</li>
</ul>
<h3 id="qmllivereload">Qml LiveReload</h3>
<p>Qml LiveReload is available <a href="https://github.com/penk/qml-livereload">here</a>.</p>
<p>After building, the target is placed at <code>/usr/local/bin</code> (for some reason..)<br>
To use,</p>
<pre><code>/usr/local/bin/qmllive /path/to/file.qml
</code></pre>
<p><em><strong>Advantages:</strong></em></p>
<ul>
<li>Easy to use, simply build and execute a QML file with the binary specified above.</li>
<li>Hard to use with large projects, does not preserve states</li>
</ul>
<p><em><strong>Disadvantages:</strong></em></p>
<ul>
<li>Out of build target.. builds to <code>/usr/local/bin/qmllive</code></li>
<li>Reloads the entire application</li>
</ul>
<h3 id="qmllive">QmlLive</h3>
<p>I lightly covered QmlLive <a href="https://qml.guide/live-reloading-hot-reloading-qml/%5BQmlLive%5D(https://qml.guide/qtautomotivesuite-getting-started-with-qt-applicationmanager/#qmllive)">here</a>.</p>
<p><em><strong>Advantages:</strong></em></p>
<ul>
<li>Application preserves workspace, you can easily open and close the app and restore your workspace</li>
<li>Allows deployment of a runtime to an embedded device to see a UI reload live on a different device.</li>
</ul>
<p><em><strong>Disadvantages:</strong></em></p>
<ul>
<li>Reloads the entire application</li>
<li>UI states are not preserved upon reload</li>
</ul>
<h3 id="customloaderqqmlenginesolution">Custom Loader + QQmlEngine Solution</h3>
<p>This is my preferred solution. I believe it is the most flexible one as it provides reload capability to individual <em>pieces</em> of a project's user interface; unlike some of the aforementioned solutions which reload the <em>entire</em> user interface.</p>
<p>Before diving into the code that powers this method of live reloading, let's investigate <em>how</em> the <code>QmlEngine</code> works with respect to the <em>loading</em> of QML elements.</p>
<p>In QML, a <code>Component</code> is a <em>template</em> that defines an object.  A <code>Component</code> can be used to build objects that have a well-defined structure and interface.</p>
<pre><code>Component {
    id: _componentIconLabel
    
    Row {
        property var icon
        property var text
        Image {
            width: 50; height: 50
            source: parent.icon
        }
        Text {
            text: parent.text
        }
    }
}

Button {
    onClicked: {
        var iconLabelObject = _componentIconLabel.createObject(root);
        iconLabelObject.text = &quot;Hello World&quot;; 
        // NOTE: These properties can be set before the 
        // element is created by using the createObject 
        // method's second argument
    }
}
</code></pre>
<p>In the example above, we already created the <code>Component</code> by declaring it in QML. You can also create a <code>Component</code> <a href="http://doc.qt.io/qt-5/qqmlcomponent.html#details">by loading a file</a>.</p>
<p>Once a <code>Component</code> is created, it is cached in the <code>QmlEngine</code>.</p>
<p>How does this cache work? Let's dig a little deeper into the sources.</p>
<ol>
<li>
<p><code>Component</code> uses the <code>QmlEngine</code>'s <code>QmlTypeLoader</code> to get the type of what is being loaded into a <code>Component</code>. More information can be read in the Qt sources <a href="https://code.woboq.org/qt5/qtdeclarative/src/qml/qml/qqmlcomponent.cpp.html#660">here</a>.</p>
</li>
<li>
<p><code>QmlTypeLoader</code> provides a <code>getType</code> <a href="https://code.woboq.org/qt5/qtdeclarative/src/qml/qml/qqmltypeloader.cpp.html#_ZN14QQmlTypeLoader7getTypeERK4QUrlNS_4ModeE">method</a> that checks a cache (<code>QmlTypeCache</code>), if there is a hit it returns cached data, else, it loads in new data.</p>
</li>
</ol>
<p>To allow for hot or live reloading, it is crucial for us to ignore the cache and reload from disk. The criteria for checking cache is not particularly sophisticated as every type is <a href="https://code.woboq.org/qt5/qtdeclarative/src/qml/qml/qqmltypeloader.cpp.html#1651">registered by URL / type name</a>.</p>
<p>Since we do not want modify the criteria for how <code>Component</code> caching works in Qt sources, we can work around this cache by simply clearing it when a reload is required.</p>
<p><code>QmlEngine</code> provides two methods for manipulating the QML type component cache.</p>
<p><code>QQmlEngine::trimComponentCache()</code> - Trims component cache entries for components that are no longer used. This is a very difficult criteria to satisfy as components are generally used widely throughout a QML project.</p>
<p>See Qt sources <a href="https://code.woboq.org/qt5/qtdeclarative/src/qml/qml/qqmlengine.cpp.html#_ZN10QQmlEngine18trimComponentCacheEv">here</a></p>
<p><code>QQmlEngine::clearComponentCache()</code> - Clears the entire component cache. If an element is still used, it is at risk of causing warnings throughout the UI as when the same type is loaded again, it will be loaded into a new cache entry. This new cache entry and the old active element will no longer match.</p>
<p>This is a small inconvenience for the benefit of hot reloading. By clearing the entire component cache, we can simply reload a QML file to view updated changes.</p>
<p>See Qt sources <a href="https://code.woboq.org/qt5/qtdeclarative/src/qml/qml/qqmlengine.cpp.html#_ZN10QQmlEngine19clearComponentCacheEv">here</a>.</p>
<p>Let's get down to business.</p>
<p>There are a few ways you can implement this:</p>
<ul>
<li>Option A: Build a custom <code>Component</code> loader in Qt C++, reference <code>QmlEngine</code> directly in C++</li>
<li>Option B: Extend the QML <code>Loader</code> and expose a reference to the <code>QmlEngine</code> to QML</li>
</ul>
<p>I prefer <em>Option B</em>, so let's do it:</p>
<p>First, let's create an example project with a <code>Window</code>, a <code>Loader</code>, and a <code>Component</code>.</p>
<p><em>main.qml</em></p>
<pre><code>import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr(&quot;Hello World&quot;)

    Loader {
        id: _loader

        function reload() {
            source = &quot;&quot;;
            source = &quot;Circle.qml&quot;;
        }

        anchors.centerIn: parent
        source: &quot;Circle.qml&quot;
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            _loader.reload();
        }
    }
}
</code></pre>
<p>Add a <code>MouseArea</code> and a method in the loader called <em>reload</em>. We will use these to <em>prove</em> that the <code>QmlEngine</code> and its associates are caching types.</p>
<p>In this example, we are creating a <code>Loader</code> and load in file called <em>Circle.qml</em>:</p>
<p><em>Circle.qml</em></p>
<pre><code>import QtQuick 2.9

Rectangle {
    width: 300
    height: 300
    radius: width / 2

    color: &quot;blue&quot;
}
</code></pre>
<p>Run the UI and you will see this:</p>
<p><img src="https://qml.guide/content/images/2018/01/Screen-Shot-2018-01-04-at-8.49.21-PM.png" alt="Live Reloading or Hot Reloading with QML"></p>
<p>Keep the UI open. Now, modify <em>Circle.qml</em> to make the <code>Rectangle</code> color <em>red</em>:</p>
<p><em>Circle.qml</em></p>
<pre><code>import QtQuick 2.9

Rectangle {
    width: 300
    height: 300
    radius: width / 2

    color: &quot;red&quot;
}
</code></pre>
<p>Now that the <em>Circle</em> is <em>red</em>, click on the UI to reload the <code>Loader</code>.</p>
<p>Notice how the <em>Circle</em> remains <em>blue</em>? This <code>Loader</code> is being reloaded yet the <em>Circle</em> is still <em>blue</em>. This is proof that the <code>Component</code> created from <em>Circle.qml</em> is cached.  It's also apparent that the cache is <em>not</em> keyed by the contents of <em>Circle.qml</em>.</p>
<p>Let's keep working until we can figure out how to make the <em>Circle</em> change colors when we click the UI.</p>
<p>Above, we learned about the methods available in the <code>QmlEngine</code> to trim and clear the cache in the <code>QmlEngine</code>. Let's use some of these methods.</p>
<p>To use a method from the <code>QmlEngine</code> in QML land, we must expose it. Let's do it via <em>context properties</em>.</p>
<p>Here is our auto-generated (by project template) main.cpp:</p>
<p><em>original main.cpp</em></p>
<pre><code>#include &lt;QGuiApplication&gt;
#include &lt;QQmlApplicationEngine&gt;

int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral(&quot;qrc:/main.qml&quot;)));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}
</code></pre>
<p>Let's use <a href="http://doc.qt.io/qt-5/qtqml-cppintegration-contextproperties.html">context properties</a> to expose the <em>engine</em> to QML. Context properties are simply <em>magic global variables</em> that are available in all of QML without the need of importing anything.</p>
<p><em>modified main.qml</em></p>
<pre><code>#include &lt;QGuiApplication&gt;
#include &lt;QQmlApplicationEngine&gt;

#include &lt;QQmlContext&gt;

int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    engine.rootContext()-&gt;setContextProperty(&quot;$QmlEngine&quot;, &amp;engine);

    engine.load(QUrl(qgetenv(&quot;MAIN_QML&quot;)));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}
</code></pre>
<p>In this code, we are exposing a global variable called <code>$QmlEngine</code> as a context property of the <code>QmlEngine</code>'s root context. This allows the <code>$QmlEngine</code> variable to be used from <em>any</em> QML file loaded inside this this particular engine.</p>
<p>Also note how we replaced the <code>qrc://</code> URL with a <code>qgetenv</code>. We <em>do not</em> want Qt to compile our resources into a binary QRC file as this would require us to <em>rebuild</em> the project when changing a QML file.</p>
<p>I have removed the use of QRC in almost every large-scale project I've worked on. Compiling QML files into resource files is very detrimental to developer productivity.  Compiling QML files into resources can easily be enabled for <em>release</em> or <em>production</em> builds and avoided in <em>developer</em> builds.</p>
<p>We should run our application with the environment variable specified, e.g:</p>
<pre><code>MAIN_QML=../HotReloading/main.qml ./bin/HotReloading
</code></pre>
<p>Now that we have a reference to the <code>QmlEngine</code>, let's invoke the <code>QQmlEngine::clearComponentCache</code> when we are reloading the <code>Loader</code> element in <em>main.qml</em>:</p>
<p><em>main.qml</em></p>
<pre><code>import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr(&quot;Hello World&quot;)

    Loader {
        id: _loader

        function reload() {
            source = &quot;&quot;;
            $QmlEngine.clearComponentCache();
            source = &quot;Circle.qml&quot;;
        }

        anchors.centerIn: parent
        source: &quot;Circle.qml&quot;
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            _loader.reload();
        }
    }
}
</code></pre>
<p>Let's try this again. Build your code and run the UI again.<br>
Modify the color of the <code>Rectangle</code> in <em>Circle.qml</em>.</p>
<p>Click the circle. Did it change colors?</p>
<p>Nope! Now we got a warning:</p>
<pre><code>qrc:/main.qml:15: TypeError: Property 'clearComponentCache' of object QQmlApplicationEngine(0x7fff58907a98) is not a function
</code></pre>
<p>What gives? It seems that <code>QQmlEngine::clearComponentCache</code> is <em>not</em> allowed to be invoked by QML.  It <em>is</em> a public method, but it does not have the <code>Q_INVOKABLE</code> flag.</p>
<p>Let's create a <em>utility</em> class that exposes an aliased function that calls <code>QQmlEngine::clearComponentCache</code>. These kinds of hoops are common when attempting to expose Qt functionality to QML.</p>
<p>We have two options here, we can either create a brand new class that extends <code>QObject</code> or we can create a brand new class that extends <code>QQmlApplicationEngine</code>. The latter is simpler as we don't need to pass in the <code>QQmlEngine</code> object.</p>
<p>Create a new file called <code>EnhancedQmlApplicationEngine</code>:</p>
<p><em>enhancedqmlapplicationengine.h</em></p>
<pre><code>#pragma once

#include &lt;QQmlApplicationEngine&gt;

class EnhancedQmlApplicationEngine : public QQmlApplicationEngine
{
    Q_OBJECT
public:
    explicit EnhancedQmlApplicationEngine(QObject *parent = nullptr);

    Q_INVOKABLE void clearCache();
};
</code></pre>
<p><em>enhancedqmlapplicationengine.cpp</em></p>
<pre><code>#include &quot;enhancedqmlapplicationengine.h&quot;

EnhancedQmlApplicationEngine::EnhancedQmlApplicationEngine(QObject *parent)
    : QQmlApplicationEngine(parent)
{

}

void EnhancedQmlApplicationEngine::clearCache()
{
    this-&gt;clearComponentCache();
}
</code></pre>
<p>Note how we had to name the method <em>clearCache</em> instead of <em>clearComponentCache</em> since the latter was already taken by the super class, <code>QQmlEngine</code> by proxy of <code>QQmlApplicationEngine</code>.</p>
<p>Use this new engine in <em>main.cpp</em>:</p>
<p><em>main.cpp</em></p>
<pre><code>#include &lt;QGuiApplication&gt;
#include &lt;QQmlContext&gt;

#include &quot;enhancedqmlapplicationengine.h&quot;

int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    EnhancedQmlApplicationEngine engine;

    engine.rootContext()-&gt;setContextProperty(&quot;$QmlEngine&quot;, &amp;engine);

    engine.load(QUrl(qgetenv(&quot;MAIN_QML&quot;)));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}
</code></pre>
<p>Update your <em>reload</em> method in <em>main.qml</em> to call our new <em>clearCache</em> method:</p>
<pre><code>import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr(&quot;Hello World&quot;)

    Loader {
        id: _loader

        function reload() {
            source = &quot;&quot;;
            $QmlEngine.clearCache();
            source = &quot;Circle.qml&quot;;
        }

        anchors.centerIn: parent
        source: &quot;Circle.qml&quot;
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            _loader.reload();
        }
    }
}
</code></pre>
<p>Voila! Build your code again.</p>
<p>Run the UI.</p>
<p><img src="https://qml.guide/content/images/2018/01/screencast.gif" alt="Live Reloading or Hot Reloading with QML"></p>
<p>Now, you can scatter these <code>Loader</code> elements with a custom <code>reload</code> method throughout your UI. Whenever you need to reload, you can. This allows for <em>rapid</em> UI development, especially when building out individual widgets or scenes.</p>
<p>This <em>Hot Reloading</em> solution can be extended:</p>
<ul>
<li>Use a <code>QFileSystemWatcher</code> class to track the loaded file for changes. When a change is signaled, reload the <code>Loader</code>.</li>
<li>Use a <code>Timer</code> to reload constantly while developing.</li>
</ul>
<p>The source code is available on the <a href="https://github.com/ndesai/qml.guide/tree/master/examples/HotReloading">qml.guide GitHub repository</a>.</p>
</div>]]></content:encoded></item><item><title><![CDATA[QtAutomotiveSuite Part 1 - An overview of the suite]]></title><description><![CDATA[<div class="kg-card-markdown"><h2 id="qtautomotivesuiteoverview">QtAutomotiveSuite Overview</h2>
<p><a href="https://www1.qt.io/qt-automotive-suite/">QtAutomotiveSuite</a> is a collection of Qt-based projects geared towards the Automotive industry.</p>
<p>Some projects in the suite include:</p>
<ul>
<li>
<p><a href="https://doc.qt.io/QtApplicationManager/">Qt ApplicationManager</a> - An application framework that can emulate the behavior of on OS at the application-layer of an automotive platform. It allows developers to build a SystemUI and several</p></li></ul></div>]]></description><link>https://qml.guide/qtautomotivesuite-getting-started-with-qt-applicationmanager/</link><guid isPermaLink="false">5a4523fde6209c23cfc4cbb1</guid><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Sun, 31 Dec 2017 21:42:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1508974239320-0a029497e820?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=0aa464ccf37ce95104dcb64c2320423f" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><h2 id="qtautomotivesuiteoverview">QtAutomotiveSuite Overview</h2>
<img src="https://images.unsplash.com/photo-1508974239320-0a029497e820?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=0aa464ccf37ce95104dcb64c2320423f" alt="QtAutomotiveSuite Part 1 - An overview of the suite"><p><a href="https://www1.qt.io/qt-automotive-suite/">QtAutomotiveSuite</a> is a collection of Qt-based projects geared towards the Automotive industry.</p>
<p>Some projects in the suite include:</p>
<ul>
<li>
<p><a href="https://doc.qt.io/QtApplicationManager/">Qt ApplicationManager</a> - An application framework that can emulate the behavior of on OS at the application-layer of an automotive platform. It allows developers to build a SystemUI and several Applications that may be launched in separate processes.</p>
</li>
<li>
<p><a href="https://doc-snapshots.qt.io/qtivi/idl-syntax.html">QFace</a> - An IDL format with a python-based generator tha simplifies the development of large scale interfaces, structs, and enums.<br>
<a id="qtappman"></a></p>
</li>
<li>
<p><a href="https://doc.qt.io/QtQmlLive/index.html">QML Live</a> - A hot reloading application that automatically refreshes QML files when they are changed. This tool greatly simplifies the development of UIs by automatically reloading an application view without requiring the developer to re-compile and re-run an application.</p>
</li>
</ul>
<h2 id="qtapplicationmanager">Qt ApplicationManager</h2>
<p>The Qt ApplicationManager provides one primary function: Provide the ability to run multi-process applications using the Wayland protocol implemented by QtWayland.</p>
<p>Common terminology:<br>
<em><strong>SystemUI</strong></em> - The main homescreen of an application. This UI is loaded in the main process alongside Qt ApplicationManager code and is responsible for forking new processes. This is analogous to the homescreen on your mobile phone. If the system ui dies, the entire project is killed including all applications.</p>
<p><em><strong>ApplicationUI</strong></em> - The available applications that are loaded by Qt ApplicationManager. These applications can be <em>pre-installed</em> or even <em>installed at runtime</em>. This is analogous to an application on your mobile phone. If an application on your mobile phone dies, you may be redirected to the homescreen or system ui.</p>
<h3 id="advantagesofmultiprocess">Advantages of multi-process</h3>
<ul>
<li>
<p><em><strong>Isolated processes per application</strong></em> - In the domain of automotive, this allows infotainment develoeprs the ability to launch a Navigation application, a Radio application, and a Settings application in separate linux processes. If the Navigation application <em>crashes</em>, the rest of the system is left unharmed. The Radio application and Settings application remain intact.</p>
</li>
<li>
<p><em><strong>Application resource usage</strong></em> - Since the Navigation application, Radio application, and Settings application are running in separate processes, the system is able to report back resource usage per application. QtApplicationManager provides <code>CpuConsumption</code> and <code>MemoryConsumption</code> for each process. With this, we can figure out, for example, that the Navigation application is using 300MB of RAM, the Radio application is using 100MB of RAM and the Settings application is using 120MB of RAM. In a traditional single-process setup, all <em>applications</em> would be in a single process and there is no way of knowing how much machine resource is being used by one piece of this group of applications.</p>
</li>
</ul>
<h3 id="disadvantagesofmultiprocess">Disadvantages of multi-process</h3>
<p>With advantages come disadvantages. And with multi-process being the leading advantage, we would have to write these disadvantages off as a <em>debt of innovation</em>.</p>
<ul>
<li><em><strong>Inter-application Communication</strong></em> - In <strong>single-process</strong>, if the Navigation application needed to talk to the Radio application, we could simply refer to the Navigation application by QML <code>id</code>, i.e.</li>
</ul>
<pre><code class="language-qml">import QtQuick 2.7

Window {
    SystemUi { id: _systemUi }
    NavigationApplication { id: _navigationApplication } 
    RadioApplication { id: _radioApplication } 
    SettingsApplication { id: _settingsApplication } 
}
</code></pre>
<p>We could simply refer to <code>_navigationApplication</code> by <code>id</code> and invoke methods, modify properties, send signals, etc:</p>
<pre><code>Button {
    onClicked: _navigationApplication.routeToHome();
}
</code></pre>
<p>In <strong>multi-process</strong>, these applications are represented in the <code>SystemUI</code> as <em>proxies</em> living in the same process; however, each application is actually running in its own process. Each process has its own memory space; therefore, the memory referred to by the <code>_navigationApplication</code> pointer does not actually exist.</p>
<p>This prevents us from simply using the <code>id</code> to invoke methods, modify properties, send signals, etc. This work must be done using <em>IPC</em> or <em>Inter-process Communication</em></p>
<ul>
<li>
<p><em><strong>Singletons</strong></em> - QtQuick developers far too often rely on singletons to manage global data or references to objects deeply nested within their object hierarchy. This is no longer supported as each process has its own <code>QQmlEngine</code> instance and cannot synchronize singletons across these engines.</p>
</li>
<li>
<p><em><strong>Resource Usage</strong></em> - As each application is running in its own process, linux requires each process to load symbols from any shared libraries (e.g. Qt libs) in each process. This results in duplication of memory for each process. This would also result in duplication for assets such as fonts, images, media, etc.<br>
<a id="qface"></a></p>
</li>
<li>
<p><em><strong>Developer experience</strong></em> - Multi-process in Qt ApplicationManager uses QtWayland which is only available on Linux operating systems. From my experience, good production developers nowadays will use MacOS (which provides the ability to open design files in Photoshop, Sketch, Zeplin) and translate them into running code. Since MacOS does not support QtWayland – QtApplicationManager falls back to a single-process emulated mode. The downside; however, is that this single-process emulated mode does not prevent deveopers from accessing different application elements by <code>id</code> and could therefore break when the code is moved to a multi-process capable environment such as linux.</p>
</li>
</ul>
<h2 id="qface">QFace</h2>
<p><a id="qmllive"></a></p>
<p>QFace is a very easy to use IDL format which includes a grammatical model template support to automatically generate Qt classes.<br>
It is well-documented here: <a href="https://doc-snapshots.qt.io/qtivi-5.10/qtivi-attribution-qface.html">https://doc-snapshots.qt.io/qtivi-5.10/qtivi-attribution-qface.html</a></p>
<h2 id="qmllive">QmlLive</h2>
<p>QmlLive is well-documented here:<br>
<a href="https://doc.qt.io/QtQmlLive/index.html">https://doc.qt.io/QtQmlLive/index.html</a></p>
<h3 id="advantages">Advantages</h3>
<ul>
<li>Hot reloading is the <em>new rage</em> in development. It allows UI developers to quickly modify pixel values, colors, etc. and see their creation live on screen.</li>
<li>Allows deployment of a runtime to an embedded device to see a UI reload live on a different device.</li>
</ul>
<h3 id="disadvantages">Disadvantages</h3>
<ul>
<li>This solution is too generic; reloads the entire application</li>
<li>UI states are not preserved upon reload</li>
</ul>
<h2 id="tips">Tips</h2>
<ul>
<li>Qt ApplicationManager (and the majority of the QtAutomotiveSuite) was developed by  <a href="http://www.pelagicore.com/">Pelagicore</a> in their Munich, Germany office.</li>
<li>Github - <a href="https://github.com/qt/qtapplicationmanager">https://github.com/qt/qtapplicationmanager</a></li>
<li>Two developers from Pelagicore have contributed the majority of the Qt ApplicationManager, <a href="https://github.com/rgriebl">Robert Griebl</a> and <a href="https://github.com/Gagi2k">Dominik Holland</a>.</li>
<li>Another developer from Pelagicore, <a href="https://github.com/jryannel">Juergen Ryannel</a> , created QFace</li>
<li>Major props to the team at Pelagicore!</li>
</ul>
<p><em><strong>Stay tuned for more in-depth posts for each of the above projects</strong></em></p>
</div>]]></content:encoded></item><item><title><![CDATA[Using the QtObject element]]></title><description><![CDATA[The absolute basic element in QML is the QtObject.  It is a pure representation of Qt C++'s QObject class. What can we use it for?]]></description><link>https://qml.guide/using-the-qtobject-element/</link><guid isPermaLink="false">5a47fac0e6209c23cfc4cbb5</guid><category><![CDATA[logic]]></category><category><![CDATA[data]]></category><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Sat, 30 Dec 2017 22:41:40 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1509094632847-e97545d7d043?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=9ae8c037b174345283cec682e1ee2585" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1509094632847-e97545d7d043?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=9ae8c037b174345283cec682e1ee2585" alt="Using the QtObject element"><p>The absolute <em>basic</em> element in QML is <code>QtObject</code>:</p>
<pre><code class="language-qml">import QtQml 2.2

QtObject {
    property var name: &quot;John Doe&quot;
}
</code></pre>
<p>A <code>QtObject</code> is a QML representation of the <code>QObject</code> element. This can be seen in Qt source code <a href="https://code.woboq.org/qt5/qtdeclarative/src/qml/qml/qqmlengine.cpp.html#218">here</a> where the QML base types are registered:</p>
<pre><code class="language-c++">...
void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
{
    ...
    qmlRegisterType&lt;QObject&gt;(uri,versionMajor,versionMinor,&quot;QtObject&quot;);
    ...
</code></pre>
<p><code>QtObject</code> is a non-visual element and is very useful for grouping together or creating blocks of <em>business logic</em> in the otherwise <em>UI-heavy</em> QML land.</p>
<h3 id="privatepropertiesinqml">Private properties in QML</h3>
<p>Controlling access to QML-based objects is not possible, i.e. it is not possible to use the membership keywords such as <code>private</code>, <code>public</code>, or <code>protected</code> in QML.</p>
<p>To workaround this slight inconvenience, developers can use the <code>QtObject</code> element to privatize methods or properties.</p>
<p>Let's say we want to build a <em>Slider</em> component that can be used by anyone. We want to ensure our API is clean and indestructible.</p>
<p>Start with the <em>Slider</em> UI.</p>
<ul>
<li>First, build the <em>track</em> or the line that the slider circle will move on</li>
<li>Second, build the <em>scrubber</em> or the circle that the user will interact with</li>
<li>Third, add a <code>MouseArea</code> in the <em>scrubber</em> so it is interactive. We set the <code>minimumX</code> and <code>maximumX</code> so the center of the circle is at the ends of the line when its value is minimized or maximized, respectively.</li>
</ul>
<p><em>Slider.qml</em></p>
<pre><code>import QtQuick 2.7

Item {
    id: root
    width: 200
    height: 40

    Rectangle {
        id: _rectangleTrack
        anchors.centerIn: parent
        width: parent.width - _rectangleScrubber.width
        height: 4
        color: &quot;#222222&quot;
    }

    Rectangle {
    	id: _rectangleScrubber
    	anchors.verticalCenter: _rectangleTrack.verticalCenter
    	width: parent.height / 2
    	height: width
    	radius: width / 2

    	color: &quot;#EEEEEE&quot;

    	border.color: &quot;#DDDDDD&quot;
    	border.width: 2

        MouseArea {
            anchors.fill: parent
            drag.target: parent
            drag.minimumX: 0
            drag.maximumX: _rectangleTrack.width
    	}
    }
}
</code></pre>
<p>Now run your <em>Slider.qml</em> through <code>qmlscene</code> and you should see this:<br>
<img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-30-at-1.48.07-PM.png" alt="Using the QtObject element"></p>
<p>Now that we have a UI for this <em>Slider</em>, let's expose an API.</p>
<p>Several great examples of APIs are already written, and in this case, Qt has already built a Slider. In the interest of learning from the ground up, let's take three properties from <a href="http://doc.qt.io/qt-5/qml-qtquick-controls-slider.html">their API</a>:</p>
<ul>
<li><em><strong>value</strong></em> - The current value held by the slider. This is calculated by mapping the percentage of the <em>scrubber</em> on the <em>track</em> to the difference between the <em>maximumValue</em> and <em>minimumValue</em> properties</li>
<li><em><strong>minimumValue</strong></em> - The smallest possible value, i.e. the value when the scrubber is at 0%</li>
<li><em><strong>maximumValue</strong></em> - The largest possible value, i.e. the value when the scrubber is at 100%</li>
</ul>
<pre><code class="language-qml">    property real value: 0.0
    property real minimumValue: 0.0
    property real maximumValue: 10.0
</code></pre>
<p>We will use floating point values for maximum flexibility.</p>
<p>Now, let's connect this API to our UI elements. It's important to consider the <em>user</em> of each property in order to build a stable, secure API.</p>
<p>The <code>value</code> property will be used by:</p>
<ul>
<li><em>External</em>: Developers who use the <em>Slider</em> element can set a real number to the <code>value</code> property</li>
<li><em>Internal</em>: When a user of the <em>Slider</em> UI element drag the <em>scrubber</em>, logic that lives internal to the <em>Slider</em> will update the <code>value</code> property to accurately reflect the new value.</li>
</ul>
<p>The <code>minimumValue</code> and <code>maximumValue</code> properties will be used by:</p>
<ul>
<li><em>External</em>: Developers who use the <em>Slider</em> element can set these two values to create a range of possible values for the <em>Slider</em></li>
<li><em>Internal</em>: This value is never changed by internal logic of the <em>Slider</em> element</li>
</ul>
<p>Now we're ready to connect our properties to our UI elements. Let's begin with the <code>value</code> property. When the <em>Slider</em> element is first created, we want to ensure the default real number of the <code>value</code> property affects where the position of the scrubber is on the track.</p>
<p>Set the <code>value</code> property to <code>5.0</code>; this indicates the scrubber is halfway through the track.</p>
<pre><code>percentageAlongTheTrack = value / (maximumValue - minimumValue)
</code></pre>
<p>Plugging in our numbers we get:</p>
<pre><code class="language-qml">50% = 5.0 / (10.0 - 0.0)
</code></pre>
<p>We can use this simple equation to set the <code>x</code> value of the <em>scrubber</em>:</p>
<pre><code class="language-qml">x: _rectangleTrack.width * (root.value / (root.maximumValue - root.minimumValue))
</code></pre>
<p>Here's the entire file for clarity:</p>
<p><em>Slider.qml</em></p>
<pre><code class="language-qml">import QtQuick 2.7

Item {
    id: root

    property real value: 5.0
    property real minimumValue: 0.0
    property real maximumValue: 10.0

    width: 200
    height: 40

    Rectangle {
        id: _rectangleTrack
        anchors.centerIn: parent
        width: parent.width - _rectangleScrubber.width
        height: 4
        color: &quot;#222222&quot;
    }

    Rectangle {
    	id: _rectangleScrubber
    	anchors.verticalCenter: _rectangleTrack.verticalCenter

    	x: _rectangleTrack.width * (root.value / (root.maximumValue - root.minimumValue))

    	width: parent.height / 2
    	height: width
    	radius: width / 2

    	color: &quot;#EEEEEE&quot;

    	border.color: &quot;#DDDDDD&quot;
    	border.width: 2

        MouseArea {
            anchors.fill: parent
            drag.target: parent
            drag.minimumX: 0
            drag.maximumX: _rectangleTrack.width
    	}
    }
}
</code></pre>
<p>That is <em>already</em> a decent amount of logic within a UI element. Let's move it to the <code>root</code> element:</p>
<pre><code class="language-qml">import QtQuick 2.7

Item {
    id: root

    property real value: 4.0
    property real minimumValue: 0.0
    property real maximumValue: 10.0

    property int scrubberXPosition: _rectangleTrack.width * (value / (maximumValue - minimumValue))

    width: 200
    height: 40

    Rectangle {
        id: _rectangleTrack
        anchors.centerIn: parent
        width: parent.width - _rectangleScrubber.width
        height: 4
        color: &quot;#222222&quot;
    }

    Rectangle {
    	id: _rectangleScrubber
    	anchors.verticalCenter: _rectangleTrack.verticalCenter

    	x: root.scrubberXPosition

    	width: parent.height / 2
    	height: width
    	radius: width / 2

    	color: &quot;#EEEEEE&quot;

    	border.color: &quot;#DDDDDD&quot;
    	border.width: 2

        MouseArea {
            anchors.fill: parent
            drag.target: parent
            drag.minimumX: 0
            drag.maximumX: _rectangleTrack.width
    	}
    }
}
</code></pre>
<p>We can make it <em>readonly</em> so the developers who use the <em>Slider</em> component cannot overwrite our logic:</p>
<pre><code class="language-qml">readonly property int scrubberXPosition: _rectangleTrack.width * (value / (maximumValue - minimumValue))
</code></pre>
<p>Our API has now been extended by one property; unwillingly:</p>
<ul>
<li>value</li>
<li>minimumValue</li>
<li>maximumValue</li>
<li>scrubberXPosition</li>
</ul>
<p>It is really necessary for us to expose a <em>readonly</em> property for the scrubber's x position? In this case, no. This is where a <code>private</code> member in C++ is quite useful; however, since we are in QML land, we do not have such capability.</p>
<p>Enter <code>QtObject</code>:</p>
<p>We can use a <code>QtObject</code> as a lightweight container to wrap our logic since it is unwanted as an exposed API:</p>
<pre><code class="language-qml">import QtQuick 2.7

Item {
    id: root

    property real value: 4.0
    property real minimumValue: 0.0
    property real maximumValue: 10.0

    width: 200
    height: 40

    QtObject {
        id: internal

        readonly property int scrubberXPosition: _rectangleTrack.width * (root.value / (root.maximumValue - root.minimumValue))
    }

    Rectangle {
        id: _rectangleTrack
        anchors.centerIn: parent
        width: parent.width - _rectangleScrubber.width
        height: 4
        color: &quot;#222222&quot;
    }

    Rectangle {
    	id: _rectangleScrubber
    	anchors.verticalCenter: _rectangleTrack.verticalCenter

    	x: internal.scrubberXPosition

    	width: parent.height / 2
    	height: width
    	radius: width / 2

    	color: &quot;#EEEEEE&quot;

    	border.color: &quot;#DDDDDD&quot;
    	border.width: 2

        MouseArea {
            anchors.fill: parent
            drag.target: parent
            drag.minimumX: 0
            drag.maximumX: _rectangleTrack.width
    	}
    }
}
</code></pre>
<p>We have now reduced our API back to the original three properties we wanted:</p>
<ul>
<li>value</li>
<li>minimumValue</li>
<li>maximumValue</li>
</ul>
<p>Let's continue building our <em>Slider</em> element.</p>
<p>Whenever a user drags the scrubber, we want the <code>value</code> property to update. We can add this logic directly to the scrubber <code>Rectangle</code> using an <code>onXChanged</code> handler:</p>
<pre><code class="language-qml">...
Rectangle {
    id: _rectangleScrubber
    anchors.verticalCenter: _rectangleTrack.verticalCenter

    x: internal.scrubberXPosition

    onXChanged: {
        root.value = (x / _rectangleTrack.width) * (root.maximumValue - root.minimumValue)
    }

    width: parent.height / 2
    height: width
    radius: width / 2
        
        ...
</code></pre>
<p>Now, we run into a similar problem as we did above. This logic should not be in a UI element; but rather a logic block. We now have the <code>QtObject</code>; let's move our logic into there:</p>
<pre><code class="language-qml">QtObject {
    id: internal

    readonly property int scrubberXPosition: _rectangleTrack.width * (root.value / (root.maximumValue - root.minimumValue))

    Connections {
        target: _rectangleScrubber
        onXChanged: {
            root.value = (x / _rectangleTrack.width) * (root.maximumValue - root.minimumValue)
        }
    }
}
</code></pre>
<p>Now, use <code>qmlscene</code> to run your program:</p>
<pre><code>file:///qmlguide/examples/QtObject/Slider.qml:18 Cannot assign to non-existent default property
</code></pre>
<p>Uh oh! What does this mean?</p>
<p>The issue here is that since <code>QtObject</code> is <em>exactly</em> a <code>QObject</code> registered using <code>qmlRegisterType</code>; as we saw above, it is not prepared for the likeness of QML. <code>QQuickItem</code> derived elements have a <code>data</code> property is set as the <code>default</code> property.</p>
<p>What is a <code>default</code> property? Whenever you use the QML syntax to create an object hierarchy, the child elements <em>have to go somewhere</em>.<br>
The child elements have to be <em>stored</em> somewhere in the parent.</p>
<pre><code class="language-qml">Car {
    Tire { }
    Tire { }
    Tire { }
    Tire { }
}
</code></pre>
<p>In this example, the <code>Car</code> element has four child <code>Tire</code> elements. Given that <code>Car</code> is a <code>QQuickItem</code> derived class, the <code>Tire</code> elements are automatically placed into the <code>default</code> property which is <code>data</code>.</p>
<h4 id="settingthedefaultpropertyinc">Setting the default property in C++</h4>
<p>In C++, this is accomplished using <code>Q_CLASSINFO(&quot;DefaultProperty&quot;, &quot;data&quot;)</code> and building up a <code>QQmlListProperty</code> for the <code>data</code> member. You can see how Qt does this for <code>QQuickItem</code> <a href="https://code.woboq.org/qt5/qtdeclarative/src/quick/items/qquickitem.h.html#150">here</a>.</p>
<h4 id="settingthedefaultpropertyinqml">Setting the default property in QML</h4>
<p>In QML, this is accomplished in a much easier way. We can simply use the <code>default</code> directive prior to the property name.</p>
<p>Create a new QML file called <em>BaseObject.qml</em>:</p>
<p><em>BaseObject.qml</em></p>
<pre><code class="language-qml">import QtQml 2.2

QtObject {
    default property var data
}
</code></pre>
<p>Now, any new element that is created within this object instance is automatically placed within the <code>data</code> property.</p>
<p>Update your <em>Slider</em> element to look like this:</p>
<p><em>Slider.qml</em></p>
<pre><code class="language-qml">import QtQuick 2.7

Item {
    id: root

    property real value: 5.0
    property real minimumValue: 0.0
    property real maximumValue: 10.0

    width: 200
    height: 40

    BaseObject {
        id: internal

        readonly property int scrubberXPosition: _rectangleTrack.width * (root.value / (root.maximumValue - root.minimumValue))

        Connections {
            target: _rectangleScrubber
            onXChanged: {
                root.value = (x / _rectangleTrack.width) * (root.maximumValue - root.minimumValue)
            }
        }
    }

    Rectangle {
        id: _rectangleTrack
        anchors.centerIn: parent
        width: parent.width - _rectangleScrubber.width
        height: 4
        color: &quot;#222222&quot;
    }

    Rectangle {
    	id: _rectangleScrubber
    	anchors.verticalCenter: _rectangleTrack.verticalCenter

    	x: internal.scrubberXPosition

    	width: parent.height / 2
    	height: width
    	radius: width / 2

    	color: &quot;#EEEEEE&quot;

    	border.color: &quot;#DDDDDD&quot;
    	border.width: 2
    	
        MouseArea {
            anchors.fill: parent
            drag.target: parent
            drag.minimumX: 0
            drag.maximumX: _rectangleTrack.width
    	}
    }
}
</code></pre>
<p>Run your code again, and voila! Everything's working great.</p>
<p>There are more touch ups you can do to the <em>Slider</em> element to avoid binding loops. Use the <code>pressed</code> boolean of the <code>MouseArea</code> to avoid recalculating the <code>scrubberXPosition</code> of the scrubber when it is being dragged. When the scrubber is released, the binding of <code>root.value</code> to <code>internal.scrubberXPosition</code> needs to be re-established.</p>
<p>The code in this tutorial is available at the <a href="https://github.com/ndesai/qml.guide/tree/master/examples/QtObject">qml.guide GitHub repo</a>.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Data Models Deconstructed - Part 2: QAbstractListModel]]></title><description><![CDATA[QAbstractListModel is the tried and true way of exposing data from Qt C++ to QML. This abstract class provides an interface or contract that is adhered to by QtQuick elements.]]></description><link>https://qml.guide/data-models-deconstructed-part-2-qabstractlistmodel/</link><guid isPermaLink="false">5a4439d4e6209c23cfc4cba8</guid><category><![CDATA[models]]></category><category><![CDATA[qabstractlistmodel]]></category><category><![CDATA[data]]></category><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Fri, 29 Dec 2017 01:45:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1477244075012-5cc28286e465?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=650281f5f6da101b6954a53645bf6501" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1477244075012-5cc28286e465?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=650281f5f6da101b6954a53645bf6501" alt="Data Models Deconstructed - Part 2: QAbstractListModel"><p><em>NOTE: This is Part 2 of the <strong>Data Models Deconstructed</strong> series, <a href="https://qml.guide/data-models-deconstructed-part-1-qml-js-arrays/">see Part 1 here.</a></em></p>
<p><a href="http://doc.qt.io/qt-5/qabstractitemmodel.html"><code>QAbstractListModel</code></a> is the tried and true way of exposing data from Qt C++ to QML. This abstract class provides an interface or <em>contract</em> that is adhered to by QtQuick elements such as <code>ListView</code>, <code>PathView</code>, <code>GridView</code>, and <code>Repeater</code>.</p>
<p>Because of this <em>contract</em> set forth by <code>QAbstractListModel</code>, Qt is able to provide a very efficient mechanism of data exposure to QML.</p>
<p>Efficiencies can be seen in many things including:</p>
<ul>
<li>Inserting items to a data set</li>
<li>Moving items in a data set</li>
<li>Editing items in a data set</li>
<li>Removing items from a data set</li>
</ul>
<p>These <em>dataset manipulation</em> methods allow us to update QML UIs or views without heavy performance impact.</p>
<p>If a list of top 100 music tracks needs to be displayed in QML, and one track at index #10 is changed, we don't need to rebuild the entire dataset and the list UI doesn't need to be completely re-drawn. The element at index #10 is modified in the dataset, and correspondingly the element at index #10 in the list UI is updated without modifying the list scroll position or any other visual element of the list.</p>
<p><img src="https://qml.guide/content/images/2017/12/datamodel-qabstractlistmodel-tracks.png" alt="Data Models Deconstructed - Part 2: QAbstractListModel"></p>
<h2 id="qabstractlistmodelbasics">QAbstractListModel Basics</h2>
<p>Since <code>QAbstractListModel</code> is an <em>abstract</em> class, it provides an <em>interface</em> or <em>contract</em> that must be <em>implemented</em> or <em>adhered to</em> by the user.</p>
<p>It is essentially useless in itself as it is an interface. Extend it, implement it.</p>
<pre><code class="language-c++">int rowCount();
QVariant data();
QHash&lt;int, QByteArray&gt; roleNames()
</code></pre>
<p>There is a good amount of detail on how to do this here:<br>
<a href="http://doc.qt.io/qt-5/qabstractlistmodel.html">http://doc.qt.io/qt-5/qabstractlistmodel.html</a></p>
<h2 id="qabstractlistmodelcaveats">QAbstractListModel Caveats</h2>
<p>If you read the above <em>Basics</em> section and the Qt documentation linked above, you may notice that the <em>roleNames</em> requirement is quite cumbersome.</p>
<p>If you have a model of music tracks, each model item would be a music track.</p>
<p>Imagine a QML-based API looking like this:</p>
<pre><code class="language-qml">MusicTrackModel {
    MusicTrack { }
    MusicTrack { }
    MusicTrack { }
    MusicTrack { }
}
</code></pre>
<p>Here, <code>MusicTrackModel</code> is the class name of your model, and each <code>MusicTrack</code> is an item within your model.</p>
<p>Say the <code>MusicTrack</code> is defined as:</p>
<pre><code class="language-qml">QtObject {
    property string title
    property string artistName
    property int duration
}
</code></pre>
<p>Each property of the <code>MusicTrack</code> item is considered a <code>roleName</code> of the <code>MusicTrackModel</code>.</p>
<p>The C++ shortened implementation of the <code>MusicTrackModel</code> would look like this:</p>
<pre><code class="language-c++">
...
...
...

class MusicTrackModel : QAbstractListModel {
    Q_OBJECT

public:
    enum ModelRoles {
        TitleRole = Qt::UserRole + 1,
        ArtistNameRole,
        DurationRole
    };
    
    ...
    ...
    ...
    
    QHash&lt;int, QByteArray&gt; roleNames() const
    {
        QHash&lt;int, QByteArray&gt; roles;
        roles[TitleRole] = &quot;title&quot;;
        roles[ArtistNameRole] = &quot;artistName&quot;;
        roles[DurationRole] = &quot;duration&quot;;
        return roles;
    }
}
</code></pre>
<p>As can be seen, there is tight coupling between the model and the model item. This may be useful for some cases where this model couples with another object to sort / filter the data before sending it to the QML-side of the codebase.</p>
<p>However; for most use-cases, the model items, i.e. <code>MusicTrack</code>, will be QObject-derived objects with properties that are distinguishable via the <code>QMetaObject</code>. If having restricted properties per model item is not a concern, you can build a generic model for all QObject-derived items. These items can be defined in Qt or in QML.</p>
<h2 id="buildingagenericmodelthatholdsanyqobjectderivedclass">Building a generic model that holds any QObject-derived class</h2>
<blockquote>
<p><em>When designing an object that will be exposed to QML, I have found it easier to start with the API of the object, then work towards the implementation</em></p>
</blockquote>
<h3 id="designingtheqmlfacingapi">Designing the QML-facing API</h3>
<p>Let's start with the QML API for what a generic model that can hold any QObject-derived class:</p>
<pre><code class="language-qml">
DataObjectModel {
    id: _dataObjectModel
    
    QtObject {
        property string title: &quot;The first track&quot;
        property string artistName: &quot;John Doe&quot;
        property int duration: 230213
    }
    QtObject {
        property string title: &quot;The second track&quot;
        property string artistName: &quot;John Doe&quot;
        property int duration: 123111
    }
    QtObject {
        property string title: &quot;The third track&quot;
        property string artistName: &quot;John Doe&quot;
        property int duration: 12239991
    }
}

ListView {
    ...
    model: _dataObjectModel
}

</code></pre>
<p>As we can see here, we would like a model that can be fed into a QtQuick view; i.e. a <code>ListView</code>. This model is constructed by placing QtObject's within it.</p>
<p>Let's simplify the API by creating a new component called <code>MusicTrack</code>, e.g. MusicTrack.qml</p>
<pre><code class="language-qml">QtObject {
    property string title
    property string artistName
    property int duration
}
</code></pre>
<p>Now, our simplified API use-case is:</p>
<pre><code class="language-qml">
DataObjectModel {
    id: _dataObjectModel
    
    MusicTrack {
        title: &quot;The first track&quot;
        artistName: &quot;John Doe&quot;
        duration: 230213
    }
    MusicTrack {
        title: &quot;The second track&quot;
        artistName: &quot;John Doe&quot;
        duration: 123111
    }
    MusicTrack {
        title: &quot;The third track&quot;
        artistName: &quot;John Doe&quot;
        duration: 12239991
    }
}

ListView {
    ...
    model: _dataObjectModel
}

</code></pre>
<h3 id="buildingtheqabstractlistmodelimplementation">Building the QAbstractListModel implementation</h3>
<p>Let's call our model <code>DataObjectModel</code> to fit our API design.</p>
<p><code>DataObjectModel</code> doesn't seem to have any properties in the example above, but let's consider the <em>hidden</em> API of a standard QtQuick-provided model, i.e. <code>ListModel</code></p>
<p>A <a href="http://doc.qt.io/qt-5/qml-qtqml-models-listmodel.html"><code>ListModel</code></a> has:</p>
<ul>
<li>count - The total number of items in the model</li>
<li>append(..) - A method to append an object to the model</li>
<li>insert(.., ..) - A method to insert an object to a particular index of the model</li>
<li>get(..) - A method to get the object at a particular index from the model</li>
</ul>
<p>This is a standard API amongst many pre-built models in QtQuick. Let's include these in our <code>DataObjectModel</code>.</p>
<p>Let's start by creating a new C++ class in your project with QtCreator.</p>
<p>Go to <em><strong>File &gt; New File or Project</strong></em></p>
<p><img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-28-at-3.07.16-PM.png" alt="Data Models Deconstructed - Part 2: QAbstractListModel"></p>
<p>Name your class <code>DataObjectModel</code> and derive it from QObject, for now:</p>
<p><img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-28-at-3.17.53-PM.png" alt="Data Models Deconstructed - Part 2: QAbstractListModel"></p>
<p>You should now have a header file, <code>dataobjectmodel.h</code> that looks like this:</p>
<pre><code class="language-c++">#ifndef DATAOBJECTMODEL_H
#define DATAOBJECTMODEL_H

#include &lt;QObject&gt;

class DataObjectModel : public QObject
{
    Q_OBJECT
public:
    explicit DataObjectModel(QObject *parent = nullptr);

signals:

public slots:
};

#endif // DATAOBJECTMODEL_H
</code></pre>
<p>I prefer using <code>#pragma once</code> with <a href="https://woboq.com/blog/cpp11-in-qt5.html">C++11</a>, instead of the defines that are generated by by QtCreator templates:</p>
<p><em>dataobjectmodel.h</em></p>
<pre><code class="language-c++">#pragma once

#include &lt;QObject&gt;

class DataObjectModel : public QObject
{
    Q_OBJECT
public:
    explicit DataObjectModel(QObject *parent = nullptr);

signals:

public slots:
};
</code></pre>
<p>Now, let's derive our class from <code>QAbstractListModel</code>:</p>
<p><em>dataobjectmodel.h</em></p>
<pre><code class="language-c++">#pragma once

#include &lt;QAbstractListModel&gt;

class DataObjectModel : public QAbstractListModel
{
    Q_OBJECT
public:
    explicit DataObjectModel(QObject *parent = nullptr);

signals:

public slots:
};
</code></pre>
<p><em>dataobjectmodel.cpp</em></p>
<pre><code class="language-c++">#include &quot;dataobjectmodel.h&quot;

DataObjectModel::DataObjectModel(QObject *parent)
    : QAbstractListModel(parent)
{

}
</code></pre>
<blockquote>
<p><em>Build it, make sure your code is building!</em></p>
</blockquote>
<p>Now, let's setup the properties from the API we designed earlier:</p>
<p>Start with the <em>count</em> property:</p>
<p>Add a <code>Q_PROPERTY</code> under the <code>Q_OBJECT</code> macro:</p>
<pre><code>...
Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)
...
</code></pre>
<p>To generate the setters / getters, simply right click on the <code>Q_PROPERTY</code> designator and right click, <em><strong>Refactor -&gt; Generate Missing Q_PROPERTY members</strong></em></p>
<p><img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-28-at-3.39.32-PM.png" alt="Data Models Deconstructed - Part 2: QAbstractListModel"></p>
<p><em>dataobjectmodel.h</em></p>
<pre><code class="language-c++">#pragma once

#include &lt;QAbstractListModel&gt;

class DataObjectModel : public QAbstractListModel
{
    Q_OBJECT
    Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)

    int m_count;

public:
    explicit DataObjectModel(QObject *parent = nullptr);

    int count() const
    {
        return m_count;
    }

signals:
    void countChanged(int count);

public slots:
    void setCount(int count)
    {
        if (m_count == count)
            return;

        m_count = count;
        emit countChanged(m_count);
    }
};
</code></pre>
<p>Move the implementations to the cpp file by right clicking on the signature and <em><strong>Refactor -&gt; Move definition to dataobjectmodel.cpp</strong></em></p>
<p>I also prefer moving the member variable, <code>m_count</code> to a specific <code>private</code> block at the bottom of the document:</p>
<p><em>dataobjectmodel.h</em></p>
<pre><code class="language-c++">#pragma once

#include &lt;QAbstractListModel&gt;

class DataObjectModel : public QAbstractListModel
{
    Q_OBJECT
    Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)

public:
    explicit DataObjectModel(QObject *parent = nullptr);
    int count() const;

signals:
    void countChanged(int count);

public slots:
    void setCount(int count);

private:
    int m_count;
};
</code></pre>
<p><em>dataobjectmodel.cpp</em></p>
<pre><code class="language-c++">#include &quot;dataobjectmodel.h&quot;

DataObjectModel::DataObjectModel(QObject *parent)
    : QAbstractListModel(parent)
{

}

int DataObjectModel::count() const
{
    return m_count;
}

void DataObjectModel::setCount(int count)
{
    if (m_count == count)
        return;

    m_count = count;
    emit countChanged(m_count);
}
</code></pre>
<p>Now, initialize the count to 0 in the cpp file:</p>
<p><em>dataobjectmodel.cpp</em></p>
<pre><code class="language-c++">
...

DataObjectModel::DataObjectModel(QObject *parent)
    : QAbstractListModel(parent)
    , m_count(0)
{

}

...

</code></pre>
<p>Let's continue building out our API:</p>
<ul>
<li><s>count - The total number of items in the model</s></li>
<li>append(..) - A method to append an object to the model</li>
<li>insert(.., ..) - A method to insert an object to a particular index of the model</li>
<li>get(..) - A method to get the object at a particular index from the model</li>
</ul>
<p>The remaining three API considerations are methods. We can create methods simply by adding <code>Q_INVOKABLE</code> to a standard C++ method.</p>
<p><em>dataobjectmodel.h</em></p>
<pre><code class="language-c++">...
public:
    Q_INVOKABLE void append(QObject* o);
    Q_INVOKABLE void insert(QObject* o, int i);
    Q_INVOKABLE QObject* get(int i);
...
</code></pre>
<p>Add stub implementations into <em>dataobjectmodel.cpp</em>.</p>
<p>Now, let's step back and think about what we're building.<br>
We are building a <em>wrapper</em> to a set of data that we want to expose to QML. This <em>wrapper</em> provides the API we designed above.</p>
<blockquote>
<p>If <code>DataObjectModel</code> is simply a <em>wrapper</em>, where is the real data stored?</p>
</blockquote>
<p>The data is stored <em>inside</em> the <code>DataObjectModel</code> class. Let's add a new private member called <code>m_data</code> and use the <code>QList</code> data structure to store a list of object pointers.</p>
<p><em>dataobjectmodel.h</em></p>
<pre><code class="language-c++">...
private:
    int m_count;
    QList&lt;QObject*&gt; m_data;
...
</code></pre>
<p>Now, let's think back to how we can complete our <em>wrapper</em> to provide data from the <code>m_data</code> list. At the start of this article, we learned about how the <code>QAbstractListModel</code> is essentially an <em>interface</em> or <em>contract</em> that many different elements adhere to. We need to make sure we fulfill our side of this <em>contract</em> by implementing the methods required by the <code>QAbstractListModel</code>.</p>
<p>Which methods do we need to implement?</p>
<p>Let's add these methods for <code>rowCount(..)</code>, <code>data(..,..)</code>, and <code>roleNames()</code> to our <code>DataObjectModel</code> class:</p>
<pre><code class="language-c++">    int rowCount(const QModelIndex &amp;p) const;
    QVariant data(const QModelIndex &amp;index, int role) const;
    QHash&lt;int, QByteArray&gt; roleNames() const;
</code></pre>
<ul>
<li><em><strong>rowCount</strong></em> - This method simply returns the count of items in <code>m_data</code> as this is our data set. The argument <code>p</code> is unused and can be masked in a <code>Q_UNUSED(p)</code> block to avoid compiler warnings.</li>
</ul>
<pre><code class="language-c++">int DataObjectModel::rowCount(const QModelIndex &amp;p) const
{
    Q_UNUSED(p)
    return m_data.size();
}
</code></pre>
<ul>
<li><em><strong>data</strong></em> - This method is how a <code>ListView</code> or other view element that ingests the model can access individual data objects and properties. The argument <code>index</code> is the index of the element in the list – 0 of course is the first element in the the list. The argument <code>role</code> is the enum value of the property described by the <code>roleNames</code> method.</li>
<li>Since we have dynamic properties in the objects that are added to this model, the concept of <em>roles</em> are not needed; therefore, to satisfy our contract with <code>QAbstractListModel</code>, we will only have one dummy role (see the <em>roleNames</em> bullet point below).</li>
<li>The implementation of this method is simply returning an item at <code>index</code> of the <code>m_data</code> list where we store our data. We must wrap our object in a <code>QVariant</code> to satisfy the method signature. Since we only have one <em>dummy role</em>, we will wrap the <code>role</code> argument with <code>Q_UNUSED</code> to avoid compiler warnings.</li>
</ul>
<pre><code class="language-c++">QVariant DataObjectModel::data(const QModelIndex &amp;index, int role) const
{
    Q_UNUSED(role)
    return QVariant::fromValue(m_data[index.row()]);
}
</code></pre>
<ul>
<li><em><strong>roleNames</strong></em> - This method is a mapping of role enums to string values of their keys. Since we are allowing dynamic roles, we essentially only have one value here which refers to our object, called <code>dataObject</code>. This value is a <em>dummy role</em> but is still used on the QML side to refer to the object inside of a <code>delegate</code>, i.e. in a QtQuick view element, e.g. <code>ListView</code></li>
<li>The implementation of this method simply returns a <code>QHash</code> with one role. We use a static <code>QHash</code> variable called <code>pHash</code> as this preserves the map through consequent calls to the <code>roleNames()</code> method.</li>
</ul>
<pre><code class="language-c++">QHash&lt;int, QByteArray&gt; DataObjectModel::roleNames() const
{
    static QHash&lt;int, QByteArray&gt; *pHash;
    if (!pHash) {
        pHash = new QHash&lt;int, QByteArray&gt;;
        (*pHash)[Qt::UserRole + 1] = &quot;dataObject&quot;;
    }
    return *pHash;
}
</code></pre>
<p>Now we have implemented the features required by the <code>QAbstractListModel</code> <em>contract</em>. What's left?</p>
<p>Well, so far, we have built a <em>wrapper</em> to our data set held by the member variable <code>m_data</code>. If you have noticed, there is <em>nothing</em> in this variable. <code>m_data</code> is empty and our count is 0.</p>
<h3 id="insertingdataobjectsintothedataobjectmodel">Inserting Data Objects into the DataObjectModel</h3>
<p>Let's discuss how we can get data <em>into</em> our model and subsequently into our member variable <code>m_data</code>. We of course have the API methods <code>insert(.., ..)</code> and <code>append(..)</code> that we must implement:</p>
<ul>
<li><em><strong>append</strong></em> - Appending an object to our model simply involves us appending the object to our list variable, <code>m_data</code>, and emitting the necessary change signals – to adhere to our <em>contract</em> – so the user of our <code>QAbstractListModel</code> implementation knows that our data has been updated.</li>
<li>The implementation of this method starts by retrieving the current count of the data set. As we are <em>appending</em> an object to the end of our list, we can use this count value to instruct the <code>QAbstractListModel</code> interface as to where we are inserting our rows using the <code>beingInsertRows</code> method. We then append our object to the list <code>m_data</code>. Since <code>count</code> was a <code>Q_PROPERTY</code>, it is advisable to emit a changed signal as anyone who is bound to this on the QML side should receive an update when an object is appended. Finally, signal through the <code>QAbstractListModel</code> that we are done with the <code>endInsertRows</code> method.</li>
</ul>
<pre><code class="language-c++">void DataObjectModel::append(QObject *o) {
    int i = m_data.size();
    beginInsertRows(QModelIndex(), i, i);
    m_data.append(o);
    
    // Emit changed signals
    emit countChanged(count());
    
    endInsertRows();
}
</code></pre>
<p><img src="https://qml.guide/content/images/2017/12/modelview-begin-append-rows.png" alt="Data Models Deconstructed - Part 2: QAbstractListModel"></p>
<ul>
<li><em><strong>insert</strong></em> - Inserting an element allows a user to insert an object to a specified index of the model.</li>
<li>The implementation is nearly identical to the implementation of the <em>append</em> method:</li>
</ul>
<pre><code class="language-c++">void DataObjectModel::insert(QObject *o, int i)
{
    beginInsertRows(QModelIndex(), i, i);
    m_data.insert(i, o);

    // Emit changed signals
    emit countChanged(count());

    endInsertRows();
}
</code></pre>
<p>It is not necessary to invoke a <em>beginMoveRows</em> for the rows that are displaced by this insertion. In my testing, this seems to be handled internally.</p>
<p><img src="https://qml.guide/content/images/2017/12/modelview-begin-insert-rows.png" alt="Data Models Deconstructed - Part 2: QAbstractListModel"></p>
<p>See the <a href="http://doc.qt.io/qt-5/qabstractitemmodel.html#beginInsertRows">Qt Documentation</a> for more information regarding <em>beginInsertRows</em></p>
<p>It seems we have implemented the entire API for <code>DataObjectModel</code>! Slow down, we have one more thing to do. Remember how we wanted to use <code>DataObjectModel</code> in QML?</p>
<pre><code class="language-qml">
DataObjectModel {
    id: _dataObjectModel
    
    MusicTrack {
        title: &quot;The first track&quot;
        artistName: &quot;John Doe&quot;
        duration: 230213
    }
    MusicTrack {
        title: &quot;The second track&quot;
        artistName: &quot;John Doe&quot;
        duration: 123111
    }
    MusicTrack {
        title: &quot;The third track&quot;
        artistName: &quot;John Doe&quot;
        duration: 12239991
    }
}

ListView {
    ...
    model: _dataObjectModel
}

</code></pre>
<p>The <code>MusicTrack</code> objects are <em>children</em> of the <code>DataObjectModel</code>. Sadly, being <em>children</em> of an object is not enough for us to be able to automatically insert them into our list <code>m_data</code>. We need add a <em>default property</em> to where the <code>MusicTrack</code> or any other QObject-derived class will be parented to when placed inside the <code>DataObjectModel</code> QML block.</p>
<pre><code class="language-qml">DataObjectModel {
    // How do we get any element that is instantiated here to be
    // added to our model?
}
</code></pre>
<p>Let's start by defining the <code>QQmlListProperty</code> that will be <em>holding</em> a reference to the our <code>MusicTrack</code> objects.</p>
<p>Add a new public method called <code>content</code> that is a <code>QQmlListProperty</code> of <code>QObject</code>, i.e. <code>QQmlListProperty&lt;QObject&gt;</code></p>
<p><em>dataobjectmodel.h</em></p>
<pre><code class="language-c++">...
public:
    explicit DataObjectModel(QObject *parent = nullptr);
    QQmlListProperty&lt;QObject&gt; content();
...
</code></pre>
<p>This <code>QQmlListProperty</code> will define callbacks that will be executed whenever the QML object tree is modified.</p>
<p>We can see how this works in our implementation of the <code>content()</code> method. We have added 4 <em>slots</em> or callbacks to the return value for appending, count, at and clear.</p>
<p>We will declare and define these static slots later.</p>
<p><em>dataobjectmodel.cpp</em></p>
<pre><code class="language-c++">QQmlListProperty&lt;QObject&gt; DataObjectModel::content()
{
    return QQmlListProperty&lt;QObject&gt;(this,
                                     0,
                                     &amp;DataObjectModel::dataObjectAppend,
                                     &amp;DataObjectModel::dataObjectCount,
                                     &amp;DataObjectModel::dataObjectAt,
                                     &amp;DataObjectModel::dataObjectClear);
}
</code></pre>
<p><code>QQmlListProperty</code> will call those static slots for append, count, at, and clear whenever an element is modified in the QML object tree. We pass in <em>this</em>, or a reference to the <code>DataObjectModel</code> instance itself into the <code>QQmlListProperty</code> constructor so we can get a reference to it in the implementation of the static callbacks below.</p>
<p>See <a href="http://doc.qt.io/qt-5/qqmllistproperty.html#QQmlListProperty-2">Qt Documentation</a> for more information.</p>
<p>Let's define these methods:</p>
<p><em>dataobjectmodel.h</em></p>
<pre><code class="language-c++">...
public slots:
    static void dataObjectAppend(QQmlListProperty&lt;QObject&gt; *list, QObject *e);
    static int dataObjectCount(QQmlListProperty&lt;QObject&gt; *list);
    static QObject* dataObjectAt(QQmlListProperty&lt;QObject&gt; *list, int i);
    static void dataObjectClear(QQmlListProperty&lt;QObject&gt; *list);
...
</code></pre>
<p>And declare them:</p>
<p><em>dataobjectmodel.cpp</em></p>
<pre><code class="language-c++">...
void DataObjectModel::dataObjectAppend(QQmlListProperty&lt;QObject&gt; *list, QObject *o)
{
    DataObjectModel *dom = qobject_cast&lt;DataObjectModel*&gt;(list-&gt;object);
    if (dom &amp;&amp; o) {
        dom-&gt;append(o);
    }
}

int DataObjectModel::dataObjectCount(QQmlListProperty&lt;QObject&gt; *list)
{
    DataObjectModel *dom = qobject_cast&lt;DataObjectModel*&gt;(list-&gt;object);
    if (dom) {
        return dom-&gt;m_data.count();
    }
    return 0;
}

QObject *DataObjectModel::dataObjectAt(QQmlListProperty&lt;QObject&gt; *list, int i)
{
    DataObjectModel *dom = qobject_cast&lt;DataObjectModel*&gt;(list-&gt;object);
    if (dom) {
        return dom-&gt;get(i);
    }
    return 0;
}

void DataObjectModel::dataObjectClear(QQmlListProperty&lt;QObject&gt; *list)
{
    DataObjectModel *dom = qobject_cast&lt;DataObjectModel*&gt;(list-&gt;object);
    if (dom) {
        dom-&gt;m_data.clear();
    }
}
...
</code></pre>
<p>For each of these callbacks, we simply grab a reference to our <code>DataObjectModel</code> instance and execute commands to manipulate our data set represented by the member variable <code>m_data</code>.</p>
<p>Each <code>MusicTrack</code> object would be received as an argument <code>o</code> into the <code>dataObjectAppend</code> function.</p>
<p>Finally, to ensure the MOC associates the <em>content</em> method as the <code>DataObjectModel</code>'s default property, we must add two lines, one for the <code>Q_PROPERTY</code> declaration and another with the <code>Q_CLASSINFO</code> declaration.</p>
<pre><code class="language-c++">...
// Include the QQmlListProperty class
#include &lt;QQmlListProperty&gt;

class DataObjectModel : public QAbstractListModel {
    Q_OBJECT
    Q_DISABLE_COPY(DataObjectModel)
    Q_PROPERTY(int count READ count NOTIFY countChanged)

    // Add these two lines
    Q_PROPERTY(QQmlListProperty&lt;QObject&gt; content READ content)
    Q_CLASSINFO(&quot;DefaultProperty&quot;, &quot;content&quot;)
...
</code></pre>
<p>Voila! Your class is now ready to use in QML. Simply register it via <code>qmlRegisterType</code> and you can begin using it!</p>
<h3 id="exampleusage">Example Usage</h3>
<pre><code class="language-qml">
import QtQuick 2.7

Window {
    id: root
    
    DataObjectModel {
        id: _dataObjectModel

        MusicTrack {
            title: &quot;The first track&quot;
            artistName: &quot;John Doe&quot;
            duration: 230213
        }
        MusicTrack {
            title: &quot;The second track&quot;
            artistName: &quot;John Doe&quot;
            duration: 123111
        }
        MusicTrack {
            title: &quot;The third track&quot;
            artistName: &quot;John Doe&quot;
            duration: 12239991
        }
    }

    ListView {
        anchors.fill: parent
        model: _dataObjectModel
        delegate: Item {
            width: ListView.view.width
            height: 40
            
            Text {
                anchors.centerIn: parent
                font.bold: true
                // NOTE: This is where the roleName comes into play
                // There is a magic object called &quot;dataObject&quot; that references the
                // MusicTrack object for this particular index
                text: dataObject.title + &quot; by &quot; + dataObject.artistName
            }
        }
    }
}

</code></pre>
<p>And that's it!</p>
<p><img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-28-at-5.30.18-PM.png" alt="Data Models Deconstructed - Part 2: QAbstractListModel"></p>
<p>Sample code is available in the <a href="https://github.com/ndesai/qml.guide/tree/master/examples/DataObjectModel">qml.guide GitHub repository</a>.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Getting started with QML and QtQuick]]></title><description><![CDATA[QML, or Qt Markup Language, is a declarative language used to simplify the development with its neatly organized grammatical structure.]]></description><link>https://qml.guide/getting-started-with-qml/</link><guid isPermaLink="false">5a447073e6209c23cfc4cbb0</guid><category><![CDATA[Getting Started]]></category><category><![CDATA[Beginners]]></category><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Thu, 28 Dec 2017 20:00:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1505744386214-51dba16a26fc?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=30204a7ce82dc1e5e76ee4a94f3a2f91" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><h2 id="whatisqmlandqtquick">What is QML and QtQuick?</h2>
<img src="https://images.unsplash.com/photo-1505744386214-51dba16a26fc?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=30204a7ce82dc1e5e76ee4a94f3a2f91" alt="Getting started with QML and QtQuick"><p>QML, or Qt Markup Language, is a declarative language used to simplify the development with its neatly organized grammatical structure. QML is used to build QtQuick, to assist in building complex user interfaces. It's an easy to learn Javascript-based declarative markup and allows the quick creation and deployment of GUIs.</p>
<h2 id="gettingstartedwithqtqml">Getting Started with Qt/QML</h2>
<p>Download the Qt online installer for the best installation and setup. This installer will also assist you in installing mobile versions for iOS and Android; including any dependencies that are needed.</p>
<h3 id="preferredinstallationmethodqtinstaller">Preferred installation method: Qt Installer</h3>
<p>Offline and online installers are available <a href="http://download.qt.io/official_releases/qt/">here</a>.</p>
<ul>
<li><s>A qt.io account is <em>needed</em> to install.</s></li>
<li>Edit: <a href="https://github.com/ndesai/qml.guide/issues/1">As reader @Larpon reports</a>, it is possible to <em>skip</em> the login step in the installer.</li>
<li>Build Kits are setup properly in QtCreator.</li>
</ul>
<p><img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-30-at-1.53.09-PM.png" alt="Getting started with QML and QtQuick"></p>
<h3 id="alternateinstallationmethod">Alternate installation method</h3>
<p>You may use repository installation. Do note that these installs may require additional setup. You will also need to download the QtCreator IDE separately.</p>
<ul>
<li>A qt.io account is <em>not</em> needed when using this method.</li>
<li>Build Kits require additional setup in QtCreator.</li>
</ul>
<pre><code># On macOS with homebrew:
brew install qt5

# On Ubuntu with apt:
sudo apt-get install qt5
</code></pre>
<h2 id="qtcreator">QtCreator</h2>
<p>QtCreator is the preferred IDE for Qt-based projects.</p>
<p><img src="https://qml.guide/content/images/2017/12/qtcreator-welcome.jpg" alt="Getting started with QML and QtQuick"></p>
<p>Start by <a href="https://www1.qt.io/download-open-source/">downloading</a> and installing the Qt SDK which includes the Qt libraries and the Qt Creator IDE.</p>
<p>Once you've installed the Qt SDK, go ahead and launch QtCreator, the well-built IDE for anything Qt. Create a new project. Choose a new <em>Qt Quick Application</em> which will allow maximum flexibility in creating C++/QML hybrid applications.</p>
<p><img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-27-at-8.31.42-PM.png" alt="Getting started with QML and QtQuick"></p>
<p>Choose a name for your project. The name you place in here can be changed later by simply renaming the *.pro file that is created.</p>
<p><img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-27-at-8.32.30-PM.png" alt="Getting started with QML and QtQuick"></p>
<p>In this example, QtCreator will automatically create two folders:</p>
<pre><code>$ ls /Users/niraj/Work/qmlguide/examples/
- ExampleQtQuickApplication/
- build-ExampleQtQuickApplication-Qt510-Debug/
</code></pre>
<h3 id="buildsystems">Build Systems</h3>
<p>A variety of build systems are supported by QtCreator.</p>
<h4 id="qmake">qmake</h4>
<p><a href="http://doc.qt.io/qt-5/qmake-manual.html">qmake</a> is Qt's original build system. It uses an esoteric language to generate Makefiles which are then used by the <code>make</code> tool to build code into binaries.</p>
<p>qmake is the preferred build system when building Qt code for multiple supported platforms, i.e. iOS and Android.</p>
<p>I have found it difficult to integrate other open source projects with qmake-based projects cleanly. This can always be supported by wrapping qmake in bash-based build scripts.</p>
<blockquote>
<p>The qmake tool helps simplify the build process for development projects across different platforms. It automates the generation of Makefiles so that only a few lines of information are needed to create each Makefile. You can use qmake for any software project, whether it is written with Qt or not.</p>
</blockquote>
<h4 id="cmake">CMake</h4>
<p><a href="https://cmake.org/">CMake</a> is an open source build tool used for many C/C++ projects.</p>
<p>CMake is preferred if the platform is not iOS / Android. I have found CMake the better option as it can be easily integrated with many open source applications / projects. It is also really well documented.</p>
<blockquote>
<p>CMake is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice.</p>
</blockquote>
<h4 id="qbs">QBS</h4>
<p>This is a relatively new build system, maintained by Qt, based on the QML language.<br>
More information can be found <a href="http://doc.qt.io/qbs/">here</a>.</p>
<blockquote>
<p>Qbs is a tool that helps simplify the build process for developing projects across multiple platforms. Qbs can be used for any software project, regardless of programming language, toolkit, or libraries used.</p>
</blockquote>
<h3 id="buildingandrunning">Building and Running</h3>
<p>Hit the green play button and your project will build and run!</p>
<p>You will now see a blank window similar to this:<br>
<img src="https://qml.guide/content/images/2017/12/Screen-Shot-2017-12-27-at-8.52.39-PM.png" alt="Getting started with QML and QtQuick"></p>
<h2 id="qtquickbasicelements">QtQuick - Basic Elements</h2>
<p>QML is a language, QtQuick is a UI framework built on top of Qt in the QML language.</p>
<p><strong><em>Item</em></strong> - This element is the absolute basic element. It is a pure <a href="https://doc-snapshots.qt.io/qt5-5.9/qquickitem.html">QQuickItem</a> with no visible or drawn pixels. Every QML element extends the Item element. I generally use this element as a wrapper element for pages, screens, dialogs, etc. It's generally preferred for structures over the Rectangle element due to it's undrawn and invisible nature.</p>
<p><code>anchors</code> is a object property of Item that allows you to position any Item-derived element relative to any other Item-derived element. This is one of the greatest features of QML when designing GUIs for multiple resolution.</p>
<p><em><strong>Rectangle</strong></em> - This element is basically an Item element with a colored fill. It is possible to have an uncolored Rectangle by using <code>color: &quot;transparent&quot;</code> as a property. Again, Item is usually preferred to a Rectangle due to this colored fill. It is more efficient to use an Item as a wrapper as it reduces the number of pixels required to be drawn; especially on GL graphics views where the entire screen is repainted when one pixel is changed.</p>
<p>Another advantage of the Rectangle element over the Item element is that it contains a border property. This can prove useful when one requires other items, such as Images, to be surrounded by a colored border of variable width. See more properties of Rectangle in the <a href="https://doc-snapshots.qt.io/qt5-5.9/qml-qtquick-rectangle.html">Qt Documentation</a>.</p>
<p><em><strong>Image</strong></em> - This element is used to load an image, from a local file or from a URL. It is important to understand the <code>asynchronous</code> property of the Image element. By default, if your <code>source</code> is a local file, <code>asynchronous: false</code> is default. If your source is a network file (indicated by the http search path), <code>asynchronous: true</code> would be the default.</p>
<p>This is an important consideration when building GUIs with image-based structures, or GUIs that rely on the width/height of the image that's expected to be loaded. We'll go over more of this later on in this guide. View the Qt documentation for more helpful properties of the Image element.</p>
<p><em><strong>BorderImage</strong></em> - This element is great for using one graphic at multiple width/height scenarios. This is very similar to <a href="https://developer.android.com/studio/write/draw9patch.html">Android's 9-patch</a> image drawing mechanism  – with the main difference being the BorderImage only allows for <em>one</em> stretchable zone in the x or y direction. Android's 9-patch allows for multiple stretch zones.</p>
<p>A Qt port is available in QtQuick Controls in the Android style <a href="http://code.qt.io/cgit/qt/qtquickcontrols.git/tree/src/controls/Styles/Android/qquickandroid9patch.cpp">here</a>.</p>
<p>This element is very useful when building different sized buttons with the same graphic. View the Qt documentation for several visual examples.</p>
<p><em><strong>Gradient</strong></em> - This element draws a color-blend (gradient). It can be assigned to the gradient property of Rectangle.</p>
<p><em><strong>Text</strong></em> - This element is the preferred choice when displaying text on a GUI. This element accepts HTML as an input to the text property. This will prove useful when you need to bold or italicize only parts of text; for example, <code>text: &quot;&lt;b&gt;Name:&lt;/b&gt;John Doe&quot;</code>. You will need to consider alignment whenever using the Text element. Lucky for us, the guys at Qt developed a very intuitive method of aligning any piece of text.</p>
<p>Here're a couple examples you can refer to when dealing with text:<br>
<img src="https://qml.guide/content/images/2017/12/text-information.png" alt="Getting started with QML and QtQuick"></p>
<p>When dealing with paragraphs of text, <code>maximumLineCount</code>, <code>wrapMode</code>, and <code>elide</code> will prove immensely useful.</p>
<p>Combining a Text element with a Flickable element can give you a neat panning effect for scrollable Text views. Just set the Flickable's <code>contentWidth</code> and <code>contentHeight</code> to the Text element's <code>paintedWidth</code> and <code>paintedHeight</code> respectively.</p>
<p><em><strong>TextEdit</strong></em> - This element can be used to provide keyboard input into your GUI. I prefer using a heavily modified Text element to achieve this task when using a touchscreen device as this element doesn't provide the flexibility in alignment and fill as the Text element. View more information about TextEdit in the <a href="http://doc.qt.io/qt-5/qml-qtquick-textedit.html">Qt Documentation</a>.</p>
<p><em><strong>MouseArea</strong></em> - This element allows hitareas to be placed in your GUIs. This element (using <code>anchors</code>) can fill every Item-derived element with a hitarea. It is generally acceptable to subclass the basic MouseArea element with a MouseArea element that contains <code>anchors.fill: parent</code> as the MouseArea must know who to apply the hitarea to; in more cases than not, the MouseArea will fill it's parent.</p>
<p>The Qt MouseEvent system employs three crucial mouse events; including press, release, and click. A click is always built of one press and one release. Mouse events always follow this order: press, release, click. A click is only achieved if the press and release occur on the same MouseArea.</p>
<p>This is an important concept when building GUIs for touchscreen devices where a user may accidentally &quot;press&quot; a button, but &quot;release&quot; over another part of the GUI. This will have no effect on the GUI as the click event will not be created. This allows the user to change their mind while navigating a GUI.</p>
<p>Also, when building GUIs for touchscreens, one must take into consideration the touch resolution of the touchscreen. If a resistive touchscreen is used, accuracy can be within ~20%. By increasing the size of the mousearea relative to the button it is covering, can allow a more user-friendly experience. To do this, use anchors.centerIn: parent assuming the parent is the button. Then, set the width and height of the MouseArea to 1.5x the width and height of the intended button target.</p>
<p>The MouseArea element also contains several drag properties to allow dragging of any Item-derived element across a screen. This is particularly tricky as you would have to implement a position persisting mechanism to triumph the deletion of any QML components. Read more about the MouseArea in the <a href="http://doc.qt.io/qt-5/qml-qtquick-mousearea.html">Qt Documentation</a>.</p>
<h2 id="qtquickviewelements">QtQuick View Elements</h2>
<p>View elements in QtQuick strictly adhere to the model-view paradigm in that each View element we cover in this section has a <code>model</code> and a <code>delegate</code> property.</p>
<p>The <code>model</code> can be a <a href="http://doc.qt.io/qt-5/qml-qtqml-models-listmodel.html">ListModel</a>, <a href="http://doc.qt.io/qt-5/qml-qtquick-xmllistmodel-xmllistmodel.html">XmlListModel</a>, <a href="http://doc.qt.io/qt-5/qabstractlistmodel.html">QAbstractListModel</a>, a QList of QObjects, a QStringList, and several other Javascript-based data structures. See <a href="http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html">here</a> for more information about data models.</p>
<p>The <code>delegate</code> is generally a Component-based object that you would like to repeat. For a list view of text, this would be a rectangle with text in it. For a coverflow-esque carousel, this would be an image. Components are useful in low-resource environments as they're not instantiated until needed.</p>
<p><em><strong>ListView</strong></em> - This element is useful in creating lists or carousels of objects. The <code>ListView</code> element does not allow a repeating or circular carousel. The <code>ListView</code> element can be positioned horizontally or vertically using the <code>orientation</code> property.</p>
<p><code>ListView</code> inherits <code>Flickable</code>; allowing developers to modify the <code>contentX</code> and <code>contentY</code> of the element.</p>
<p><img src="https://qml.guide/content/images/2017/12/listview-1.png" alt="Getting started with QML and QtQuick"></p>
<p><img src="https://qml.guide/content/images/2017/12/listview-2.png" alt="Getting started with QML and QtQuick"></p>
<p><em><strong>PathView</strong></em> - This element is useful in creating more customized carousels of objects. The <code>PathView</code> includes an additional <code>path</code> property and a <code>pathItemCount</code> property that allows you to set the track on which the objects move around the view. The <code>PathView</code> is always a repeating or circular view. The <code>PathView</code> element can be positioned horizontally, vertically, diagonally, along any axis using the path property with the <code>Path</code> element. The <code>PathAttribute</code> property helps add different attributes for objects on different parts of the path make the <code>PathView</code> one of the most flexible views available in QtQuick.</p>
<p><code>PathView</code> does not inherit <code>Flickable</code>. If you're trying to modify the position of an item along a <code>PathView</code>, consider the <code>highlightRangeMode</code> by modifying the <code>preferredHighlightBegin</code> and the <code>preferredHighlightEnd</code> of your <code>PathView</code>.</p>
<p>The choice between a <code>ListView</code> element and a <code>PathView</code> element for your next carousel or list relies on one simple fact: Does your view need to repeat? If so, you need a <code>PathView</code>. Does your view require non-straight paths? If so, you need a <code>PathView</code>.</p>
<p><img src="https://qml.guide/content/images/2017/12/pathview-1.png" alt="Getting started with QML and QtQuick"></p>
<p><em><strong>GridView</strong></em> - This element is useful in creating grids of objects. <code>GridView</code> relies on two important properties, <code>cellWidth</code> and <code>cellHeight</code> to properly calculate the size of each object's wrapper. The component delegate would be placed within this cell.</p>
<p><code>GridView</code> also inherits <code>Flickable</code>; allowing developers to modify the <code>contentX</code> and <code>contentY</code> of the element.</p>
<p><img src="https://qml.guide/content/images/2017/12/gridview-1.png" alt="Getting started with QML and QtQuick"></p>
</div>]]></content:encoded></item><item><title><![CDATA[Singletons]]></title><description><![CDATA[The Singleton design pattern is a useful software design pattern for Qt/QML applications that need access to certain services or logic-heavy backend components.]]></description><link>https://qml.guide/singletons/</link><guid isPermaLink="false">5a3da03c2a1b5f0cf716c7ae</guid><category><![CDATA[singleton]]></category><category><![CDATA[singletons]]></category><category><![CDATA[data]]></category><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Wed, 27 Dec 2017 23:11:09 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1498420459002-ab35d585c163?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=8f07c1bc62dd3e09738500edbc0950a2" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><h2 id="designpatternsingletons">Design Pattern: Singletons</h2>
<img src="https://images.unsplash.com/photo-1498420459002-ab35d585c163?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=8f07c1bc62dd3e09738500edbc0950a2" alt="Singletons"><p>The <em>Singleton</em> design pattern is a useful software design pattern for Qt/QML applications that need access to certain services or logic-heavy backend components.</p>
<p>My favorite explanation of the problem solved by the singleton design pattern:</p>
<blockquote>
<p><em>The application needs one, and only one, instance of an object. Additionally, lazy initialization and global access are necessary.</em><br>
<strong><em>By <a href="https://sourcemaking.com/designpatterns/singleton">SourceMaking</a>.</em></strong></p>
</blockquote>
<h2 id="method1exposingaqtcclassasaqmlsingleton">Method 1: Exposing a Qt C++ Class as a QML Singleton</h2>
<p>Qt's preferred way to expose a Qt C++ Class as a QML Singleton is by using <code>qmlRegisterSingletonType</code> which is fairly well <a href="http://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterSingletonType">documented</a>.</p>
<p>This method can be used to register a singleton provider (basically an <code>instance()</code> method with a different signature) of a certain class to a <em>uri</em> which can then be imported in QML through a <code>QQuickExtensionPlugin</code>.</p>
<p>The singleton provider, or instance method, is called by the <code>QQmlEngine</code> when the <em>singleton is first used</em> in QML – and not when the <em>import is first used</em>.</p>
<p>Because of this behavior, it is very difficult to precisely control the instantiation of the singleton object.</p>
<p>In this example, we are using a singleton called <code>Theme</code> to build up a custom <code>Text</code> element:</p>
<pre><code class="language-qml">import QtQuick 2.7
import QmlGuide 1.0

Text {
    font.pixelSize: Theme.adjustedFontSize(24)
    font.family: Theme.fontFamily
}
</code></pre>
<p>The singleton called <code>Theme</code> is under the <code>QmlGuide 1.0</code> import. This import is where we want to register our <code>Theme</code> class:</p>
<pre><code class="language-qml">qmlRegisterSingletonType(&quot;QmlGuide&quot;, 1, 0, &quot;Theme&quot;, Theme::singletonProvider);
</code></pre>
<p>The last argument in the <code>qmlRegisterSingletonType</code> macro is a callback, defined as <code>QObject *(*callback)(QQmlEngine *, QJSEngine *)</code>.</p>
<p>This callback is invoked the first time the <code>Theme</code> singleton is used, i.e. in the example above, the <code>Theme::singletonProvider</code> callback is executed when <code>font.pixelSize</code> is set to <code>Theme.adjustedFontSize(24)</code>.</p>
<p>In this example, the <code>Theme::singletonProvider</code> callback would never be executed, and therefore, the <code>Theme</code> object would never be created, even though <code>import QmlGuide 1.0</code> is specified:</p>
<pre><code class="language-qml">import QtQuick 2.7
import QmlGuide 1.0

Text {

}
</code></pre>
<p>This can potentially lead to dangerous code follies, as the simplest case of a developer <em>logging</em> the <code>Theme</code> object can create the singleton:</p>
<pre><code class="language-qml">import QtQuick 2.7
import QmlGuide 1.0

Text {
    Component.onCompleted: {
        console.log(&quot;Theme: &quot;, Theme);
    }
}
</code></pre>
<p>Generally, once a developer sees the <code>Theme</code> singleton being logged in the example above – they will automatically assume the <code>Theme</code> object is being initialized correctly. However, once the <code>console.log</code> statement is removed, the <code>Theme</code> object is no longer initialized.</p>
<p>For most users, this behavior of <em>extreme</em> lazy instantiation is perfectly okay. For those users who are focused on performance optimization or application start up times, may find this a <a href="https://www.urbandictionary.com/define.php?term=pita"><em>PITA</em></a>.</p>
<h2 id="method2usingtheqmlenginesrootcontexttosetcontextproperties">Method 2: Using the QmlEngine's root context to set context properties</h2>
<p>This method counters method #1 in stating clearly that:</p>
<blockquote>
<p><em>I do not want the QmlEngine to manage my singletons – I will manage them myself.</em></p>
</blockquote>
<p><code>QmlContext</code> allows us to manipulate the <a href="http://doc.qt.io/qt-5/qqmlcontext.html#the-context-hierarchy">context hierarchy</a> of a tree of elements within a QmlEngine.</p>
<p>This feature can be used to add global properties to all QML files within a single <code>QmlEngine</code>. This allows us to replicate the behavior of a <em>singleton</em> by exposing a <code>QmlContext</code> property through the <code>QmlEngine::rootContext</code></p>
<p>In the <code>Theme</code> class, we can define a <code>registerSingleton(..)</code> method:</p>
<pre><code class="language-c++">
...

void Theme::registerSingleton(QQmlEngine *qmlEngine)
{
    if (!s_instance) {
        s_instance = new Theme(qmlEngine);
    }
    QQmlContext *rootContext = qmlEngine-&gt;rootContext();
    rootContext-&gt;setContextProperty(&quot;Theme&quot;, s_instance);
}

...

</code></pre>
<p>Now, in <code>main.cpp</code>, we can invoke this method by passing in a reference to the <code>QQmlEngine</code> object:</p>
<pre><code class="language-c++">#include &lt;QGuiApplication&gt;
#include &lt;QQmlApplicationEngine&gt;

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    Theme::registerSingleton(&amp;engine);

    engine.load(QUrl(QStringLiteral(&quot;qrc:/main.qml&quot;)));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}
</code></pre>
<p>Now, we can use the <code>Theme</code> object in QML:</p>
<pre><code class="language-qml">
...

Text {
    anchors.centerIn: parent
    font.pixelSize: 42
    font.family: Theme.fontFamily

    text: &quot;Hello World&quot;
}
    
...

</code></pre>
<p>Note that the <code>import QmlGuide 1.0</code> statement is no longer necessary as the <code>Theme</code> object was registered to the <code>rootContext</code> of the <code>QQmlEngine</code> which means it is available in all QML files that are built by this <code>QQmlEngine</code>.</p>
<p>As can be seen, the statement:</p>
<pre><code class="language-c++">Theme::registerSingleton(&amp;engine);
</code></pre>
<p>can be invoked in any order the developer sees fit. This helps when tuning an application for startup and even for runtime performance. If a QML developer tries to use the <code>Theme</code> object before it is instantiated, a warning will be output. And as always, warnings guide developers between good practices and evil ones.</p>
<p>Sample code is available in the <a href="https://github.com/ndesai/qml.guide/tree/master/examples/singletons">qml.guide GitHub repository</a>.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Data Models Deconstructed - Part 1: QML / JS Arrays]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Qt provides many different methods of exposing data and using data in QML Model Views, i.e. the <a href="http://doc.qt.io/qt-5/qml-qtquick-listview.html">ListView</a>, <a href="http://doc.qt.io/qt-5/qml-qtquick-pathview.html">PathView</a>, or <a href="http://doc.qt.io/qt-5/qml-qtquick-gridview.html">GridView</a></p>
<p>Over this many part series of posts, we will investigate the many methods of exposing data to QML views – starting from the simplest, to the most complex.</p>
<h6 id="qmljavascriptarray">QML</h6></div>]]></description><link>https://qml.guide/data-models-deconstructed-part-1-qml-js-arrays/</link><guid isPermaLink="false">5a3da03c2a1b5f0cf716c7ad</guid><category><![CDATA[models]]></category><category><![CDATA[data]]></category><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Sat, 11 Mar 2017 04:32:29 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1477244075012-5cc28286e465?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=650281f5f6da101b6954a53645bf6501" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1477244075012-5cc28286e465?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=650281f5f6da101b6954a53645bf6501" alt="Data Models Deconstructed - Part 1: QML / JS Arrays"><p>Qt provides many different methods of exposing data and using data in QML Model Views, i.e. the <a href="http://doc.qt.io/qt-5/qml-qtquick-listview.html">ListView</a>, <a href="http://doc.qt.io/qt-5/qml-qtquick-pathview.html">PathView</a>, or <a href="http://doc.qt.io/qt-5/qml-qtquick-gridview.html">GridView</a></p>
<p>Over this many part series of posts, we will investigate the many methods of exposing data to QML views – starting from the simplest, to the most complex.</p>
<h6 id="qmljavascriptarray">QML / Javascript Array</h6>
<p>The simplest method is using a Javascript array to feed primitive type-based data into a ListView.</p>
<p>All QML delegates inside a model view contain a <code>model</code> property that represents the data for that particular index in the data model array.</p>
<p>In this example, the data model is a JS array – therefore, the data is available directly through the <code>modelData</code> property of the <code>model</code> object.</p>
<p>Qt documentation uses <em>magic</em> to demonstrate this. They use <code>modelData</code> directly <a href="https://code.woboq.org/qt5/qtdeclarative/src/qml/util/qqmladaptormodel.cpp.html#906">since this pointer is available as a context property</a> of the delegate. It is optional to reference the color value using <code>model.modelData</code> but it is more verbose to a bystander reading the code.</p>
<pre><code>import QtQuick 2.5

Item {
    id: root
    
    property var colors: [&quot;red&quot;, &quot;white&quot;, &quot;blue&quot;]

    width: 640; height: 480

    ListView {
        id: _listView
        anchors.fill: parent

        model: root.colors
        delegate: Rectangle {
            id: _rectangleDelegate
            width: ListView.view.width
            height: ListView.view.height / 3
            
            // Use the colors array to change
            // the color of this Rectangle
            color: model.modelData

            // Many times developers misuse
            // model views by accessing the array
            // directly, i.e.
            // color: root.colors[model.index]
            // or
            // color: root.colors[index]
        }
    }
}
</code></pre>
<p><img src="https://qml.guide/content/images/2017/03/Screen-Shot-2017-03-10-at-8.18.19-PM.png" alt="Data Models Deconstructed - Part 1: QML / JS Arrays"></p>
</div>]]></content:encoded></item><item><title><![CDATA[Structure and Scale]]></title><description><![CDATA[<div class="kg-card-markdown"><p>QML has grown to be a fairly unstructured language. It may be due to its heritage as a rapid prototyping language or possibly its javascript lineage.</p>
<p>Because of this, many C++ developers find it difficult to organize QML for scalability.</p>
<p>Here is a coding standard that has evolved over many</p></div>]]></description><link>https://qml.guide/structure-and-scale/</link><guid isPermaLink="false">5a3da03c2a1b5f0cf716c7ac</guid><dc:creator><![CDATA[Niraj Desai]]></dc:creator><pubDate>Mon, 10 Oct 2016 04:35:32 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1492551557933-34265f7af79e?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=505a01f32b7c67692783aca383ee6317" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1492551557933-34265f7af79e?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=505a01f32b7c67692783aca383ee6317" alt="Structure and Scale"><p>QML has grown to be a fairly unstructured language. It may be due to its heritage as a rapid prototyping language or possibly its javascript lineage.</p>
<p>Because of this, many C++ developers find it difficult to organize QML for scalability.</p>
<p>Here is a coding standard that has evolved over many years of QML experience. It provides a well structured approach to creating identifiers for objects as well as a clean hierarchical approach to defining properties.</p>
<p>Let's have a look:</p>
<pre><code class="language-qml">import QtQuick 2.5

Item {
    id: root

    signal clicked
    property alias text: _textButton.text

    function open() { }
    function close() { }

    Rectangle {
        id: _rectangleButton
        anchors.centerIn: parent
        width: 100
        height: 40

        Text {
            id: _textButton
            anchors.fill: parent
            anchors.margins: 4

            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            elideMode: Text.ElideRight
        }

        MouseArea {
            id: _mouseAreaButton
            anchors.fill: parent
            onClicked: { 
                root.clicked();
            }
        }
    }
}
</code></pre>
<hr>
<h6 id="thegeneralrules">The General Rules</h6>
<p><em>Here are a collection of general rules to follow to ensure every developer has equal opportunity for QML code structure and scalability. These techniques work very well in projects ranging from a few lines of code to 100,000+ lines of code.</em></p>
<p><strong>The top-most element of every page must have <code>root</code> as its identifier.</strong></p>
<p>Using <code>root</code> as the identifier creates a known standard for every QML component separated into its own QML file. This speeds up development as the developer knows the root element of a document is identified as <code>root</code>.</p>
<p><strong>All identifiers (with the exception of the root element as well as <code>QtObject</code> elements) must follow this indistinguishable format, <code>_[componentName][componentDescription]</code></strong></p>
<p>Using <code>_[componentName][componentDescription]</code> allows for a clean standardization of element identifiers. It allows a developer to know what type of component they are referencing to. When paired with developer knowledge of the codebase; specifically QML element types, this single guideline can save hours of developer time.</p>
<pre><code class="language-qml">...
Item {
    id: _itemContainer
    // ...
}
...
</code></pre>
<pre><code class="language-qml">...
Button {
    id: _buttonOpenList
    // ...
}
...
</code></pre>
<pre><code class="language-qml">...
ListView {
    id: _listViewAlbums
    // ...
}
...
</code></pre>
<p><strong>Hierarchical Order of Declarations</strong></p>
<p>A common hierarchy promotes code sustainability and clarity. This guideline is similar to a Q_PROPERY/public/private/protected/signals/slots hierarchy in C++.</p>
<pre><code class="language-qml">// Qt imports first, then custom imports
import QtQuick 2.5
// Alias Qt imports that are rarely used (that a developer wouldn't understand)
import QtGraphicalEffects 1.0 as QGE

import custom.import 1.0

</code></pre>
</div>]]></content:encoded></item></channel></rss>