Zoom feature for QWebEngine does not work - qt

I created simple project for displaying local .html page.
I used Qt5.4 with QWebView there. But after switching to Qt5.6 I noticed
that Qt WebKit is deprecated and not supported any more.
Thus I decided to replace Qt WebKit functionality with one from the
Qt WebEngine.
After replacing QWebView with QWebEngineView
I investigated that setZoomFactor method has no effect.
Is it known issue? How can I handle with this?
EDIT:
An interesting thing have been investigated recently. I use setHtml method for setting content of local .html files to my QWebEngineView. These files also contain references to images. So I set baseUrl parameter as a relative path to required images. In that case using of setZoomFactor method has no effect.
But when I don't set relative path to images as parameter, images are absent on QWebEngineView but zoom functionality works. Any ideas what is wrong here?

Setting zoomFactor for QML WebEngineView in Qt 5.11 using QML zoomFactor property or C++ setZoomFactor (private-API) did not work as expected. I discovered from comments in QT Bug 51992 that it works when set after a page load.
QML solution:
WebEngineView {
// ...
onLoadingChanged: {
zoomFactor = 0.75
}
}
QWebEngineView solution: connect to the loadFinished signal, and set zoomFactor after each page load:
main.cpp (after engine.load call):
QWebEngineView *webView; // = ...
QObject::connect(webView, &QWebEngineView::loadFinished,
[=](bool arg) {
webView->setZoomFactor(zoomFactor);
});

It seems to be a known bug in this version of Qt. You can check by yourself here : Qt Bug 51992.
Basically, it is said that :
This looks like a known glitch that is currently happening because of
the Chromium API that we use for setting the zoom factor.
And also :
Chromium limits the zoom factor to a maximum of 5.0 - any calls with a
number higher than that will have no effect.
Hope that will help you.

The setZoomFactor does not function properly in the QT 5.15 release.
Call setZoomFactor multiple times to resolve the problem.
WebEngineView {
function setZoomFactor(real) {
zoomFactor = real
zoomFactor = real
zoomFactor = real
}
}

Related

GStreamer d3dvideosink overlay repaint flicker

I've got a quite persistent problem regarding the d3dvideosink.
My GStreamer pipeline is written by using the GStreamer SDK 1.14.2 in Qt/C++ and looks like this:
videotestsrc -> d3dvideosink
I use gst_video_overlay_set_window_handle to place the sinks output over the corresponding QWidget (using WId QWidget::winId() const).
The stream works as expected, but will produce flicker whenever the widget (or any parent widget) is repainting (e.g. while resizing).
How can I configure the widget / pipeline / d3dvideosink / ... to eliminate flickers ?
P.S. Using glimagesink instead of d3dvideosink works, but will be less performant.
Disable Qt repaints over the Window. To do this:
setAttribute(Qt::WA_PaintOnScreen);
Overload paintEngine() to return nullptr.

How to change WebView settings from QML

I'm using a simple WebView in my QML file.
WebView {
anchors.fill: parent
url: "file:///android_asset/example.html"
}
The problem is, that I'm getting an error about access-control-allow-origin is null. I found a fix for this here, which is using WebView settings property. It seems to be accessible from c++, but I haven't found any way of using this property from qml. So how can I use WebView settings from QML to get rid of the error? I'm using Qt 5.10.
Use Qt's resource system, add the file to it, and load the file via
url: "qrc:///android_assets/example.html"

QWebView Open in new Window

I want to open links from a QWebView with target="_blank" in a new window of a new process.
I tried using QWebView::createWindow(QWebPage::WebWindowType), but I didn't find a way to get the url to send to the new process. Actually, I tried a hack to get the url using a hidden QWebView (returned by the createWindow method) with the urlChanged event, but sometimes this event is triggered twice, so it is not reliable.
Is there any way to get the URL in the createWindow method?
If not, what can I do to open this kind of links in a new window of a new process?
I found a way to do what I want.
I had to overload the mousePressEvent to get the mouse position so that I can get the url from it.
Here is the code:
QWebView* WebView::createWindow(QWebPage::WebWindowType) {
QWebHitTestResult result{page()->mainFrame()->hitTestContent(lastClickPosition)};
openNewWindow(result.linkUrl());
return nullptr;
}
void WebView::mousePressEvent(QMouseEvent* mouseEvent) {
lastClickPosition = mouseEvent->pos();
QWebView::mousePressEvent(mouseEvent);
}
I let this question opened a few days to see if anyone can find a better solution.
If you're trying for a multi-process webview architecture, I would suggest looking at QtWebEngine. QtWebEngine will be replacing QtWebKit and is based on Chromium. Because of this, it has a multi-process architecture by default. QtWebEngine will no longer be updated, so I would suggest migrating to QtWebEngine anyway.
QtWebEngine overview

How to get the contentSize of a web page in Qt5.4-QtWebEngine

I'm using the new Qt5.4 with the module QtWebEngine and from what I see mainFrame() doesn't exists anymore. How to get the contentSize/size of the page and how to render it now? I tried with the setView and view but doesn't work.
I couldn't find any native Qt method for that, but I came up with a workaround:
once the page is loaded, I do the following to resize my widget to the web content:
webView->page()->runJavaScript("document.documentElement.scrollWidth;",[=](QVariant result){
int newWidth=result.toInt()+10;
webView->resize(newWidth,webView->height());
});
webView->page()->runJavaScript("document.documentElement.scrollHeight;",[=](QVariant result){
int newHeight=result.toInt();
webView->resize(webView->width(),newHeight);
});
NB: I added a 10px width margin
Check if the QWebEnginePage::geometryChangeRequested signal does what you want.
Also you display a QWebEnginePage by creating a QWebEngineView (it's a QWidget) and calling QWebEngineView::setPage(yourPage).

Transparency of QDeclarativeView containing QML on top of a QWidget playing a video (using either phonon or libvlc)

I am currently developing a video player.
The GUI as the topmost layer is written in QML. It should be transparent to lower layers. It contains control elements, some Lists etc., It's displayed using a QDeclarativeView.
Description
QDeclarativeView *upperLayer = new QDeclarativeView(this);
upperLayer->setSource(QUrl("/home/projects/QtVideo/qml/videoControl.qml"));
upperLayer->setStyleSheet(QString("background: transparent");
upperLayer->setResizeMode(QDeclarativeView::SizeRootObjectToView);
uperLayer->showFullScreen();
The layer underneath is a QWidget: I use the libvlc to display the video content
in this widget.
Reason: I am receiving MPEG-TS, which can not be decoded by phonon, afaik. Therefore I need the libvlc to decode the incoming *.ts stream and put the output onto the display.
QWidget *lowerLayer = new QWidget(this);
lowerLayer.setGeometry(QString("background: red"));
QUrl* url = new QUrl("file:///home/projects/QtVideo/video.ts");
libvlc_instance_t*vlcObject;
libvlc_media_t*vlcMedia;
libvlc_media_player_t*vlcPlayer;
vlcPlayer = NULL;
if(vlcObject = libvlc_new(argc, argv)) == NULL)
{
printf("Not able to initialize";
exit(1);
}
if(vlcPlayer && libvlc_media_player_is_playing(vlcPlayer))
{
libvlc_media_player_stop(vlcPlayer);
}
vlcPlayer = libvlc_media_player_new(vlcObject);
vlcMedia = libvlc_media_new_location(vlcObject, url.toString().toUtf8().constData());
libvlc_media_player_set_media(vlcPlayer, vlcMedia);
#if defined(Q_OS_MAC)
libvlc_media_player_set_nsobject(vlcPlayer, lowerLayer->winId());
#elif defined(Q_OS_UNIX)
libvlc_media_player_set_x_window(vlcPlayer, lowerLayer->winId());
#elif defined(Q_OS_WIN)
libvlc_media_player_set_hwnd(vlcPlayer, lowerLayer->winId());
#endif
libvlc_media_player_play(vlc_player);
Both Elements, the QDeclarativeView and the QWidget
are embedded in a QMainWindow, lowerLayer created before the upperLayer,
upperLayer Transparent to the lowerLayer.
The Problem:
As long as the lowerLayer is displaying static elements such as a picture, or some colored shapes, everything works fine, full transparency and functionality.
As soon as I start displaying a video, such as the described *.ts using the libvlc OR some random video using the Phonon::VideoPlayer, the parts of the upperLayer which are above the video parts of the lowerLayer are displayed in the color of the lowerLayer(default: gray), the parts of the upperLayer which are positioned above parts of the lowerLayer or others which do not contain video elements are displayed in correct behaviour.
Question:
Is there any posibility and if, how, to get the upperLayer transparent, even if there is a video playing?
Are you still fighting with this issue? I, sadly, do not have a satisfying answer for you. The best I can do is point you to reasons why it doesn't work:
http://lists.trolltech.com/qt-interest/2007-02/thread01061-0.html
See Message #4 in the link above.
I have tried many different methods to get transparent painting over a video (specifically Phonon::VideoPlayer) using Qt. The only method I've found so far, is to set the overlaying QWidget as a toolTip doing something like
pWidget->setWindowFlags(Qt::ToolTip)
Depending on what exactly you're wanting to do this may be sufficient, but (in my opinion) it's a hack at best. I'm actively struggling with this issue and if I can find some sort of solution, I'll be sure to post it here.
Best of luck.
you're using direct rendering (by passing the wid of the widget) which draws the video overtop at that geometry:
libvlc_media_player_set_x_window
you need to use offscreen rendering and draw that to your qwidget. this can be done with an opengl context (complicated) or using the callback methods available in libvlc.
if you use the display callback (libvlc_video_display_cb) libvlc will also generate lock/unlock methods also, if you need. in this method libvlc will expect some parameters to be set such as canvas geometry and pixel format.
that said, phonon has a libvlc backend which might help, but may still use direct rendering depending on some factors..

Resources