This chapter reveals how to embed a full-featured web client directly into a Qt application and get a hybrid that looks native, works fast, and leverages the full power of modern web technologies. You’ll discover why professional developers increasingly bet on Qt WebEngine.
We’ll show how to display a web page in just a few lines of code, how to manage navigation history, and track resource loading. The text includes specific figures, Qt6 architectural modules, and real examples of hybrid applications already using this approach.
If you leave this chapter for later — there’s a risk of continuing to write redundant code and waste time where everything is already solved.
This chapter includes ready-to-use code examples.
Chapter Self-Check
Why was WebKit replaced with Chromium in Qt5.4, and what advantages did this give developers?Answer
Correct answer: Chromium ensured modern compatibility across all platforms, full integration with Qt ecosystem (signals/slots, QML), JS-C++ interaction via WebChannel, and compactness compared to Electron.
Why was the WebEngine module split into three separate modules in Qt6: Core, Widgets, and Quick?Answer
Correct answer: Separation allows Qt Quick applications to avoid carrying redundant widget code, reducing size and improving performance for applications without classic widgets.
Why doesn’t Qt WebEngine provide a ready-made full-featured browser as a single widget?Answer
Correct answer: Instead, a “constructor” with components is provided, allowing developers to create browsers in the needed configuration using other Qt widgets.
What happens if a user enters address www.example.com without specifying protocol, and how should this be handled?Answer
Correct answer: The load() method may not recognize the address correctly. The application should check the string start and automatically add https:// if protocol is missing.
Why does the QWebEngineHistory class automatically remove duplicate items when addresses match?Answer
Correct answer: This prevents uncontrolled growth of the history list to huge sizes and makes navigation history practically usable.
What is the main complexity of web page loading that Qt WebEngine hides from developers?Answer
Correct answer: Asynchronous loading of multiple resources (images, CSS, JS, frames) that arrive independently and in any order, with handling of possible network and server errors.
Which signal should be used to display a page loading progress bar, and what does it pass?Answer
Correct answer: The loadProgress() signal of QWebEngineView class, which passes an integer value from 0 to 100 showing completion percentage.
Why connect back() and forward() slots of QWebEngineView to buttons if history is managed automatically?Answer
Correct answer: Automatic navigation only works when clicking links; buttons give users explicit history control to return to previous pages without searching for links.
What happens to the user interface if the address field isn’t updated after following a link?Answer
Correct answer: The user will see an outdated address, won’t be able to correctly copy the current URL or make changes to it, breaking basic browser functionality.
Why is MSVC recommended over MinGW for WebEngine projects under Windows?Answer
Correct answer: MinGW can cause issues when working with the WebEngine module, while MSVC 2017+ ensures stable compilation of projects with this module.
In which cases is a hybrid application (native code + web content) more advantageous than a pure web application?Answer
Correct answer: When you need access to local system resources, native interface performance, OS integration, or working with data outside the web (configurators, control panels).
How should an application handle when loadFinished() returns false?Answer
Correct answer: Inform the user about the error, for example, by calling setHtml() to display an error message right in the browser window.
Why are canGoBack() and canGoForward() methods important for managing navigation button states?Answer
Correct answer: They prevent attempts to navigate to non-existent history items, allowing buttons to be active only when transition is actually possible.
What’s the fundamental difference between VS Code architecture (on Electron) and the Qt WebEngine approach?Answer
Correct answer: Electron uses Chromium + Node.js with UI entirely in HTML/JS, while Qt WebEngine embeds web engine into native application, ensuring greater compactness and performance.
What can happen if you forget to add webenginewidgets to the pro-file or CMake?Answer
Correct answer: Compiler will output “Unknown module(s)” error or won’t find QWebEngineView classes; also possible module absence in minimal Qt builds, requiring installation via Maintenance Tool.
Practical Assignments
Easy Level
Simple Documentation Viewer
Create an application that displays local HTML documentation or help. Add “Back”, “Forward”, and “Home” buttons (return to start page). Implement page loading indicator using QProgressBar.
Hints: Use QWebEngineView for display. Connect buttons to back(), forward(), and reload() slots. For indicator, connect loadProgress() signal to setValue() of progress bar. Load initial page via load(QUrl::fromLocalFile(“path/to/file.html”)).
Medium Level
Browser with History Management
Develop a web browser with address input field, automatic URL validation (adding https:// when needed), navigation button management (active only when transition available), and visited pages list display. Add button for clearing history.
Hints: In slotGo(), check string start with startsWith() method. Use QWebEngineHistory::canGoBack()/canGoForward() for button state management. Access history via webView->page()->history(). For page list, use items(), backItems(), or forwardItems() methods. Clearing — clear() method.
Hard Level
Hybrid Application with Local and Web Resources
Create a configurator application that displays web pages with product information but also allows loading and saving configuration to local JSON file. Implement tabs (QTabWidget) for simultaneous work with multiple pages, error handling with informative messages, and ability to export current page to PDF.
Hints: Create QTabWidget and add new QWebEngineView to it. Use QJsonDocument for JSON. Handle errors in loadFinished(bool) slot. For PDF export, use webView->page()->printToPdf(). Synchronize address bar with active tab via QTabWidget’s currentChanged() signal. Consider using QWebChannel for C++-JavaScript interaction.
💬 Join the Discussion!
Got a handle on integrating web content into Qt applications? Have questions about when to choose the hybrid approach?
Share your experience creating web browsers, talk about challenges working with Qt WebEngine, or help other readers find optimal solutions for their tasks!