1
/****************************************************************************
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
6
** This file is part of the documentation of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:FDL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
17
** GNU Free Documentation License Usage
18
** Alternatively, this file may be used under the terms of the GNU Free
19
** Documentation License version 1.3 as published by the Free Software
20
** Foundation and appearing in the file included in the packaging of
21
** this file. Please review the following information to ensure
22
** the GNU Free Documentation License version 1.3 requirements
23
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
26
****************************************************************************/
29
\example googlesuggest
30
\title Google Suggest Example
31
\ingroup examples-network
32
\brief Obtains the list of search recommendations by the Google search engine
34
The example uses the QNetworkAccessManager to obtain the list of search
35
recommendations by Google as the user types into a QLineEdit.
37
\image googlesuggest-example.png
39
The application makes use of the \c get function in
40
QNetworkAccessManager to post a request and obtain the result of the search
41
query sent to the Google search engine. The results returned are listed as
42
clickable links appearing below the search box as a drop-down menu.
44
The widget is built up by a QLineEdit as the search box, and a QTreeView
45
used as a popup menu below the search box.
47
\section1 GSuggestCompletion Class Declaration
49
This class implements an event filter and a number of functions to display
50
the search results and to determent when and how to perform the search.
52
\snippet googlesuggest/googlesuggest.h 1
54
The class connects to a QLineEdit and uses a QTreeWidget to display the
55
results. A QTimer controls the start of the network requests that are
56
executed using a QNetworkAccessManager.
58
\section1 GSuggestCompletion Class Implementation
60
We start by defining a constant containing the URL to be used in the Google
61
queries. This is the basis for the query. The letters typed into the search
62
box will be added to the query to perform the search itself.
64
\snippet googlesuggest/googlesuggest.cpp 1
66
In the constructor, we set the parent of this GSuggestCompletion instance
67
to be the QLineEdit passed in. For simplicity, the QLineEdit is also stored
68
in the explicit \c editor member variable.
70
We then create a QTreeWidget as a toplevel widget and configure the various
71
properties to give it the look of a popup widget. The widget is populated
72
with the results by Google Suggest API request.
74
Furthermore, we install the GSuggestCompletion instance as an event filter
75
on the QTreeWidget, and connect the \c itemClicked() signal with the \c
76
doneCompletion() slot.
78
A single-shot QTimer is used to start the request when the user has stopped
81
Finally, we connect the networkManagers \c finished() signal with the \c
82
handleNetworkData() slot to handle the incoming data.
84
\snippet googlesuggest/googlesuggest.cpp 2
86
Since the QTreeWidget popup has been instantiated as a toplevel widget, the
87
destructor has to delete it explicitly from memory to avoid a memory leak.
89
\snippet googlesuggest/googlesuggest.cpp 3
91
The event filter handles mouse press and key press events that are
92
delivered to the popup. For mouse press events we just hide the popup and
93
return focus to the editor widget, and then return true to prevent further
96
Key event handling is implemented so that Enter and Return execute the
97
selected link, while the Escape key hides the popup. Since we want to be
98
able to navigate the list of suggestions using the different navigation
99
keys on the keyboard we let Qt continue regular event processing for those
100
by returning false from the eventFilter reimplementation.
102
For all other keys, the event will be passed on to the editor widget and the
103
popup is hidden. This way the user's typing will not be interrupted by the
104
popping up of the completion list.
106
\snippet googlesuggest/googlesuggest.cpp 4
108
The \c showCompletion() function populates the QTreeWidget with the results
109
returned from the query. It takes a QStringList of the suggested search
112
\snippet googlesuggest/googlesuggest.cpp 5
114
A QTreeWidgetItem is created for each index in the list and inserted into
115
the QTreeWidget. Finally, we adjust position and size of the popup to make
116
sure that it pops up in the correct position below the editor, and show it.
118
The \c doneCompletion() function, which is called by the event filter when
119
either Enter or Return keys are pressed, stops the timer to prevent further
120
requests and passes the text of the selected item to the editor. We then
121
make the \c editor QLineEdit emit the returnPressed() signal, to which the
122
application can connect to open the respective web page.
124
\snippet googlesuggest/googlesuggest.cpp 6
126
The \c autoSuggest() slot is called when the timer times out, and uses the
127
text in the editor to build the complete search query. The query is then
128
passed to the QNetworkAccessManager's \c get() function to start the
131
\snippet googlesuggest/googlesuggest.cpp 7
133
The function \c preventSuggest() stops the timer to prevent further
134
requests from being started.
136
\snippet googlesuggest/googlesuggest.cpp 8
138
When the network request is finished, the QNetworkAccessManager delivers the
139
data received from the server through the networkReply object.
141
\snippet googlesuggest/googlesuggest.cpp 9
143
To extract the data from the reply we use the \c readAll() function, which
144
is inherited from QIODevice and returns a QByteArray. Since this data is
145
encoded in XML we can use a QXmlStreamReader to traverse the data and
146
extract the search result as QStrings, which we can stream into two
147
QStringLists used to populate the popup.
149
Finally, we schedule the QNetworkReply object for deletion using the \c
150
deleteLater function.
152
\section1 SearchBox Class Declaration
154
The SearchBox class inherits QLineEdit and adds the protected slot \c
157
A \c GSuggestCompletion member provides the SearchBox with the request
158
functionality and the suggestions returned from the Google search engine.
160
\snippet googlesuggest/searchbox.h 1
162
\section1 SearchBox Class Implementation
164
The search box constructor instantiates the GSuggestCompletion object and
165
connects the returnPressed() signal to the doSearch() slot.
167
\snippet googlesuggest/searchbox.cpp 1
169
The function \c doSearch() stops the completer from sending any further
170
queries to the search engine.
172
Further, the function extracts the selected search phrase and opens it
173
in the default web browser using QDesktopServices.
175
\snippet googlesuggest/searchbox.cpp 2