Sophie

Sophie

distrib > Mageia > 7 > armv7hl > media > core-release > by-pkgid > c61c536f80c3d067f7ca643389c560f9 > files > 45

qtremoteobjects5-doc-5.12.2-2.mga7.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- remoteobjects-repc.qdoc -->
  <title>Qt Remote Objects Compiler | Qt Remote Objects 5.12.2</title>
  <link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
  <script type="text/javascript">
    document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
    // loading style sheet breaks anchors that were jumped to before
    // so force jumping to anchor again
    setTimeout(function() {
        var anchor = location.hash;
        // need to jump to different anchor first (e.g. none)
        location.hash = "#";
        setTimeout(function() {
            location.hash = anchor;
        }, 0);
    }, 0);
  </script>
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="main">
    <div class="main-rounded">
      <div class="navigationbar">
        <table><tr>
<td >Qt 5.12</td><td ><a href="qtremoteobjects-index.html">Qt Remote Objects</a></td><td >Qt Remote Objects Compiler</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right"><a href="qtremoteobjects-index.html">Qt 5.12.2 Reference Documentation</a></td>
        </tr></table>
      </div>
    </div>
<div class="content">
<div class="line">
<div class="content mainContent">
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#repc-overview">REPC Overview</a></li>
<li class="level1"><a href="#the-rep-file-format">The rep file format</a></li>
<li class="level2"><a href="#the-class-type">The class type</a></li>
<li class="level2"><a href="#the-pod-type">The POD type</a></li>
<li class="level2"><a href="#the-enum-type">The ENUM type</a></li>
<li class="level2"><a href="#use-enum-keyword">USE_ENUM keyword</a></li>
<li class="level2"><a href="#directives">Directives</a></li>
<li class="level1"><a href="#qmake-variables">qmake variables</a></li>
<li class="level2"><a href="#repc-replica">REPC_REPLICA</a></li>
<li class="level2"><a href="#repc-source">REPC_SOURCE</a></li>
<li class="level2"><a href="#repc-merged">REPC_MERGED</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Qt Remote Objects Compiler</h1>
<span class="subtitle"></span>
<!-- $$$qtremoteobjects-repc.html-description -->
<div class="descr"> <a name="details"></a>
<a name="repc-overview"></a>
<h2 id="repc-overview">REPC Overview</h2>
<p>The <u>Rep</u>lica <u>C</u>ompiler (repc) generates QObject header files based on an API definition file. The file (called a &quot;rep&quot; file) uses a specific (text) syntax to describe the API. By convention, these files are given a .rep file extension, short for Replica. When these files are processed by repc, repc generates both <a href="qtremoteobjects-source.html#source">Source</a> and <a href="qtremoteobjects-replica.html#replica">Replica</a> header files.</p>
<p>The Qt Remote Objects module also includes qmake variables (<a href="qtremoteobjects-repc.html#repc-source">REPC_SOURCE</a>, <a href="qtremoteobjects-repc.html#repc-replica">REPC_REPLICA</a>, and <a href="qtremoteobjects-repc.html#repc-merged">REPC_MERGED</a>) that can be added to your project file to automatically run repc, and add the resulting files to the list of files processed by Meta Object Compiler during the build process, making use of Qt Remote Objects in your projects simple.</p>
<p>While Qt Remote Objects supports sharing any QObject over the network (using enableRemoting on the Source side and acquireDynamic on the Replica side), there are a couple of advantages to letting repc define your objects. First of all, while <a href="qremoteobjectdynamicreplica.html">DynamicReplicas</a> are useful, they are more cumbersome to work with. The API is not known until the object is initialized, and using the API from C++ requires string lookups through QMetaObject's methods. Secondly, having the interface known at compile time finds any issues at compile vs. at runtime. Thirdly, the rep format supports default values, which can be handy if you are unable to ensure the Source is available when the Replica is instantiated.</p>
<p>See the documentation <a href="qtremoteobjects-source.html#source">here</a> for information on using the generated files in your code. Here we will focus on the repc format and options.</p>
<a name="the-rep-file-format"></a>
<h2 id="the-rep-file-format">The rep file format</h2>
<p>The rep file format is a simple <a href="https://en.wikipedia.org/wiki/Domain-specific_language">Domain Specific Language (DSL)</a> for describing an interface supported over Qt Remote Objects (QtRO). Since QtRO is an object based system, these interfaces are defined by APIs available through objects, that is, classes with properties, signals, and slots.</p>
<a name="the-class-type"></a>
<h3 >The class type</h3>
<p>Each class defined in a rep file becomes a QObject in the generated header files, with the described API generated for you.</p>
<p>To define a class use the <code>class</code> keyword, followed by the name you want for your type, and then enclose your API in brackets like so</p>
<pre class="cpp">

  <span class="keyword">class</span> MyType
  {
      <span class="comment">//PROP/SIGNAL/SLOT/ENUM declarations to define your API</span>
  };

</pre>
<a name="prop"></a>
<h4 >PROP</h4>
<p>Q_PROPERTY elements are created by using the PROP keyword in the rep file. The syntax is the <code>PROP</code> keyword followed by the definition enclosed in parentheses, where the definition is the type, the name, and (optionally) a default value or attributes.</p>
<pre class="cpp">

  PROP(bool simpleBool)                <span class="comment">// boolean named simpleBool</span>
  PROP(bool defaultFalseBool<span class="operator">=</span><span class="keyword">false</span>)    <span class="comment">// boolean named defaultFalseBool, with false</span>
                                       <span class="comment">// as the default value</span>

  PROP(<span class="type">int</span> lifeUniverseEverything<span class="operator">=</span><span class="number">42</span>)  <span class="comment">// int value that defaults to 42</span>
  PROP(<span class="type">QByteArray</span> myBinaryInfo)        <span class="comment">// Qt types are fine, may need #include</span>
                                       <span class="comment">// additional headers in your rep file</span>

  PROP(<span class="type">QString</span> name CONSTANT)          <span class="comment">// Property with the CONSTANT attribute</span>
  PROP(<span class="type">QString</span> setable READWRITE)      <span class="comment">// Property with the READWRITE attribute</span>
                                       <span class="comment">// note: Properties default to READPUSH</span>
                                       <span class="comment">// (see description below)</span>

  PROP(SomeOtherType myCustomType)     <span class="comment">// Custom types work. Needs #include for the</span>
                                       <span class="comment">// appropriate header for your type, make</span>
                                       <span class="comment">// sure your type is known to the metabject</span>
                                       <span class="comment">// system, and make sure it supports Queued</span>
                                       <span class="comment">// Connections (see Q_DECLARE_METATYPE and</span>
                                       <span class="comment">// qRegisterMetaType)</span>

</pre>
<p>More information about creating custom types can be found here.</p>
<p>By default, properties will have getters and a &quot;push&quot; slot defined, as well as a notify signal emitted when the value is changed. Qt Remote Objects requires the notify signal on the Source object to trigger sending updates to the attached Replicas. In earlier versions of QtRO, properties defaulted to being read/write, that is, having getters and setters. However, due to the asynchronous nature of QtRO, this led to unintuitive behavior at times. Setting the READWRITE attribute on the PROP will provide the old (getter and setter) behavior.</p>
<pre class="cpp">

  <span class="comment">// In .rep file, old (setter) behavior</span>
  PROP(<span class="type">int</span> myVal READWRITE)             <span class="comment">// Old behavior with setMyVal(int myVal) method</span>

  <span class="comment">// In code...  Assume myVal is initially set to 0 in Source</span>
  <span class="type">int</span> originalValue <span class="operator">=</span> rep<span class="operator">-</span><span class="operator">&gt;</span>myVal();     <span class="comment">// Will be 0</span>
  rep<span class="operator">-</span><span class="operator">&gt;</span>setMyVal(<span class="number">10</span>);                    <span class="comment">// Call setter, expecting a blocking/</span>
                                        <span class="comment">// non-asynchronous return</span>

  <span class="keyword">if</span> (rep<span class="operator">-</span><span class="operator">&gt;</span>myVal() <span class="operator">=</span><span class="operator">=</span> <span class="number">10</span>) <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>           <span class="comment">// Test will usually fail</span>

</pre>
<p>If it is necessary to block until the value is changed, something like the following is necessary.</p>
<pre class="cpp">

  <span class="comment">// In .rep file, old (setter) behavior</span>
  PROP(<span class="type">int</span> myVal READWRITE)             <span class="comment">// Old behavior with setMyVal(int myVal) method</span>

  <span class="comment">// In code...  Assume myVal is initially set to 0 in Source</span>
  bool originalValue <span class="operator">=</span> rep<span class="operator">-</span><span class="operator">&gt;</span>myVal();    <span class="comment">// Will be 0</span>

  <span class="comment">// We can wait for the change using \l QSignalSpy</span>
  <span class="type">QSignalSpy</span> spy(rep<span class="operator">,</span> SIGNAL(myValChanged(<span class="type">int</span>)));

  rep<span class="operator">-</span><span class="operator">&gt;</span>setMyVal(<span class="number">10</span>);                    <span class="comment">// Call setter, expecting a blocking/</span>
                                        <span class="comment">// non-asynchronous return</span>

  spy<span class="operator">.</span>wait();                           <span class="comment">// spy.wait() blocks until changed signal</span>
                                        <span class="comment">// is received</span>
  <span class="keyword">if</span> (rep<span class="operator">-</span><span class="operator">&gt;</span>myVal() <span class="operator">=</span><span class="operator">=</span> <span class="number">10</span>) <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>           <span class="comment">// Test will succeed assuming</span>
                                        <span class="comment">// 1. Source object is connected</span>
                                        <span class="comment">// 2. Nobody else (Source or other Replica)</span>
                                        <span class="comment">//    sets the myVal to something else (race</span>
                                        <span class="comment">//    condition)</span>
  <span class="comment">// Rather than use QSignalSpy, the event-driven practice would be to connect the</span>
  <span class="comment">// myValChanged notify signal to a slot that responds to the changes.</span>

</pre>
<p>QtRO now defaults to READPUSH, which provides an automatically generated slot for requesting a property change.</p>
<pre class="cpp">

  <span class="comment">// In .rep file, defaults to READPUSH</span>
  PROP(bool myVal)                      <span class="comment">// No setMyVal(int myVal) on Replica, has</span>
                                        <span class="comment">// pushMyVal(int myVal) instead</span>

  <span class="comment">// In code...  Assume myVal is initially set to 0 in Source</span>
  bool originalValue <span class="operator">=</span> rep<span class="operator">-</span><span class="operator">&gt;</span>myVal();    <span class="comment">// Will be 0</span>

  <span class="comment">// We can wait for the change using \l QSignalSpy</span>
  <span class="type">QSignalSpy</span> spy(rep<span class="operator">,</span> SIGNAL(myValChanged(<span class="type">int</span>)));

  rep<span class="operator">-</span><span class="operator">&gt;</span>pushMyVal(<span class="number">10</span>);                   <span class="comment">// Call push method, no expectation that change</span>
                                        <span class="comment">// is applied upon method completion.</span>

  <span class="comment">// Some way of waiting for change to be received by the Replica is still necessary,</span>
  <span class="comment">// but hopefully not a surprise with the new pushMyVal() Slot.</span>
  spy<span class="operator">.</span>wait();                           <span class="comment">// spy.wait() blocks until changed signal</span>
                                        <span class="comment">// is received</span>
  <span class="keyword">if</span> (rep<span class="operator">-</span><span class="operator">&gt;</span>myVal() <span class="operator">=</span><span class="operator">=</span> <span class="number">10</span>) <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>           <span class="comment">// Test will succeed assuming</span>
                                        <span class="comment">// 1. Source object is connected</span>
                                        <span class="comment">// 2. Nobody else (Source or other Replica)</span>
                                        <span class="comment">//    set the myVal to something else (race</span>
                                        <span class="comment">//    condition)</span>

</pre>
<p>You can also use the <code>CONSTANT</code>, <code>READONLY</code>, <code>PERSISTED</code>, <code>READWRITE</code>, <code>READPUSH</code>, or <code>SOURCEONLYSETTER</code> keywords in the PROP declaration, which affects how the property is implemented. READPUSH is the default value if no value used.</p>
<pre class="cpp">

  PROP(<span class="type">int</span> lifeUniverseEverything<span class="operator">=</span><span class="number">42</span> CONSTANT)
  PROP(<span class="type">QString</span> name READONLY)

</pre>
<p>Please note there are some subtleties here. A CONSTANT PROP has a Q_PROPERTY declared as CONSTANT on the SOURCE side. However, replicas cannot know the correct value until they are initialized, which means the property value has to be allowed to change during initialization. For READONLY, the source will have neither a setter nor a push slot, and the replica side will not have a push slot generated. Adding the PERSISTED trait to a PROP will have the PROP use the <a href="qremoteobjectabstractpersistedstore.html">QRemoteObjectAbstractPersistedStore</a> instance set on a Node (if any) to save/restore PROP values.</p>
<p>Another nuanced value is SOURCEONLYSETTER, which provides another way of specifying asymmetric behavior, where the <a href="qtremoteobjects-source.html#source">Source</a> (specifically the helper class, <code>SimpleSource</code>) will have a public getter and setter for the property, but it will be ReadOnly (with a notify signal) on the <a href="qtremoteobjects-replica.html#replica">Replica</a> side. Thus the property can be fully controlled from the <a href="qtremoteobjects-source.html#source">Source</a> side, but only observed from the <a href="qtremoteobjects-replica.html#replica">Replica</a> side. SOURCEONLYSETTER is the mode used by repc for MODEL and CLASS instances, meaning the <a href="qtremoteobjects-source.html#source">Source</a> can change the pointed to object, but the <a href="qtremoteobjects-replica.html#replica">Replica</a> can not provide a new object, as no set&lt;Prop&gt; or push&lt;Prop&gt; method is generated. Note, this does not impact the behavior of the pointed to type's properties, just the ability to change the pointer itself.</p>
<a name="signal"></a>
<h4 >SIGNAL</h4>
<p>Signal methods are created by using the SIGNAL keyword in the rep file.</p>
<p>Usage is to declare <code>SIGNAL</code> followed by the desired signature wrapped in parentheses. The void return value should be skipped.</p>
<pre class="cpp">

  SIGNAL(test())
  SIGNAL(test(<span class="type">QString</span> foo<span class="operator">,</span> <span class="type">int</span> bar))
  SIGNAL(test(<span class="type">QMap</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> foo))
  SIGNAL(test(<span class="keyword">const</span> <span class="type">QString</span> <span class="operator">&amp;</span>foo))
  SIGNAL(test(<span class="type">QString</span> <span class="operator">&amp;</span>foo))

</pre>
<p>Just like in Qt queued connections, parameters in signals that are references will be copied when being passed to replicas.</p>
<a name="slot"></a>
<h4 >SLOT</h4>
<p>Slot methods are created by using the SLOT keyword in the rep file.</p>
<p>Usage is to declare <code>SLOT</code> followed by the desired signature wrapped in parentheses. The return value can be included in the declaration. If the return value is skipped, void will be used in the generated files.</p>
<pre class="cpp">

  SLOT(test())
  SLOT(<span class="type">void</span> test(<span class="type">QString</span> foo<span class="operator">,</span> <span class="type">int</span> bar))
  SLOT(test(<span class="type">QMap</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> foo))
  SLOT(test(<span class="type">QMap</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> foo<span class="operator">,</span> <span class="type">QMap</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> bar))
  SLOT(test(<span class="type">QMap</span><span class="operator">&lt;</span><span class="type">QList</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">&gt;</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> foo))
  SLOT(test(<span class="keyword">const</span> <span class="type">QString</span> <span class="operator">&amp;</span>foo))
  SLOT(test(<span class="type">QString</span> <span class="operator">&amp;</span>foo))
  SLOT(test(<span class="keyword">const</span> <span class="type">QMap</span><span class="operator">&lt;</span><span class="type">QList</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">&gt;</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> <span class="operator">&amp;</span>foo))
  SLOT(test(<span class="keyword">const</span> <span class="type">QString</span> <span class="operator">&amp;</span>foo<span class="operator">,</span> <span class="type">int</span> bar))

</pre>
<p>Just like in Qt queued connections and QtRO SIGNALS, parameters in slots that are references will be copied when being passed to Replicas.</p>
<a name="enum"></a>
<h4 >ENUM</h4>
<p>Enumerations (which use a combination of C++ enum and Qt's Q_ENUM in QtRO) are described using the ENUM keyword.</p>
<pre class="cpp">

  ENUM MyEnum {Foo}
  ENUM MyEnum {Foo<span class="operator">,</span> Bar}
  ENUM MyEnum {Foo<span class="operator">,</span> Bar <span class="operator">=</span> <span class="operator">-</span><span class="number">1</span>}
  ENUM MyEnum {Foo<span class="operator">=</span><span class="operator">-</span><span class="number">1</span><span class="operator">,</span> Bar}
  ENUM MyEnum {Foo<span class="operator">=</span><span class="number">0xf</span><span class="operator">,</span> Bar}
  ENUM MyEnum {Foo<span class="operator">=</span><span class="number">1</span><span class="operator">,</span> Bar<span class="operator">=</span><span class="number">3</span><span class="operator">,</span> Bas<span class="operator">=</span><span class="number">5</span>}

</pre>
<p>Related topics: <a href="qtremoteobjects-repc.html#the-enum-type">The ENUM type</a>, <a href="qtremoteobjects-repc.html#use-enum-keyword">USE_ENUM keyword</a></p>
<a name="the-pod-type"></a>
<h3 >The POD type</h3>
<p>Plain Old Data (POD) is a term to describe a simple data collection, along the lines of a C++ struct. For example, if you have an API for a phonebook, you may want to use the concept of an &quot;address&quot; in its interface (where address might include street, city, state, country, and postal code). You can use the POD keyword to define objects like this, which can then be used by in PROP/SIGNAL/SLOT definitions in your class definitions.</p>
<p>Usage is to declare <code>POD</code> followed by the name for the generated type, followed by type and name pairs separated by commas, where the type/name pairs are wrapped in parentheses.</p>
<pre class="cpp">

  POD Foo(<span class="type">int</span> bar)
  POD Foo(<span class="type">int</span> bar<span class="operator">,</span> <span class="type">double</span> bas)
  POD Foo(<span class="type">QMap</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> bar)
  POD Foo(<span class="type">QList</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">&gt;</span> bar)
  POD Foo(<span class="type">QMap</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> bar<span class="operator">,</span> <span class="type">QMap</span><span class="operator">&lt;</span><span class="type">double</span><span class="operator">,</span><span class="type">int</span><span class="operator">&gt;</span> bas)

</pre>
<p>A full example would look like this</p>
<pre class="cpp">

  POD Foo(<span class="type">QList</span><span class="operator">&lt;</span><span class="type">QString</span><span class="operator">&gt;</span> bar)
  <span class="keyword">class</span> MyType
  {
      SIGNAL(sendCustom(Foo foo));
  };

</pre>
<p>The code generated by repc creates a Q_GADGET class for each POD, with corresponding Q_PROPERTY members for each type defined for the POD.</p>
<a name="the-enum-type"></a>
<h3 >The ENUM type</h3>
<p>It is often easier and cleaner to define an ENUM inside a class (see <a href="qtremoteobjects-repc.html#enum">ENUM</a>), but if you need a standalone enum type, using the ENUM keyword outside of a class definition can be helpful. This will generate a new class in your header files that handles marshalling, etc.. The syntax is identical to <a href="qtremoteobjects-repc.html#enum">ENUM</a>, with the exception that the declaration in this case is not contained in a <code>class</code> declaration.</p>
<p>Related topics: <a href="qtremoteobjects-repc.html#enum">ENUM</a>, <a href="qtremoteobjects-repc.html#use-enum-keyword">USE_ENUM keyword</a></p>
<a name="use-enum-keyword"></a>
<h3 >USE_ENUM keyword</h3>
<p>The USE_ENUM keyword was implemented before autogeneration via the ENUM keyword was added. It is kept for backwards compatibility.</p>
<p>Related topics: <a href="qtremoteobjects-repc.html#enum">ENUM</a>, <a href="qtremoteobjects-repc.html#the-enum-type">The ENUM type</a></p>
<a name="directives"></a>
<h3 >Directives</h3>
<p>The rep file defines an interface, but interfaces often require external elements. In order to support this, repc will include any (single line) directives at the top of the generated files. This allows you to, for instance, use #include or #define directives that support the logic or datatypes needed.</p>
<p>The repc tool currently ignores everything from the &quot;#&quot; symbol to the end-of-line and adds that to the generated files. So multi-line #if/#else/#endif statements and multi-line macros are not supported.</p>
<a name="qmake-variables"></a>
<h2 id="qmake-variables">qmake variables</h2>
<a name="repc-replica"></a>
<h3 >REPC_REPLICA</h3>
<p>Specifies the names of all rep files in the project that should be used to generate replica header files.</p>
<p>For example:</p>
<pre class="cpp">

  REPC_REPLICA <span class="operator">=</span> media<span class="operator">.</span>rep \
                 location<span class="operator">.</span>rep

</pre>
<p>The generated file(s) will be of the form <code>rep_&lt;replica file base&gt;_replica.h</code>.</p>
<a name="repc-source"></a>
<h3 >REPC_SOURCE</h3>
<p>Specifies the names of all rep files in the project that should be used to generate source header files.</p>
<p>For example:</p>
<pre class="cpp">

  REPC_SOURCE <span class="operator">=</span> media<span class="operator">.</span>rep \
                location<span class="operator">.</span>rep

</pre>
<p>The generated file(s) will be of the form <code>rep_&lt;replica file base&gt;_source.h</code>.</p>
<a name="repc-merged"></a>
<h3 >REPC_MERGED</h3>
<p>Specifies the names of all rep files in the project that should be used to generate combined (source and replica) header files.</p>
<p>For example:</p>
<pre class="cpp">

  REPC_MERGED <span class="operator">=</span> media<span class="operator">.</span>rep \
                location<span class="operator">.</span>rep

  The generated file(s) will be of the form \c {rep_<span class="operator">&lt;</span>replica file base<span class="operator">&gt;</span>_merged<span class="operator">.</span>h}<span class="operator">.</span>

  \note Typically sources and replicas live in separate processes <span class="keyword">or</span> devices<span class="operator">,</span> so <span class="keyword">this</span> variable
  is <span class="keyword">not</span> commonly used<span class="operator">.</span>

</pre>
<p><b class="redFont"><code>\section</code></b>2 QOBJECT_REP</p>
<p>Specifies the names of existing QObject header files that should be used to generate corresponding .rep files.</p>
</div>
<p><b>See also </b><a href="qremoteobjectabstractpersistedstore.html">QRemoteObjectAbstractPersistedStore</a>.</p>
<!-- @@@qtremoteobjects-repc.html -->
        </div>
       </div>
   </div>
   </div>
</div>
<div class="footer">
   <p>
   <acronym title="Copyright">&copy;</acronym> 2019 The Qt Company Ltd.
   Documentation contributions included herein are the copyrights of
   their respective owners.<br/>    The documentation provided herein is licensed under the terms of the    <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation    License version 1.3</a> as published by the Free Software Foundation.<br/>    Qt and respective logos are trademarks of The Qt Company Ltd.     in Finland and/or other countries worldwide. All other trademarks are property
   of their respective owners. </p>
</div>
</body>
</html>