File: src-imports-folderlistmodel.html

package info (click to toggle)
qt4-x11 4%3A4.8.2%2Bdfsg-11
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 701,696 kB
  • sloc: cpp: 2,686,179; ansic: 375,485; python: 25,859; sh: 19,349; xml: 17,091; perl: 14,765; yacc: 5,383; asm: 5,038; makefile: 1,259; lex: 555; ruby: 526; objc: 347; cs: 112; pascal: 112; php: 54; sed: 34
file content (197 lines) | stat: -rw-r--r-- 16,592 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- qml-folderlistmodel.qdoc -->
  <title>Qt 4.8: FolderListModel - a C++ model plugin</title>
  <link rel="stylesheet" type="text/css" href="style/offline.css" />
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="content"> 
    <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
  </div>
  <div class="breadcrumb toolblock">
    <ul>
      <li class="first"><a href="index.html">Home</a></li>
      <!--  Breadcrumbs go here -->
<li><a href="all-examples.html">Examples</a></li>
<li>FolderListModel - a C++ model plugin</li>
    </ul>
  </div>
</div>
<div class="content mainContent">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#usage-from-qml">Usage from QML</a></li>
<li class="level1"><a href="#defining-the-model">Defining the Model</a></li>
<li class="level1"><a href="#connecting-the-model-to-qml">Connecting the Model to QML</a></li>
<li class="level1"><a href="#implementing-the-model">Implementing the Model</a></li>
</ul>
</div>
<h1 class="title">FolderListModel - a C++ model plugin</h1>
<span class="subtitle"></span>
<!-- $$$src/imports/folderlistmodel-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="src-imports-folderlistmodel-plugin-cpp.html">src/imports/folderlistmodel/plugin.cpp</a></li>
<li><a href="src-imports-folderlistmodel-qdeclarativefolderlistmodel-cpp.html">src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp</a></li>
<li><a href="src-imports-folderlistmodel-qdeclarativefolderlistmodel-h.html">src/imports/folderlistmodel/qdeclarativefolderlistmodel.h</a></li>
<li><a href="src-imports-folderlistmodel-folderlistmodel-pro.html">src/imports/folderlistmodel/folderlistmodel.pro</a></li>
<li><a href="src-imports-folderlistmodel-qmldir.html">src/imports/folderlistmodel/qmldir</a></li>
</ul>
<p>The <a href="qml-folderlistmodel.html">FolderListModel</a> plugin example shows how to make a C++ model available to QML.<p>It presents a simple file list for a single folder (directory) and allows the presented folder to be changed.</p>
<p class="centerAlign"><img src="images/declarative-folderlistmodel.png" alt="The FolderListModel used to choose a QML file" /></p><p>We do not explain the model implementation in detail, but rather focus on the mechanics of making the model available to QML.</p>
<a name="usage-from-qml"></a>
<h2>Usage from QML</h2>
<p>The <a href="qml-folderlistmodel.html">FolderListModel</a> can be used from QML like this:</p>
<pre class="qml"> import QtQuick 1.0
 import Qt.labs.folderlistmodel 1.0

 <span class="type"><a href="qml-listview.html">ListView</a></span> {
     <span class="name">width</span>: <span class="number">200</span>; <span class="name">height</span>: <span class="number">400</span>

     <span class="type"><a href="qml-folderlistmodel.html">FolderListModel</a></span> {
         <span class="name">id</span>: <span class="name">folderModel</span>
         <span class="name">nameFilters</span>: [<span class="string">&quot;*.qml&quot;</span>]
     }

     <span class="type"><a href="qml-component.html">Component</a></span> {
         <span class="name">id</span>: <span class="name">fileDelegate</span>
         <span class="type"><a href="qml-text.html">Text</a></span> { <span class="name">text</span>: <span class="name">fileName</span> }
     }

     <span class="name">model</span>: <span class="name">folderModel</span>
     <span class="name">delegate</span>: <span class="name">fileDelegate</span>
 }</pre>
<p>This displays a list of all subfolders and QML files in the current folder.</p>
<p>The <a href="qml-folderlistmodel.html">FolderListModel</a> <tt>folder</tt> property can be set to change the folder that is currently displayed.</p>
<a name="defining-the-model"></a>
<h2>Defining the Model</h2>
<p>We are subclassing <a href="qabstractlistmodel.html">QAbstractListModel</a> which will allow us to give data to QML and send notifications when the data changes:</p>
<pre class="cpp"> <span class="keyword">class</span> <span class="type">QDeclarativeFolderListModel</span> : <span class="keyword">public</span> <span class="type"><a href="qabstractlistmodel.html">QAbstractListModel</a></span><span class="operator">,</span> <span class="keyword">public</span> <span class="type"><a href="qdeclarativeparserstatus.html">QDeclarativeParserStatus</a></span>
 {
     Q_OBJECT
     Q_INTERFACES(<span class="type"><a href="qdeclarativeparserstatus.html">QDeclarativeParserStatus</a></span>)</pre>
<p>As you see, we also inherit the <a href="qdeclarativeparserstatus.html">QDeclarativeParserStatus</a> interface, so that we can delay initial processing until we have all properties set (via componentComplete() below).</p>
<p>The first thing to do when devising a new type for QML is to define the properties you want the type to have:</p>
<pre class="cpp">     Q_PROPERTY(<span class="type"><a href="qurl.html">QUrl</a></span> folder READ folder WRITE setFolder NOTIFY folderChanged)
     Q_PROPERTY(<span class="type"><a href="qurl.html">QUrl</a></span> parentFolder READ parentFolder NOTIFY folderChanged)
     Q_PROPERTY(<span class="type"><a href="qstringlist.html">QStringList</a></span> nameFilters READ nameFilters WRITE setNameFilters)
     Q_PROPERTY(SortField sortField READ sortField WRITE setSortField)
     Q_PROPERTY(<span class="type">bool</span> sortReversed READ sortReversed WRITE setSortReversed)
     Q_PROPERTY(<span class="type">bool</span> showDirs READ showDirs WRITE setShowDirs)
     Q_PROPERTY(<span class="type">bool</span> showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot)
     Q_PROPERTY(<span class="type">bool</span> showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
     Q_PROPERTY(<span class="type">int</span> count READ count)</pre>
<p>The purposes of each of these should be pretty obvious - in QML we will set the folder to display (a file: URL), and the kinds of files we want to show in the view of the model.</p>
<p>Next are the constructor, destructor, and standard <a href="qabstractlistmodel.html">QAbstractListModel</a> subclassing requirements:</p>
<pre class="cpp"> <span class="keyword">public</span>:
     <span class="type">QDeclarativeFolderListModel</span>(<span class="type"><a href="qobject.html">QObject</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);
     <span class="operator">~</span><span class="type">QDeclarativeFolderListModel</span>();

     <span class="keyword">enum</span> Roles { FileNameRole <span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>UserRole<span class="operator">+</span><span class="number">1</span><span class="operator">,</span> FilePathRole <span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>UserRole<span class="operator">+</span><span class="number">2</span> };

     <span class="type">int</span> rowCount(<span class="keyword">const</span> <span class="type"><a href="qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>parent) <span class="keyword">const</span>;
     <span class="type"><a href="qvariant.html">QVariant</a></span> data(<span class="keyword">const</span> <span class="type"><a href="qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>index<span class="operator">,</span> <span class="type">int</span> role) <span class="keyword">const</span>;</pre>
<p>The data() function is where we provide model values. The rowCount() function is also a standard part of the <a href="qabstractlistmodel.html">QAbstractListModel</a> interface, but we also want to provide a simpler count property:</p>
<pre class="cpp">     <span class="type">int</span> count() <span class="keyword">const</span> { <span class="keyword">return</span> rowCount(<span class="type"><a href="qmodelindex.html">QModelIndex</a></span>()); }</pre>
<p>Then we have the functions for the remaining properties which we defined above:</p>
<pre class="cpp">     <span class="type"><a href="qurl.html">QUrl</a></span> folder() <span class="keyword">const</span>;
     <span class="type">void</span> setFolder(<span class="keyword">const</span> <span class="type"><a href="qurl.html">QUrl</a></span> <span class="operator">&amp;</span>folder);

     <span class="type"><a href="qurl.html">QUrl</a></span> parentFolder() <span class="keyword">const</span>;

     <span class="type"><a href="qstringlist.html">QStringList</a></span> nameFilters() <span class="keyword">const</span>;
     <span class="type">void</span> setNameFilters(<span class="keyword">const</span> <span class="type"><a href="qstringlist.html">QStringList</a></span> <span class="operator">&amp;</span>filters);

     <span class="keyword">enum</span> SortField { Unsorted<span class="operator">,</span> Name<span class="operator">,</span> Time<span class="operator">,</span> Size<span class="operator">,</span> Type };
     SortField sortField() <span class="keyword">const</span>;
     <span class="type">void</span> setSortField(SortField field);
     Q_ENUMS(SortField)

     <span class="type">bool</span> sortReversed() <span class="keyword">const</span>;
     <span class="type">void</span> setSortReversed(<span class="type">bool</span> rev);

     <span class="type">bool</span> showDirs() <span class="keyword">const</span>;
     <span class="type">void</span>  setShowDirs(<span class="type">bool</span>);
     <span class="type">bool</span> showDotAndDotDot() <span class="keyword">const</span>;
     <span class="type">void</span>  setShowDotAndDotDot(<span class="type">bool</span>);
     <span class="type">bool</span> showOnlyReadable() <span class="keyword">const</span>;
     <span class="type">void</span>  setShowOnlyReadable(<span class="type">bool</span>);</pre>
<p>Imperative actions upon the model are made available to QML via a <a href="qobject.html#Q_INVOKABLE">Q_INVOKABLE</a> tag on a normal member function. The isFolder(index) function says whether the value at <i>index</i> is a folder:</p>
<pre class="cpp">     Q_INVOKABLE <span class="type">bool</span> isFolder(<span class="type">int</span> index) <span class="keyword">const</span>;</pre>
<p>Then we have the <a href="qdeclarativeparserstatus.html">QDeclarativeParserStatus</a> interface:</p>
<pre class="cpp">     <span class="keyword">virtual</span> <span class="type">void</span> classBegin();
     <span class="keyword">virtual</span> <span class="type">void</span> componentComplete();</pre>
<p>Then the NOTIFY function for the folders property. The implementation will emit this when the folder property is changed.</p>
<pre class="cpp"> Q_SIGNALS:
     <span class="type">void</span> folderChanged();</pre>
<p>The class ends with some implementation details:</p>
<pre class="cpp"> <span class="keyword">private</span> Q_SLOTS:
     <span class="type">void</span> refresh();
     <span class="type">void</span> inserted(<span class="keyword">const</span> <span class="type"><a href="qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>index<span class="operator">,</span> <span class="type">int</span> start<span class="operator">,</span> <span class="type">int</span> end);
     <span class="type">void</span> removed(<span class="keyword">const</span> <span class="type"><a href="qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>index<span class="operator">,</span> <span class="type">int</span> start<span class="operator">,</span> <span class="type">int</span> end);
     <span class="type">void</span> handleDataChanged(<span class="keyword">const</span> <span class="type"><a href="qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>start<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>end);

 <span class="keyword">private</span>:
     Q_DISABLE_COPY(<span class="type">QDeclarativeFolderListModel</span>)
     <span class="type">QDeclarativeFolderListModelPrivate</span> <span class="operator">*</span>d;
 };</pre>
<p>Lastly, the boilerplare to declare the type for QML use:</p>
<pre class="cpp"> <a href="qdeclarativeengine.html#QML_DECLARE_TYPE">QML_DECLARE_TYPE</a>(<span class="type">QDeclarativeFolderListModel</span>)</pre>
<a name="connecting-the-model-to-qml"></a>
<h2>Connecting the Model to QML</h2>
<p>To make this class available to QML, we only need to make a simple subclass of <a href="qdeclarativeextensionplugin.html">QDeclarativeExtensionPlugin</a>:</p>
<pre class="cpp"> <span class="keyword">class</span> QmlFolderListModelPlugin : <span class="keyword">public</span> <span class="type"><a href="qdeclarativeextensionplugin.html">QDeclarativeExtensionPlugin</a></span>
 {
     Q_OBJECT
 <span class="keyword">public</span>:
     <span class="keyword">virtual</span> <span class="type">void</span> registerTypes(<span class="keyword">const</span> <span class="type">char</span> <span class="operator">*</span>uri)
     {
         Q_ASSERT(QLatin1String(uri) <span class="operator">=</span><span class="operator">=</span> QLatin1String(<span class="string">&quot;Qt.labs.folderlistmodel&quot;</span>));
 <span class="preprocessor">#ifndef QT_NO_DIRMODEL</span>
         qmlRegisterType<span class="operator">&lt;</span><span class="type">QDeclarativeFolderListModel</span><span class="operator">&gt;</span>(uri<span class="operator">,</span><span class="number">1</span><span class="operator">,</span><span class="number">0</span><span class="operator">,</span><span class="string">&quot;FolderListModel&quot;</span>);
 <span class="preprocessor">#endif</span>
     }
 };</pre>
<p>and then use the standard Qt plugin export macro:</p>
<pre class="cpp"> <a href="qtplugin.html#Q_EXPORT_PLUGIN2">Q_EXPORT_PLUGIN2</a>(qmlfolderlistmodelplugin<span class="operator">,</span> QT_PREPEND_NAMESPACE(QmlFolderListModelPlugin));</pre>
<p>Finally, in order for QML to connect the &quot;import&quot; statement to our plugin, we list it in the qmldir file:</p>
<p><a href="src-imports-folderlistmodel-qmldir.html">src/imports/folderlistmodel/qmldir</a></p>
<p>This qmldir file and the compiled plugin will be installed in <tt>$QTDIR/imports/Qt/labs/folderlistmodel/</tt> where the QML engine will find it (since <tt>$QTDIR/imports</tt> is the value of QLibraryInf::libraryPath()).</p>
<a name="implementing-the-model"></a>
<h2>Implementing the Model</h2>
<p>We'll not discuss the model implementation in detail, as it is not specific to QML - any Qt C++ model can be interfaced to QML. This implementation is basically just takes the krufty old <a href="qdirmodel.html" class="obsolete">QDirModel<sup>(obsolete)</sup></a>, which is a tree with lots of detailed roles and re-presents it as a simpler list model where each item is just a fileName and a filePath (as a file: URL rather than a plain file, since QML works with URLs for all content).</p>
<p><a href="src-imports-folderlistmodel-qdeclarativefolderlistmodel-cpp.html">src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp</a></p>
</div>
<!-- @@@src/imports/folderlistmodel -->
  <div class="ft">
    <span></span>
  </div>
</div> 
<div class="footer">
    <p>
      <acronym title="Copyright">&copy;</acronym> 2012 Nokia Corporation and/or its
      subsidiaries. Documentation contributions included herein are the copyrights of
      their respective owners.</p>
    <br />
    <p>
      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.</p>
    <p>
      Documentation sources may be obtained from <a href="http://www.qt-project.org">
      www.qt-project.org</a>.</p>
    <br />
    <p>
      Nokia, Qt and their respective logos are trademarks of Nokia Corporation 
      in Finland and/or other countries worldwide. All other trademarks are property
      of their respective owners. <a title="Privacy Policy"
      href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p>
</div>
</body>
</html>