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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example dialogs/findfiles
\title Find Files Example
The Find Files example shows how to use QProgressDialog to provide
feedback on the progress of a slow operation. The example also
shows how to use QFileDialog to facilitate browsing, how to use
QTextStream's streaming operators to read a file, and how to use
QTableWidget to provide standard table display facilities for
applications. In addition, files can be opened using the
QDesktopServices class.
\image findfiles-example.png Screenshot of the Find Files example
With the Find Files application the user can search for files in a
specified directory, matching a specified file name (using wild
cards if appropiate) and containing a specified text.
The user is provided with a \gui Browse option, and the result of
the search is displayed in a table with the names of the files
found and their sizes. In addition the application provides a
total count of the files found.
\section1 Window Class Definition
The \c Window class inherits QWidget, and is the main application
widget. It shows the search options, and displays the search
results.
\snippet examples/dialogs/findfiles/window.h 0
We need two private slots: The \c browse() slot is called whenever
the user wants to browse for a directory to search in, and the \c
find() slot is called whenever the user requests a search to be
performed by pressing the \gui Find button.
In addition we declare several private functions: We use the \c
findFiles() function to search for files matching the user's
specifications, we call the \c showFiles() function to display the
results, and we use \c createButton(), \c createComboBox() and \c
createFilesTable() when we are constructing the widget.
\section1 Window Class Implementation
In the constructor we first create the application's widgets.
\snippet examples/dialogs/findfiles/window.cpp 0
We create the application's buttons using the private \c
createButton() function. Then we create the comboboxes associated
with the search specifications, using the private \c
createComboBox() function. We also create the application's labels
before we use the private \c createFilesTable() function to create
the table displaying the search results.
\snippet examples/dialogs/findfiles/window.cpp 1
Then we add all the widgets to a main layout using QGridLayout. We
have, however, put the \c Find and \c Quit buttons and a
stretchable space in a separate QHBoxLayout first, to make the
buttons appear in the \c Window widget's bottom right corner.
\snippet examples/dialogs/findfiles/window.cpp 2
The \c browse() slot presents a file dialog to the user, using the
QFileDialog class. QFileDialog enables a user to traverse the file
system in order to select one or many files or a directory. The
easiest way to create a QFileDialog is to use the convenience
static functions.
Here we use the static QFileDialog::getExistingDirectory()
function which returns an existing directory selected by the
user. Then we display the directory in the directory combobox
using the QComboBox::addItem() function, and updates the current
index.
QComboBox::addItem() adds an item to the combobox with the given
text (if it is not already present in the list), and containing
the specified userData. The item is appended to the list of
existing items.
\snippet examples/dialogs/findfiles/window.cpp 3
The \c find() slot is called whenever the user requests a new
search by pressing the \gui Find button.
First we eliminate any previous search results by setting the
table widgets row count to zero. Then we retrieve the
specified file name, text and directory path from the respective
comboboxes.
\snippet examples/dialogs/findfiles/window.cpp 4
We use the directory's path to create a QDir; the QDir class
provides access to directory structures and their contents. We
create a list of the files (contained in the newly created QDir)
that match the specified file name. If the file name is empty
the list will contain all the files in the directory.
Then we search through all the files in the list, using the private
\c findFiles() function, eliminating the ones that don't contain
the specified text. And finally, we display the results using the
private \c showFiles() function.
If the user didn't specify any text, there is no reason to search
through the files, and we display the results immediately.
\image findfiles_progress_dialog.png Screenshot of the Progress Dialog
\snippet examples/dialogs/findfiles/window.cpp 5
In the private \c findFiles() function we search through a list of
files, looking for the ones that contain a specified text. This
can be a very slow operation depending on the number of files as
well as their sizes. In case there are a large number of files, or
there exists some large files on the list, we provide a
QProgressDialog.
The QProgressDialog class provides feedback on the progress of a
slow operation. It is used to give the user an indication of how
long an operation is going to take, and to demonstrate that the
application has not frozen. It can also give the user an
opportunity to abort the operation.
\snippet examples/dialogs/findfiles/window.cpp 6
We run through the files, one at a time, and for each file we
update the QProgressDialog value. This property holds the current
amount of progress made. We also update the progress dialog's
label.
Then we call the QCoreApplication::processEvents() function using
the QApplication object. In this way we interleave the display of
the progress made with the process of searching through the files
so the application doesn't appear to be frozen.
The QApplication class manages the GUI application's control flow
and main settings. It contains the main event loop, where all
events from the window system and other sources are processed and
dispatched. QApplication inherits QCoreApplication. The
QCoreApplication::processEvents() function processes all pending
events according to the specified QEventLoop::ProcessEventFlags
until there are no more events to process. The default flags are
QEventLoop::AllEvents.
\snippet examples/dialogs/findfiles/window.cpp 7
After updating the QProgressDialog, we create a QFile using the
QDir::absoluteFilePath() function which returns the absolute path
name of a file in the directory. We open the file in read-only
mode, and read one line at a time using QTextStream.
The QTextStream class provides a convenient interface for reading
and writing text. Using QTextStream's streaming operators, you can
conveniently read and write words, lines and numbers.
For each line we read we check if the QProgressDialog has been
canceled. If it has, we abort the operation, otherwise we check if
the line contains the specified text. When we find the text within
one of the files, we add the file's name to a list of found files
that contain the specified text, and start searching a new file.
Finally, we return the list of the files found.
\snippet examples/dialogs/findfiles/window.cpp 8
Both the \c findFiles() and \c showFiles() functions are called from
the \c find() slot. In the \c showFiles() function we run through
the provided list of file names, adding each file name to the
first column in the table widget and retrieving the file's size using
QFile and QFileInfo for the second column.
We also update the total number of files found.
\snippet examples/dialogs/findfiles/window.cpp 9
The private \c createButton() function is called from the
constructor. We create a QPushButton with the provided text,
connect it to the provided slot, and return a pointer to the
button.
\snippet examples/dialogs/findfiles/window.cpp 10
The private \c createComboBox() function is also called from the
contructor. We create a QComboBox with the given text, and make it
editable.
When the user enters a new string in an editable combobox, the
widget may or may not insert it, and it can insert it in several
locations, depending on the QComboBox::InsertPolicy. The default
policy is is QComboBox::InsertAtBottom.
Then we add the provided text to the combobox, and specify the
widget's size policies, before we return a pointer to the
combobox.
\snippet examples/dialogs/findfiles/window.cpp 11
The private \c createFilesTable() function is called from the
constructor. In this function we create the QTableWidget that
will display the search results. We set its horizontal headers and
their resize mode.
QTableWidget inherits QTableView which provides a default
model/view implementation of a table view. The
QTableView::horizontalHeader() function returns the table view's
horizontal header as a QHeaderView. The QHeaderView class provides
a header row or header column for item views, and the
QHeaderView::setResizeMode() function sets the constraints on how
the section in the header can be resized.
Finally, we hide the QTableWidget's vertical headers using the
QWidget::hide() function, and remove the default grid drawn for
the table using the QTableView::setShowGrid() function.
\snippet examples/dialogs/findfiles/window.cpp 12
The \c openFileOfItem() slot is invoked when the user double
clicks on a cell in the table. The QDesktopServices::openUrl()
knows how to open a file given the file name.
*/
|