Qt WebEngine url blocking - c++

I would like to ask you a question, how to correctly block some url access. I would like to block access to URLs like "file:///" on QtWebEngine. I was searching something about WebUrlRequestInterceptor and QWebEngineUrlSchemeHandler but, did I find the right answer?
// main.qml
import QtQuick 2.0
import QtQuick.Window 2.0
import QtWebEngine 1.1
Window {
id: window
width: 800
height: 600
WebEngineView {
id: webView
anchors.fill: parent
url: "file:///"
}
}
// request.cpp
#include <QtCore/QRegExp>
#include "request.h"
WebUrlRequestInterceptor::WebUrlRequestInterceptor(QObject *p)
:QWebEngineUrlRequestInterceptor(p)
{
}
void WebUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) {
if(!info.requestUrl().toString().contains(QRegExp("(?:https?|ftp)://\\S+")))
info.block(true);
}
// main.cpp
#include <QtGui/QGuiApplication>
#include <QtCore/QCoreApplication>
#include <QtQml/QQmlApplicationEngine>
#include <QtWebEngine/QQuickWebEngineProfile>
#include <QtWebEngine/QtWebEngine>
#include <QtQuick/QQuickWindow>
#include "request.h"
int main(int argc, char **argv) {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QGuiApplication app(argc, argv);
WebUrlRequestInterceptor *wuri = new WebUrlRequestInterceptor;
QQuickWebEngineProfile::defaultProfile()->setUrlRequestInterceptor(wuri);
QQmlApplicationEngine engine;
engine.load(QStringLiteral("./main.qml"));
QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().first());
QRect rectangle;
rectangle.setWidth(800);
rectangle.setHeight(600);
window->setGeometry(rectangle);
window->show();
return app.exec();
}
Is it the right way, how I made it? I founded some flags here https://doc.qt.io/qt-5/qwebengineurlscheme.html#Flag-enum like QWebEngineUrlScheme::LocalAccessAllowed, but not sure, if this will help me. Isn't possible to control this list somehow https://admx.help/?Category=Chrome&Policy=Google.Policies.Chrome::URLBlocklist ?
Thank you

Related

How to choose the OpenGL context for QtQuick applications

I am writing an QtQuick application, mainly in QML, but I have some parts that use OpenGL more directly (an OpenSceneGraph scene). For some reasons, I want to use OpenGL version >= 3.3, but Qt only choose a 3.0 implementation. My code is:
main.cpp:
#include <QApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
// Create the app.
QApplication app(argc, argv);
// Start the UI.
QQmlApplicationEngine engine;
engine.load(QUrl("main.qml"));
return app.exec();
}
main.qml:
import QtQuick 2.7
import QtQuick.Controls 2.2
ApplicationWindow {
id: root
width: 800
height: 600
title: "App"
visible: true
Label {
text: "OpenGL: " + OpenGLInfo.majorVersion + ' ' + OpenGLInfo.minorVersion + OpenGLInfo.profile
}
}
One way of doing it is to set the default QSurfaceFormat before the app.exec().
#include <QSurfaceFormat>
...
QSurfaceFormat surfaceFormat;
surfaceFormat.setMajorVersion(3);
surfaceFormat.setMinorVersion(3);
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(surfaceFormat);

Global functions or macros to get Qt version in QML code

How Can I get Qt version, for example 5.11.2 or similar, in my QML code. In my C++ code I have these options:
Method available on C++:
qVersion();
Macro available on C++:
QT_VERSION
But I couldn't find anything on QML?
You could use a Context Property, as explained here.
A simple example, given a simple qml file like this:
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
Text {
text: qtversion
}
visible: true
width: 640
height: 480
title: qsTr("Hello World")
}
Set the qtversion property at startup, in main function:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("qtversion", QString(qVersion()));
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}

How to use GrabWindow?

I have found a class GrabWindow but I am a noobie in Qt Quick 2 and can't get how to use it.
Can a someone explain how can I use this view?
At this moment I added in my main function:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "grabwindow.h"
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<GrabWindow>("test", 1, 0, "GrabWindow");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/qml/SystemTray.qml")));
if (engine.rootObjects().isEmpty()) {
return -1;
}
GrabWindow grabWnd;
grabWnd.setResizeMode(QQuickView::SizeViewToRootObject);
grabWnd.setSource(QUrl(QStringLiteral("qrc:/qml/main.qml")));
grabWnd.setFlags(Qt::Popup);
grabWnd.show();
return app.exec();
}
And my main.qml:
import QtQuick 2.9
import QtQuick.Controls 2.2
ApplicationWindow {
id: window
visible: true
width: 320
height: 480
title: qsTr("test")
}
But on start I get that only:
How to get a screenshot using that class and remove a square at the left top corner of the screen?
ADDED
I use Ubuntu 17.10

QT5.3 How can I add my Qobject to the QQmlEngine and access it's Properties via QML?

I'm starting out with QT5.3, or rather QT in general.
Now I basically want to program C/C++ console applications and add a front-end.
I created a QT Quick Application and have trouble getting my back-end code to interact with the front-end.
What I have so far:
Main.qml :
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.2
Window {
visible: true
width: 360
height: 360
MouseArea {
anchors.fill: parent
onClicked: {
// Qt.quit();
}
}
Text {
text: w1.getRoll
anchors.centerIn: parent
}
Button {
onClicked: w1.roll
}
}
Main.cpp :
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "wuerfel.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Wuerfel w1;
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
engine.setContextForObject(&w1,engine.rootContext());
return app.exec();
}
Wuerfel.h :
#ifndef WUERFEL_H
#define WUERFEL_H
#include <QObject>
#include <time.h>
#include <cstdlib>
class Wuerfel : public QObject
{
Q_OBJECT
Q_PROPERTY(QString w1 READ getRoll WRITE roll NOTIFY rolled)
public:
explicit Wuerfel(QObject *parent = 0);
void roll(){
srand((unsigned) time(NULL));
head = rand() % 6 + 1;
emit rolled();
}
int getRoll(){
return head;
}
signals:
void rolled();
public slots:
private:
int head;
};
#endif // WUERFEL_H
Debug Error
I have no clue what I have to do. The Documentation and web search results with similar issues confuse me even more. They mention QQView or QComponent etc. but whenever I try one of their solutions, something is missing. Like the method mentioned is not part of the object, so it's not found etc.
Has anyone a clue how to get this working? I want to use this approach to visualize future console applications from a C++ tutorial. And developing front-ends in QT in general.
Thanks in Advance. =)
You can use QQmlContext::setContextProperty to set a value for your name property on the root context :
engine.rootContext()->setContextProperty("w1", &w1);

C++ type's destructor not called in QML

I create a Sailfish app (using latest Sailfish SDK). I have a problem with exposing a C++ object to QML. It inherits QSettings,
class Settings : public QSettings
{
Q_OBJECT
/**/
public:
explicit Settings() : QSettings("Marcin Mielniczuk", "BigText") {}
~Settings() { qDebug() << "Dying"; }
/**/
};
I noticed that the destructor isn't called at all. (there's not destructor output)
I create the object like that:
import QtQuick 2.0
import Sailfish.Silica 1.0
import BigText 1.0
import "pages"
ApplicationWindow
{
initialPage: MainPage { }
Settings {id: settings}
}
My main.cpp is:
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QGuiApplication> app(Sailfish::createApplication(argc, argv));
qmlRegisterType<Settings>("BigText", 1, 0, "Settings");
QScopedPointer<QQuickView> view(Sailfish::createView("main.qml"));
Sailfish::showView(view.data());
return app->exec();
}
What am I doing wrong?
/edit: Text not being printed isn't an actual problem - it's just an indicator of the problem. The QSettings sycing in the destructor doesn't work too.
EDIT2: Please note, that ApplicationWindow in I'm using Sailfish Silica, not QtQuick.Controls, and the window is shown ok. These components must be a somewhat different to the stock qt quick components.
There's nothing inherently wrong with your logic. Here is a simplified version of it. I can run it locally, and consistently get a Dying message on output every time the window is closed and the application terminates.
If you cannot figure it out, I suggest transforming this code into what you're doing until it fails.
By the way, this is surely just a snippet of something larger you're doing, but at least as far as the example goes, these scoped pointers aren't doing much.
main.qml
import QtQuick 2.0
import BigText 1.0
Item {
width: 300; height: 300
Settings {id: settings}
}
main.cpp
class Settings : public QSettings
{
Q_OBJECT
public:
Settings() : QSettings("Marcin Mielniczuk", "BigText") {}
~Settings() { qDebug() << "Dying"; }
};
int main(int argc, char *argv[])
{
QScopedPointer<QGuiApplication> app(new QGuiApplication(argc, argv));
qmlRegisterType<Settings>("BigText", 1, 0, "Settings");
QScopedPointer<QQuickView> view(new QQuickView());
view->setSource(QUrl::fromLocalFile("main.qml"));
view->show();
return app->exec();
}
You could try to put and id yo tour ApplicationWindow and explicity use the destroy() method at some time and see what happens.
You cannot use QQuickView with an ApplicationWindow class. Not only is your destructor not called, your constructor isn't either, because the loading doesn't ever succeed.
The code below works fine under Qt 5.1.1. Tested on both OS X 10.8 and Windows 7.
main.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
main.pro
QT += core gui qml quick
TARGET = qml-appwin-end-18597527
TEMPLATE = app
SOURCES += main.cpp
OTHER_FILES += main.qml
RESOURCES += main.qrc
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QSettings>
#include <QQuickWindow>
#include <QtQml>
#include <QDebug>
class Settings : public QSettings
{
Q_OBJECT
public:
Settings() : QSettings("Marcin Mielniczuk", "BigText") {}
~Settings() { qDebug() << "Dying"; }
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<Settings>("BigText", 1, 0, "Settings");
engine.load(QUrl("qrc:/main.qml"));
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
window->show();
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.0
import QtQuick.Controls 1.0
import BigText 1.0
ApplicationWindow {
width: 300; height: 300
Settings {id: settings}
}
Nothing is wrong with my code. It's something with the SDK. Debugging shows
ASSERT: "QThread::currentThread() == QCoreApplication::instance()->thread()" in file debugger/qqmldebugserver.cpp, line 576
Then the program is aborted and therefore destructor not called.