Overview
Qt provides robust support for embedding web content within desktop applications through the QWebEngineView class. The implementation approach varies depending on the Qt version:
Qt4: webkit module
Qt5~Qt5.5: webkitwidgets module
Qt5.6+: webenginewidgets module
This guide demonstrates practical integration patterns using Qt5.6+ with the webenginewidgets module.
Example 1: Console Application with Web View
Create a new Console project and configure the project file:
app1.pro
QT += core gui widgets webenginewidgets network
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += html.qrc
main.cpp
#include <QCoreApplication>
#include <QApplication>
#include <QWidget>
#include <QWebEngineView>
#include <QVBoxLayout>
#include <QUrl>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QWidget rootWindow;
QVBoxLayout* layout = new QVBoxLayout(&rootWindow);
QWebEngineView* browser = new QWebEngineView(&rootWindow);
QUrl resourcePath = QUrl("qrc:/new/prefix1/test.html");
browser->setUrl(resourcePath);
// Execute JavaScript after page load completes
QObject::connect(browser, &QWebEngineView::loadFinished, [&browser]() {
QString script = QString("var map = new Microsoft.Maps.Map('#myMap',{});"
"map.setView({center: new Microsoft.Maps.Location(32.027222, 114.0225), zoom: 8});");
browser->page()->runJavaScript(script);
});
layout->addWidget(browser);
rootWindow.resize(700, 500);
rootWindow.show();
return app.exec();
}
test.html
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script type='text/javascript'
src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=[your bing key]'
async defer></script>
<script type='text/javascript'>
function GetMap()
{
var map = new Microsoft.Maps.Map('#myMap',{});
}
</script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;"></div>
</body>
</html>
Example 2: QWidget Application with Web Channel
Create a QWidget-based project for bidirectional JavaScript communication:
app2.pro
QT += core gui webenginewidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp browserwidget.cpp
HEADERS += browserwidget.h
FORMS += browserwidget.ui
main.cpp
#include "browserwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_UseOpenGLES);
QApplication app(argc, argv);
BrowserWidget window;
window.show();
return app.exec();
}
browserwidget.h
#ifndef BROWSERWIDGET_H
#define BROWSERWIDGET_H
#include <QWidget>
#include <QWebEngineView>
#include <QWebChannel>
QT_BEGIN_NAMESPACE
namespace Ui { class BrowserWidget; }
QT_END_NAMESPACE
class BrowserWidget : public QWidget
{
Q_OBJECT
public:
BrowserWidget(QWidget *parent = nullptr);
~BrowserWidget();
QWebEngineView* webView;
QWebChannel* communicationChannel;
public slots:
void onPageLoadComplete();
private:
Ui::BrowserWidget *ui;
};
#endif
browserwidget.cpp
#include "browserwidget.h"
#include "ui_browserwidget.h"
#include <QVBoxLayout>
BrowserWidget::BrowserWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::BrowserWidget)
{
ui->setupUi(this);
webView = new QWebEngineView(this);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(webView);
communicationChannel = new QWebChannel(this);
communicationChannel->registerObject(QString("webobj"), this);
webView->page()->setWebChannel(communicationChannel);
connect(webView, &QWebEngineView::loadFinished, this, &BrowserWidget::onPageLoadComplete);
webView->load(QUrl(QStringLiteral("http://www.baidu.com")));
}
BrowserWidget::~BrowserWidget()
{
delete ui;
delete webView;
}
void BrowserWidget::onPageLoadComplete()
{
QString jsStr = QString("initData('test', 1, 2, 3)");
webView->page()->runJavaScript("alert('hello world!')");
}
Example 3: QMainWindow Application
Create a QMainWindow-based project for standalone web display:
app3.pro
QT += core gui webenginewidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp webwindow.cpp
HEADERS += webwindow.h
FORMS += webwindow.ui
main.cpp
#include "webwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
WebWindow mainWin;
mainWin.show();
return app.exec();
}
webwindow.h
#ifndef WEBWINDOW_H
#define WEBWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class WebWindow; }
QT_END_NAMESPACE
class WebWindow : public QMainWindow
{
Q_OBJECT
public:
WebWindow(QWidget *parent = nullptr);
~WebWindow();
private:
Ui::WebWindow *ui;
};
#endif
webwindow.cpp
#include "webwindow.h"
#include "ui_webwindow.h"
#include <QWebEngineView>
WebWindow::WebWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::WebWindow)
{
ui->setupUi(this);
QWebEngineView* webView = new QWebEngineView(this);
webView->load(QUrl("file:///C:/Users/tomcat/Desktop/test.html"));
webView->resize(700, 600);
webView->show();
}
WebWindow::~WebWindow()
{
delete ui;
}
Example 4: Integrating Baidu Maps
This example demonstrates embedding Baidu Maps with Qt-JavaScript bidirectional communication.
Prerequisites:
- Add
QT += webenginewidgetsto your .pro file - Promote a widget to
QWebEngineViewin Qt Designer - Copy
qwebchannel.jsfromqtwebchannel/examples/webchannel/sharedto your project directory
webmap.pro
QT += core gui webenginewidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp mapmainwindow.cpp
HEADERS += mapmainwindow.h
FORMS += mapmainwindow.ui
main.cpp
#include "mapmainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MapMainWindow win;
win.show();
return app.exec();
}
mapmainwindow.h
#ifndef MAPMAINWINDOW_H
#define MAPMAINWINDOW_H
#include <QMainWindow>
#include <QWebEngineHistory>
#include <QWebEnginePage>
#include <QWebEngineView>
#include <QtWebEngineWidgets/QtWebEngineWidgets>
QT_BEGIN_NAMESPACE
namespace Ui { class MapMainWindow; }
QT_END_NAMESPACE
class MapMainWindow : public QMainWindow
{
Q_OBJECT
public:
MapMainWindow(QWidget *parent = nullptr);
~MapMainWindow();
void handleButtonClick();
private:
Ui::MapMainWindow *ui;
};
#endif
mapmainwindow.cpp
#include "mapmainwindow.h"
#include "ui_mapmainwindow.h"
#include <QPushButton>
#include <QFile>
#include <QDebug>
MapMainWindow::MapMainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MapMainWindow)
{
ui->setupUi(this);
QString htmlPath = QCoreApplication::applicationDirPath() + "/html/";
QString htmlFile = htmlPath + "map.html";
qDebug() << htmlFile;
QFile file(htmlFile);
if (!file.exists())
qDebug() << "HTML file not found";
QWebChannel* channel = new QWebChannel(ui->mapWidget->page());
ui->mapWidget->page()->setWebChannel(channel);
channel->registerObject(QString("JSInterface"), ui->mapWidget);
ui->mapWidget->page()->load(QUrl("file:///" + htmlFile));
}
MapMainWindow::~MapMainWindow()
{
delete ui;
}
void MapMainWindow::handleButtonClick()
{
// JavaScript execution from C++ side
}
map.html
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Map Demo</title>
<style type="text/css">
html, body { height: 100%; margin: 0; padding: 0; }
#container { height: 100%; }
</style>
<script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=your baidu key"></script>
<script type="text/javascript" src="qwebchannel.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
var map = new BMapGL.Map("container");
var centerPoint = new BMapGL.Point(113.557892, 34.8333);
map.centerAndZoom(centerPoint, 15);
map.enableScrollWheelZoom(true);
var markerPoint = new BMapGL.Point(113.557892, 34.8333);
var marker = new BMapGL.Marker(markerPoint);
map.addOverlay(marker);
var infoOptions = {
width: 250,
height: 100,
title: "Marker Title"
};
var infoWindow = new BMapGL.InfoWindow("Marker Info", infoOptions);
marker.addEventListener("click", function() {
map.openInfoWindow(infoWindow, map.getCenter());
});
// Qt communication setup
new QWebChannel(qt.webChannelTransport, function(channel) {
window.JSInterface = channel.objects.JSInterface;
});
function addMarker(longitude, latitude) {
var point = new BMapGL.Point(longitude, latitude);
var newMarker = new BMapGL.Marker(point);
map.addOverlay(newMarker);
alert('Marker added');
}
</script>
</body>
</html>
Qt Creator Keyboard Shortcuts
Basic Shortcuts
Ctrl + N : New file or project
Ctrl + W : Close current window/file
Ctrl + Shift + W: Close all files
Ctrl + R : Run project
Alt + Left : Navigate back (code jumping)
Alt + Right : Navigate forward (code jumping)
Code Editing
Ctrl + I : Auto-format code
Ctrl + +/- : Adjust font size
Ctrl + 0 : Reset font size
Ctrl + < : Collapse code block
Ctrl + > : Expand code block
Ctrl + Ins : Copy line
Ctrl + Alt + Up/Down: Duplicate line up/down
Ctrl + Shift + Enter: Insert new line above
Ctrl + Enter : Insert new line below
Ctrl + Shift + V: Clipboard history
Shift + Del : Cut line
Ctrl + J : Append line
Ctrl + Shift + Up/Down: Move line up/down
Ctrl + Shift + F2: Toggle function declaration/definition
F4 : Edit signals and slots
Ctrl + } : Jump to block end
Ctrl + { : Jump to block start
Ctrl + Shift + T: Open type hierarchy
Accessing Qt Documentation
Qt Creator documentation is installed alongside Qt. For Qt 5.14.2, documentation resides in Qt5.14.2/Docs/Qt-5.14.2. Access it via the Help panel by selecting the "Index" tab and searching for classes like QWebEngineView or QOpenGLBuffer.