1/**************************************************************************** 2** 3** Copyright (C) 2016 The Qt Company Ltd. 4** Contact: https://www.qt.io/licensing/ 5** 6** This file is part of the documentation of the Qt Toolkit. 7** 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. 16** 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. 24** $QT_END_LICENSE$ 25** 26****************************************************************************/ 27 28/*! 29 \example webenginewidgets/simplebrowser 30 \title WebEngine Widgets Simple Browser Example 31 \ingroup webengine-widgetexamples 32 \brief A simple browser based on Qt WebEngine Widgets. 33 34 \image simplebrowser.png 35 36 \e {Simple Browser} demonstrates how to use the 37 \l{Qt WebEngine Widgets C++ Classes}{Qt WebEngine C++ classes} to develop a 38 small Web browser application that contains the following elements: 39 40 \list 41 \li Menu bar for opening stored pages and managing windows and tabs. 42 \li Navigation bar for entering a URL and for moving backward and 43 forward in the web page browsing history. 44 \li Multi-tab area for displaying web content within tabs. 45 \li Status bar for displaying hovered links. 46 \li A simple download manager. 47 \endlist 48 49 The web content can be opened in new tabs or separate windows. HTTP and 50 proxy authentication can be used for accessing web pages. 51 52 \include examples-run.qdocinc 53 54 \section1 Class Hierarchy 55 56 We start with sketching a diagram of the main classes that we are going to 57 implement: 58 59 \image simplebrowser-model.png 60 61 \list 62 \li \c{Browser} is a class managing the application windows. 63 \li \c{BrowserWindow} is a \l QMainWindow showing the menu, a navigation 64 bar, \c {TabWidget}, and a status bar. 65 \li \c{TabWidget} is a \l QTabWidget and contains one or multiple 66 browser tabs. 67 \li \c{WebView} is a \l QWebEngineView, provides a view for \c{WebPage}, 68 and is added as a tab in \c{TabWidget}. 69 \li \c{WebPage} is a \l QWebEnginePage that represents website content. 70 \endlist 71 72 Additionally, we will implement some auxiliary classes: 73 74 \list 75 \li \c{WebPopupWindow} is a \l QWidget for showing popup windows. 76 \li \c{DownloadManagerWidget} is a \l QWidget implementing the downloads 77 list. 78 \endlist 79 80 \section1 Creating the Browser Main Window 81 82 This example supports multiple main windows that are owned by a \c Browser 83 object. This class also owns the \c DownloadManagerWidget and could be used 84 for further functionality, such as bookmarks and history managers. 85 86 In \c main.cpp, we create the first \c BrowserWindow instance and add it 87 to the \c Browser object. If no arguments are passed on the command line, 88 we open the \l{Qt Homepage}: 89 90 \quotefromfile webenginewidgets/simplebrowser/main.cpp 91 \skipto main 92 \printuntil } 93 94 \section1 Creating Tabs 95 96 The \c BrowserWindow constructor initializes all the necessary user interface 97 related objects. The \c centralWidget of \c BrowserWindow contains an instance of 98 \c TabWidget. The \c TabWidget contains one or several \c WebView instances as tabs, 99 and delegates it's signals and slots to the currently selected one: 100 101 \quotefromfile webenginewidgets/simplebrowser/tabwidget.h 102 \skipto TabWidget : 103 \printuntil { 104 \dots 105 \skipto signals 106 \printuntil triggerWebPageAction 107 \skipto } 108 \dots 109 \printline }; 110 111 Each tab contains an instance of \c WebView: 112 113 \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp 114 \skipto TabWidget::createTab( 115 \printuntil } 116 \skipto TabWidget::createBackgroundTab( 117 \printuntil } 118 119 In \c TabWidget::setupView(), we make sure that the \c TabWidget always forwards 120 the signals of the currently selected \c WebView: 121 122 \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp 123 \skipto TabWidget::setupView 124 \printuntil /^\}/ 125 126 \section1 Implementing WebView Functionality 127 128 The \c WebView is derived from QWebEngineView to support the following 129 functionality: 130 131 \list 132 \li Displaying error messages in case \c renderProcess dies 133 \li Handling \c createWindow requests 134 \li Adding custom menu items to context menus 135 \endlist 136 137 First, we create the WebView with the necessary methods and signals: 138 139 \quotefromfile webenginewidgets/simplebrowser/webview.h 140 \skipto WebView : 141 \printuntil WebView( 142 \dots 143 \skipto protected: 144 \printuntil webActionEnabledChanged 145 \skipto } 146 \dots 147 \printline }; 148 149 \section2 Displaying Error Messages 150 151 If the render process is terminated, we display a QMessageBox with an error 152 code, and then we reload the page: 153 154 \quotefromfile webenginewidgets/simplebrowser/webview.cpp 155 \skipto WebView::WebView(QWidget *parent) 156 \printuntil { 157 \skipto renderProcessTerminated 158 \dots 159 \printuntil QTimer 160 \printline }); 161 \printline } 162 163 \section2 Managing WebWindows 164 165 The loaded page might want to create windows of the type 166 QWebEnginePage::WebWindowType, for example, when a JavaScript program 167 requests to open a document in a new window or dialog. 168 This is handled by overriding \c QWebView::createWindow(): 169 170 \skipto WebView::createWindow( 171 \printuntil return nullptr; 172 \printuntil } 173 174 In case of \c QWebEnginePage::WebDialog, we create an instance of a custom \c WebPopupWindow class: 175 176 \quotefromfile webenginewidgets/simplebrowser/webpopupwindow.h 177 \skipto class WebPopupWindow 178 \printuntil }; 179 180 \section2 Adding Context Menu Items 181 182 We add a menu item to the context menu, so that users can right-click to have an inspector 183 opened in a new window. We override QWebEngineView::contextMenuEvent and use 184 QWebEnginePage::createStandardContextMenu to create a default QMenu with a 185 default list of QWebEnginePage::WebAction actions. 186 187 The default name for QWebEnginePage::InspectElement action is 188 \uicontrol Inspect. For clarity, we rename it to \uicontrol {Open Inspector In New Window} when 189 there is no Inspector present yet, 190 and \uicontrol {Inspect Element} when it's already created. 191 192 We also check if the QWebEnginePage::ViewSource action is in the menu, because if it's not 193 we have to add a separator as well. 194 195 \quotefromfile webenginewidgets/simplebrowser/webview.cpp 196 \skipto WebView::contextMenuEvent( 197 \printuntil menu->popup 198 \printline } 199 200 \section1 Implementing WebPage Functionality 201 202 We implement \c WebPage as a subclass of QWebEnginePage to enable HTTP, 203 proxy authentication, and ignoring SSL certificate errors when accessing web 204 pages: 205 206 \quotefromfile webenginewidgets/simplebrowser/webpage.h 207 \skipto WebPage : 208 \printuntil } 209 210 In all the cases above, we display the appropriate dialog to the user. In 211 case of authentication, we need to set the correct credential values on the 212 QAuthenticator object: 213 214 \quotefromfile webenginewidgets/simplebrowser/webpage.cpp 215 \skipto WebPage::handleAuthenticationRequired( 216 \printuntil } 217 \printuntil } 218 \printline } 219 220 The \c handleProxyAuthenticationRequired signal handler implements the very same 221 steps for the authentication of HTTP proxies. 222 223 In case of SSL errors, we just need to return a boolean value indicating 224 whether the certificate should be ignored. 225 226 \quotefromfile webenginewidgets/simplebrowser/webpage.cpp 227 \skipto WebPage::certificateError( 228 \printuntil } 229 \printuntil } 230 231 \section1 Opening a Web Page 232 233 This section describes the workflow for opening a new page. When the user 234 enters a URL in the navigation bar and presses \uicontrol Enter, the \c 235 QLineEdit::returnPressed signal is emitted and the new URL is then handed 236 over to \c TabWidget::setUrl: 237 238 \quotefromfile webenginewidgets/simplebrowser/browserwindow.cpp 239 \skipto BrowserWindow::BrowserWindow 240 \printline BrowserWindow::BrowserWindow 241 \skipto /^\{/ 242 \printline /^\{/ 243 \dots 244 \skipto connect(m_urlLineEdit 245 \printuntil }); 246 \dots 247 \skipto /^\}/ 248 \printline /^\}/ 249 250 The call is forwarded to the currently selected tab: 251 252 \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp 253 \skipto TabWidget::setUrl( 254 \printuntil } 255 \printuntil } 256 257 The \c setUrl() method of \c WebView just forwards the \c url to the associated \c WebPage, 258 which in turn starts the downloading of the page's content in the background. 259 260 \section1 Implementing Private Browsing 261 262 \e{Private browsing}, \e{incognito mode}, or \e{off-the-record mode} is a 263 feature of many browsers where normally persistent data, such as cookies, 264 the HTTP cache, or browsing history, is kept only in memory, leaving no 265 trace on disk. In this example we will implement private browsing on the 266 window level with tabs in one window all in either normal or private mode. 267 Alternatively we could implement private browsing on the tab-level, with 268 some tabs in a window in normal mode, others in private mode. 269 270 Implementing private browsing is quite easy using Qt WebEngine. All one has 271 to do is to create a new \l{QWebEngineProfile} and use it in the 272 \l{QWebEnginePage} instead of the default profile. In the example this new 273 profile is created and owned by the \c Browser object: 274 275 \quotefromfile webenginewidgets/simplebrowser/browser.h 276 \skipto /^class Browser$/ 277 \printuntil public: 278 \dots 279 \skipto createWindow 280 \printline createWindow 281 \skipto private: 282 \printline private: 283 \dots 284 \skipto m_otrProfile 285 \printline m_otrProfile 286 \printline /^\};$/ 287 288 The default constructor for \l{QWebEngineProfile} already puts it in 289 \e{off-the-record} mode. All that is left to do is to pass the appropriate 290 profile down to the appropriate \l QWebEnginePage objects. The \c Browser 291 object will hand to each new \c BrowserWindow either the global default 292 profile (see \l{QWebEngineProfile::defaultProfile}) or its own 293 off-the-record profile: 294 295 \quotefromfile webenginewidgets/simplebrowser/browser.cpp 296 \skipto Browser::createWindow 297 \printuntil mainWindow = new BrowserWindow 298 \skipto return mainWindow 299 \printuntil /^\}/ 300 301 The \c BrowserWindow and \c TabWidget objects will then ensure that all \l 302 QWebEnginePage objects contained in a window will use this profile. 303 304 \section1 Managing Downloads 305 306 Downloads are associated with a \l QWebEngineProfile. Whenever a download is 307 triggered on a web page the \l QWebEngineProfile::downloadRequested signal is 308 emitted with a \l QWebEngineDownloadItem, which in this example is forwarded 309 to \c DownloadManagerWidget::downloadRequested: 310 311 \quotefromfile webenginewidgets/simplebrowser/browser.cpp 312 \skipto Browser::Browser 313 \printuntil /^\}/ 314 315 This method prompts the user for a file name (with a pre-filled suggestion) 316 and starts the download (unless the user cancels the \uicontrol {Save As} 317 dialog): 318 319 \quotefromfile webenginewidgets/simplebrowser/downloadmanagerwidget.cpp 320 \skipto DownloadManagerWidget::downloadRequested 321 \printuntil /^\}/ 322 323 The \l QWebEngineDownloadItem object will periodically emit the \l 324 {QWebEngineDownloadItem::}{downloadProgress} signal to notify potential 325 observers of the download progress and the \l 326 {QWebEngineDownloadItem::}{stateChanged} signal when the download is 327 finished or when an error occurs. See \c downloadmanagerwidget.cpp for an 328 example of how these signals can be handled. 329 330 \section1 Files and Attributions 331 332 The example uses icons from the Tango Icon Library: 333 334 \table 335 \row 336 \li \l{simplebrowser-tango}{Tango Icon Library} 337 \li Public Domain 338 \endtable 339*/ 340