Qt qml crash if QQuickWidget is created inside a QWidget - qt

There's a strange issue that might as well be a bug, but before posting that bug I want to assure it first - or find my own mistake. Basically I want to create a QWidget-subclass that contains, amongst other subwidgets, a QQuickWidget that loads a qml file.
I could boil the crash down to the minimal version below. The crash only occurs
if the qml actually sets an url or calls loadhtml AND
if the QQuickWidget is created inside the Viewer`s constructor.
It doesn't even make a difference if the QQuickWidget is initialized without a parent.
To reproduce, run the app and close it then via the green icon in the system tray.
crashtest.pro
QT += core gui widgets qml quickwidgets webview
TARGET = webviewcrash
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += c++11
CONFIG += qml_debug
SOURCES += main.cpp
RESOURCES += res.qrc
main.cpp:
#include <QApplication>
#include <QMenu>
#include <QSystemTrayIcon>
#include <QtWebView>
#include <QWebSocketServer>
#include <QQuickWidget>
#include <qboxlayout.h>
#include <qqmlapplicationengine.h>
#include <QQuickView>
#include <QtQml/QQmlContext>
#include <QDebug>
class Viewer : public QWidget
{
Q_OBJECT
public:
explicit Viewer(QWidget *parent = nullptr) : QWidget(parent){
setLayout(new QVBoxLayout);
}
void init(QQuickWidget* viewer){
if ( viewer ){
this->layout()->addWidget(viewer);
}
else{
QQuickWidget* viewer = new QQuickWidget(this);
viewer->setSource(QUrl("qrc:/viewer.qml"));
viewer->setResizeMode(QQuickWidget::SizeRootObjectToView);
this->layout()->addWidget(viewer);
}
}
};
#include "main.moc"
#define TRY_VIEWER_INIT_WITH_POINTER 0 // Crash
#define TRY_VIEWER_INIT_WITH_REFERENCE 0 // OK
#define TRY_VIEWER_INIT_INSIDE_VIEWER 0 // Crash
#define TRY_STAND_ALONE 0 // Crash
#define TRY_WITHOUT_QQUICKWIDGET 0 // OK - but this is a qml ApplicationWindow, not an Item.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtWebView::initialize();
#if TRY_VIEWER_INIT_WITH_POINTER
auto v1 = new Viewer();
v1->resize(500,300);
v1->move(100,100);
v1->show();
QQuickWidget *v1_viewer = new QQuickWidget;
v1_viewer->setResizeMode(QQuickWidget::SizeRootObjectToView);
v1_viewer->setSource(QUrl("qrc:/viewer.qml"));
v1->init(v1_viewer);
#endif
#if TRY_VIEWER_INIT_WITH_REFERENCE
auto v1 = new Viewer();
v1->resize(500,300);
v1->move(100,100);
v1->show();
QQuickWidget v1_viewer;
v1_viewer.setResizeMode(QQuickWidget::SizeRootObjectToView);
v1_viewer.setSource(QUrl("qrc:/viewer.qml"));
v1->init(&v1_viewer);
#endif
#if TRY_VIEWER_INIT_INSIDE_VIEWER
auto v1 = new Viewer();
v1->resize(500,300);
v1->move(100,100);
v1->show();
v1->init(nullptr);
#endif
#if TRY_STAND_ALONE
QQuickWidget viewer;
viewer.setSource(QUrl("qrc:/viewer.qml"));
viewer.setResizeMode(QQuickWidget::SizeRootObjectToView);
viewer.show();
#endif
#if TRY_WITHOUT_QQUICKWIDGET
QQmlApplicationEngine engine;
engine.load(QUrl("qrc:/viewer2.qml"));
if (engine.rootObjects().isEmpty())
return -1;
#endif
// MENU
QMenu trayMenu;
QSystemTrayIcon tray;
trayMenu.addAction("Exit",[&](){
qApp->quit();
});
tray.setContextMenu(&trayMenu);
QPixmap pix(32,32);
pix.fill(QColor(Qt::green));
tray.setIcon(QIcon(pix));
return a.exec();
}
viewer.qml
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtWebView 1.1
Item {
WebView{
id: webView
anchors.fill: parent
// Crash on app exit, if you uncomment this line:
//url: "https://www.qt.io"
}
Component.onCompleted: {
// Crash on app exit, if you uncomment this line:
webView.loadHtml("<html><head></head><body>Simple body</body></html>","")
}
}
viewer2.qml
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtWebView 1.1
ApplicationWindow {
visible: true
x: 100
y: 100
width: 500
height: 400
WebView{
id: webView
anchors.fill: parent
// Crash on app exit, if you uncomment this line:
//url: "https://www.qt.io"
}
Component.onCompleted: {
// Crash on app exit, if you uncomment this line:
webView.loadHtml("<html><head></head><body>Simple body</body></html>","")
}
}
I am using Qt5.12.0 on a Win7 desktop, and the used compiler is MSVC2017 32 bit.
Here is the Backtrace:
[11328:19036:0223/150952.613:FATAL:render_process_host_impl.cc(887)] Check failed: map_.empty().
Backtrace:
QWebEngineUrlSchemeHandler::_q_destroyedUrlSchemeHandler [0x11B4E857+810583]
QWebEngineUrlSchemeHandler::_q_destroyedUrlSchemeHandler [0x11B5BD11+865041]
QWebEngineUrlSchemeHandler::_q_destroyedUrlSchemeHandler [0x11A93A9E+45214]
QtWebEngineCore::JavaScriptDialogController::qt_static_metacall [0x1166ED0A+32480538]
QtWebEngineCore::JavaScriptDialogController::qt_static_metacall [0x1167185F+32491631]
GetHandleVerifier [0x12ED8CE9+20263193]
IsSandboxedProcess [0x1403328B+16485723]
IsSandboxedProcess [0x13A93802+10588882]
IsSandboxedProcess [0x1406445F+16686895]
IsSandboxedProcess [0x14063EDD+16685485]
QtWebEngineCore::JavaScriptDialogController::qt_static_metacall [0x10406C6D+13180029]
QtWebEngineCore::JavaScriptDialogController::qt_static_metacall [0x10406C41+13179985]
IsSandboxedProcess [0x13D95555+13742117]
QWebEngineUrlSchemeHandler::_q_destroyedUrlSchemeHandler [0x11AC020E+227342]
QWebEngineUrlSchemeHandler::_q_destroyedUrlSchemeHandler [0x11AC0148+227144]
QWebEngineUrlSchemeHandler::_q_destroyedUrlSchemeHandler [0x11ABF94F+225103]
QWebEngineUrlSchemeHandler::_q_destroyedUrlSchemeHandler [0x11ABF96F+225135]
QWebEngineUrlSchemeHandler::_q_destroyedUrlSchemeHandler [0x11ABFA2C+225324]
QtWebEngineCore::JavaScriptDialogController::qt_static_metacall [0x1115CC69+27163769]
QtWebEngineCore::ProfileAdapterClient::downloadInterruptReasonToString [0x0F70855F+2623]
QtWebEngineCore::ProfileAdapterClient::downloadInterruptReasonToString [0x0F7086A6+2950]
QtWebEngineCore::ProfileAdapterClient::downloadInterruptReasonToString [0x0F70888F+3439]
QtWebEngineCore::ProfileAdapter::checkPermission [0x0F705B56+230]
QtWebEngineCore::FilePickerController::mode [0x0F71EDBA+33066]
QtWebEngineCore::ProfileAdapter::~ProfileAdapter [0x0F7054E6+246]
QtWebEngineCore::ProfileAdapter::~ProfileAdapter [0x0F7055DD+493]
QtWebEngineCore::WebEngineSettings::setWebContentsAdapter [0x0F69BCEA+3418]
QtWebEngineCore::WebContentsAdapter::requestedUrl [0x0F741E5A+746]
QWebEngineUrlScheme::operator!= [0x0F74BB8B+3707]
QWebEngineUrlScheme::operator!= [0x0F74BCB7+4007]
QTextCodec::codecForHtml [0x5F98A3C2+3390559]
QTreeViewPrivate::layout [0x609525D6+456449]
main [0x001F6D24+628] (d:\anonymous\qml-user-js-crash\userjs\main.cpp:67)
WinMain [0x001F664D+173] (c:\users\qt\work\qt\qtbase\src\winmain\qtmain_win.cpp:104)
invoke_main [0x001F50AE+30] (d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:107)
__scrt_common_main_seh [0x001F4F47+343] (d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
__scrt_common_main [0x001F4DDD+13] (d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331)
WinMainCRTStartup [0x001F5128+8] (d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_winmain.cpp:17)
BaseThreadInitThunk [0x7694343D+18]
RtlInitializeExceptionChain [0x776A9802+99]
RtlInitializeExceptionChain [0x776A97D5+54]

I might be wrong, but maybe this' got something to do with:
class PySide2.QtQuickWidgets.QQuickWidget(engine, parent)¶
PySide2.QtQuickWidgets.QQuickWidget([parent=None])
PySide2.QtQuickWidgets.QQuickWidget(source[, parent=None])
param parent PySide2.QtWidgets.QWidget
param source PySide2.QtCore.QUrl
param engine PySide2.QtQml.QQmlEngine
Constructs a QQuickWidget with the given QML engine and parent .
Note: In this case, the QQuickWidget does not own the given engine
object; it is the caller’s responsibility to destroy the engine. If
the engine is deleted before the view, status() will return Error .
source: https://doc.qt.io/qtforpython-5/PySide2/QtQuickWidgets/QQuickWidget.html#PySide2.QtQuickWidgets.PySide2.QtQuickWidgets.QQuickWidget

Related

View PDF in QML WebView

I would like to view a PDF file in a WebView created in my QML code. I am importing QtWebView 1.1 and setting the url property to the path of the PDF file but I am getting this error:
[13044:12820:0314/144814.854:ERROR:in_progress_cache_impl.cc(192)]
Cache is not initialized, cannot RetrieveEntry.
[13044:12820:0314/144814.854:ERROR:in_progress_cache_impl.cc(176)]
Cache is not initialized, cannot AddOrReplaceEntry.
[13044:12820:0314/144814.854:ERROR:in_progress_cache_impl.cc(192)]
Cache is not initialized, cannot RetrieveEntry.
When I use the same code to view an image it works. This question: Display PDF file with QWebView is close to what I want but QML does not seem to give me access to the settings method the way that C++ does (WebView docs). Is there some other way to do this?
It seems that you are confusing elements, QWebView belongs to QtWebkit (uses Webkit) that no longer exists in Qt and that was replaced by Qt WebEngine (uses chromium). And another thing is WebView of Qt WebView that uses the native APIs (for example Android does not support Qt WebEngine but if WebView).
Qt WebEngine and Qt WebView does not support PDF visualization (Qt WenEngine will support it very soon) natively so a solution is to use some js library that does it as PDF.js so that is the alternative that I propose in base to an old answer.
*.pro
QT += quick webview
CONFIG += c++11
SOURCES += main.cpp
RESOURCES += qml.qrc
COPY_CONFIG = 3rdParty example.pdf
copy_cmd.input = COPY_CONFIG
copy_cmd.output = ${QMAKE_FILE_IN_BASE}${QMAKE_FILE_EXT}
copy_cmd.commands = $$QMAKE_COPY_DIR ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_cmd.CONFIG += no_link_no_clean
copy_cmd.variable_out = PRE_TARGETDEPS
QMAKE_EXTRA_COMPILERS += copy_cmd
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtWebView>
class PDFJS: public QObject
{
Q_OBJECT
Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged)
QString m_version;
public:
QString version() const{
return m_version;
}
void setVersion(QString version){
if (m_version == version)
return;
m_version = version;
Q_EMIT versionChanged(m_version);
}
Q_SIGNAL void versionChanged(QString version);
Q_INVOKABLE QUrl getUrl(const QUrl & path){
QString pdfjs_path = QDir::current().filePath(QString("3rdParty/pdfjs-%1-dist/web/viewer.html").arg(m_version));
QUrl pdf_url = QUrl::fromLocalFile(pdfjs_path);
QUrlQuery query;
query.addQueryItem("file", path.toString());
pdf_url.setQuery(query);
return pdf_url;
}
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QtWebView::initialize();
QQmlApplicationEngine engine;
PDFJS pdfjs;
engine.rootContext()->setContextProperty("applicationDirPath", QGuiApplication::applicationDirPath());
engine.rootContext()->setContextProperty("PDFJS", &pdfjs);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtWebView 1.1
Window {
visible: true
width: 640
height: 480
title: qsTr("PDFJS Example")
WebView{
id: webview
anchors.fill: parent
}
Component.onCompleted:{
PDFJS.version = "2.1.266"
webview.url = PDFJS.getUrl("file://" + applicationDirPath + "/example.pdf")
}
}
You can find the complete project here
Update: only QML
.
|-- 3rdParty
| `-- pdfjs-2.1.266-dist
|-- example.pdf
`-- main.qml
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtWebView 1.1
Window {
visible: true
width: 640
height: 480
title: qsTr("PDFJS Example")
WebView{
id: webview
anchors.fill: parent
}
Component.onCompleted:{
var pdfjs_path = Qt.resolvedUrl("3rdParty/pdfjs-2.1.266-dist/web/viewer.html")
var path = Qt.resolvedUrl("example.pdf");
var url = pdfjs_path + "?file=%1".arg(path)
console.log(url)
webview.url = url
}
}
This part of the project you find here
Another option to this problem is to look into the Poppler Library. This library can be used to convert a page in a PDF to an image. Take a look into the Poppler::Page object's renderToImage. The image can then be displayed on a QQuickPaintedItem. Hope this helps someone.

According to CodeXL, I'm not succeeding in disabling the ANGLE layer in Qt

I've taken all care to disable the ANGLE layer in my Qt app, but apparently it's not happening. When I run the app in the CodeXL debugger, the event log contains lines like:
DLL Loaded: C:\Windows\SysWOW64\d3d11.dll
So it's loading Direct3D, which in Qt only happens via ANGLE I think. Also hitting the "Break" button in CodeXL does nothing, which to me means that no real OpenGL calls are happening, they're getting translated to D3D only.
The event log also says this:
Debug String: Failed to load opengl32.dll (The specified module could not be found.)
Why might that happen, how can I fix it?
The reason I want to disable ANGLE is because otherwise I can't debug with CodeXL (it doesn't support D3D debugging).
My system:
Windows 10
First GPU: Intel HD Graphics 5500
Second GPU: AMD Radeon R5 M330 (I think this is the one my app uses)
My code:
main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickFramebufferObject>
#include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject>
#include <QQuickWindow>
class MyItem : public QQuickFramebufferObject {
Q_OBJECT
public:
Renderer* createRenderer() const;
};
class MyItemRenderer : public QQuickFramebufferObject::Renderer {
public:
void render() {
update();
}
QOpenGLFramebufferObject* createFramebufferObject(const QSize &size) {
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
return new QOpenGLFramebufferObject(size, format);
}
};
QQuickFramebufferObject::Renderer* MyItem::createRenderer() const {
return new MyItemRenderer();
}
int main(int argc, char **argv) {
qputenv("QT_OPENGL_BUGLIST", "Z:/disable_angle.txt");
QGuiApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
QGuiApplication app(argc, argv);
qmlRegisterType<MyItem>("MyItem", 1, 0, "MyItem");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
#include "main.moc"
main.qml:
import QtQuick 2.0
import MyItem 1.0
import QtQuick.Window 2.2
Window {
visible: true
width: 400
height: 400
MyItem {
anchors.fill: parent
}
}
Z:/disable_angle.txt:
{
"entries": [
{
"id": 1,
"description": "Disable angle",
"os": {
"type": "win"
},
"features": [
"disable_angle"
]
}
]
}
Set QT_LOGGING_RULES environment variable to 'qt.qpa.gl=true'. Thus, you will see some additional debug output that will help to understand what exactly Qt chooses (opengl/angle/software).
Try changing Z:/disable_angle.txt to Z:\disable_angle.txt
Note the backslash :) It's Windows, so this may be the culprit.
Apart from disable_angle (your config seems correct to me), try also setting disable_d3d11 and disable_d3d9.
"disable_angle", "disable_d3d11", "disable_d3d9"
If you want to completely disable Angle, you should set the application attribute Qt::AA_UseDesktopOpenGL. If this is not enough, linking against OpenGL32.lib might help.

Qml QTouchDevice

I am new in Qt. I am working on windows desktop application and using Qt with qml. On PC that hasn't QTouchDevices, splitter between component (element that allow you resize component on window) works good with mouse (screenshot "Good distance"), but if screen is touchscreen I have next problem, please look on screenshot "Wrong distance".
My application shouldn't support any touch device. So how to disable this Qt feature? I need the same behavior like on device without touch screen.
Wrong distance
Good distance
I have tried disable touch device using privet methods using next sample:
QWindowSystemInterface::unregisterTouchDevice(QTouchDevice::devices().first());
This works, but QWindowSystemInterface is private class and it disable touchscreen. And one more in QTCreator splitters work fine, exactly as I need.
If you can't patch Qt, the only way that I can think of would be to iterate through the children, searching for the MouseArea. For example, suppose you had this QML:
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
ApplicationWindow {
width: 600
height: 400
visible: true
property alias splitView: splitView
SplitView {
id: splitView
anchors.fill: parent
Rectangle {
width: 200
Layout.maximumWidth: 400
color: "lightblue"
Text {
text: "View 1"
anchors.centerIn: parent
}
}
Rectangle {
id: centerItem
Layout.minimumWidth: 50
Layout.fillWidth: true
color: "lightgray"
Text {
text: "View 2"
anchors.centerIn: parent
}
}
}
}
You could then print out the object tree of the SplitView like so:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include <QDebug>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *window = engine.rootObjects().first();
QQuickItem *splitView = window->property("splitView").value<QQuickItem*>();
splitView->dumpObjectTree();
return app.exec();
}
That gives you:
SplitView_QMLTYPE_1::
QQmlComponent::
QQuickSystemPalette::
QObject_QML_2::
QQmlComponent::
QQuickItem::
QQuickItem::
QQuickItem::
QQuickLoader_QML_3::
QObject_QML_4::
QQuickMouseArea_QML_5::
QQuickRectangle::
QQmlContext::
QQuickItem::
QQmlComponentAttached::
QQuickRectangle::
QQuickText::
QQuickLayoutAttached::
QQuickRectangle::
QQuickText::
QQuickLayoutAttached::
QQuickLayoutAttached::
QObject::dumpObjectTree() prints out metaObject->className(), so we know to look for an object whose metaObject has a className matching that:
Then:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include <QScreen>
#include <QWindow>
#include <QDebug>
QQuickItem *findMouseArea(QQuickItem *item)
{
foreach (QQuickItem *childItem, item->childItems()) {
if (QString(childItem->metaObject()->className()).startsWith(QStringLiteral("QQuickMouseArea_QML"))) {
return childItem;
} else {
QQuickItem *mouseArea = findMouseArea(childItem);
if (mouseArea) {
return mouseArea;
}
}
}
return 0;
}
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QWindow *window = qobject_cast<QWindow*>(engine.rootObjects().first());
QQuickItem *splitView = window->property("splitView").value<QQuickItem*>();
QQuickItem *mouseArea = findMouseArea(splitView);
mouseArea->setProperty("defaultMargin", QVariant(window->screen()->physicalDotsPerInch() / 25.4));
return app.exec();
}
Apparently, Screen::pixelDensity is calculated using the physical dots per inch of the screen, divided by 25.4, so we copy that as well. You could use any other value there.
You will need to adapt the code should a second MouseArea ever be introduced, for example.
It's still largely dependent on private API, but it doesn't touch Qt code, at least.
Quick&Easy: enable/disable mouse and touch synthesizing
No need to patch things or doing any crazy tree lookups, just enable or disable mouse or touch synthesizing.
Qt::AA_SynthesizeTouchForUnhandledMouseEvents
Qt::AA_SynthesizeMouseForUnhandledTouchEvents
Just disable what you don't want, either mouse or touch to accept only authentic events.

Including a web viewer in Qt Creator App

I'm pretty new to Qt and I'm trying to add a web viewer to an app.
I have an app with 3 windows and a navigation bar with 3 buttons. When I click on a button, it swipe to the window associated.
I would have one of this button open the web viewer, without exiting the app.
The app have to be compatible with mobile (Android, iOS, Windows Phone) also.
I searched and found QtWebengine but it doesn't really help me...
I'm on Qt Creator 3.4.2, Qt 5.5.0 and using Qt Designer (don't know if it's important...)
Coding in C++ and QML.
Thanks.
EDIT: I read about the Webview doc but it's still confusing...
I saw that there is a Webkit Webview and a WbeEngine Webview. Webkit is being deprecated so I would like to use WebEngine.
So I try the MiniBrowser Example, which uses WebEngine Webview, and it works on the platforms I want.
But I can't figure how I can launch it by clicking a button...
I tried this :
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(slot_test()));
}
void MainWindow::slot_test()
{
this->webview();
}
MainWindow::~MainWindow()
{
delete ui;
}
webview.cpp
#include <QtCore/QUrl>
#include <QQmlApplicationEngine>
#include <QtCore/QCommandLineOption>
#include <QtCore/QCommandLineParser>
#include <QGuiApplication>
#include <QStyleHints>
#include <QScreen>
#include <QtQml/QQmlContext>
#include <mainwindow.h> //
#ifdef QT_WEBVIEW_WEBENGINE_BACKEND
#include <QtWebEngine>
#endif /* QT_WEBVIEW_WEBENGINE_BACKEND */
void MainWindow::webview()
{
#ifdef Q_OS_OSX
// On OS X, correct WebView / QtQuick compositing and stacking requires running
// Qt in layer-backed mode, which again resuires rendering on the Gui thread.
qWarning("Setting QT_MAC_WANTS_LAYER=1 and QSG_RENDER_LOOP=basic");
qputenv("QT_MAC_WANTS_LAYER", "1");
qputenv("QSG_RENDER_LOOP", "basic");
#endif /* Q_OS_OSX */
#ifdef QT_WEBVIEW_WEBENGINE_BACKEND
QtWebEngine::initialize();
#endif /* QT_WEBVIEW_WEBENGINE_BACKEND */
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/base/main.qml")));
}
main.qml
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtWebView 1.0
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.2
ApplicationWindow {
visible: true
x: 500
y: 500
width: 500
height: 500
title: webView.title
statusBar: StatusBar {
id: statusBar
visible: webView.loading && Qt.platform.os !== "ios"
RowLayout {
anchors.fill: parent
Label { text: webView.loadProgress == 100 ? qsTr("Done") : qsTr("Loading: ") + webView.loadProgress + "%" }
}
}
WebView {
id: webView
anchors.fill: parent
url: "https://www.google.fr"
}
}
(The webview.cpp is a simplified version of the MiniBrowser example)
When I try to launch it (in Desktop version or Android) and click on the Push Button, the Webview open in an other window and close immediately.
I don't know how to solve this...
You can use QtWebKit but it is deprecated: http://doc.qt.io/qt-5/qtwebkit-index.html
You can use QtWebEngine but it doesn't support all the platforms you need.

QtQuick, how to know if a application was compiled on debug or release mode?

At Qt/C++ there is QT_DEBUG define macro to know when it is compiled at debug or release.
Is there any method to know if is the application running in debug o release mode inside a QML file?
You can use context properties (or QQmlApplicationEngine::setInitialProperties() since Qt 5.14) to expose C++ objects to QML:
#include <QtGui/QGuiApplication>
#include <QQmlContext>
#include <QQuickView>
#include "qtquick2applicationviewer.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
#ifdef QT_DEBUG
viewer.rootContext()->setContextProperty("debug", true);
#else
viewer.rootContext()->setContextProperty("debug", false);
#endif
viewer.setMainQmlFile(QStringLiteral("qml/quick/main.qml"));
viewer.showExpanded();
return app.exec();
}
main.qml:
import QtQuick 2.2
Item {
id: scene
width: 360
height: 360
Text {
anchors.centerIn: parent
text: debug
}
}
It's not possible to determine this purely from within QML.
You need to know it in runtime or in compile time? Macros are used in compile time, QML is executed in runtime, so there are no difference for compiled application between "debug" and "release".
Solution:
Create a class with const property declared in next way:
class IsDebug : public QObject
{
QOBJECT
Q_PROPERTY( IsDebug READ IsCompiledInDebug ) // Mb some extra arguments for QML access
public:
bool IsCompiledInDebug() const { return m_isDebugBuild; }
IsDebug()
#ifdef QT_DEBUG
: m_isDebugBuild( true )
#else
: m_isDebugBuild( false )
#endif
{}
private:
const bool m_isDebugBuild;
}

Resources