3

Perhaps this is a bug. There is a top level widget that must have a drop shadow. Inside that widget I want to display a browser (only to be able to render html). The top level widget's opacity must be adjustable. For the dropshadow to work as expect (not show a black border) we need Qt::WA_TranslucentBackground to be set to true. But then the opacity changing does not work. Why? But what really bothers me is that if you replace the browser widget with any other widget, say a QTextEdit, the opacity changing works always, including with drop shadow.

I am using Qt5.8 with msvc2015 on Windows 8.1 host. Here is a working minimal example:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>
#include <QWebEngineView>
#include <QWebEnginePage>
#include <QVBoxLayout>
#include <QSlider>
#include <QGraphicsDropShadowEffect>

class TestWidget : public QWidget
{
    Q_OBJECT
public:
    explicit TestWidget(QWidget *parent = 0){
        this->setStyleSheet(".QWidget{color: qlineargradient(spread:pad, x1:0 y1:0, x2:1 y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));"
                               "background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 cyan, stop:1 blue);}");

        QWebEngineView *view = new QWebEngineView;
        view->setUrl( QUrl("https://www.google.de") );
        this->setLayout(new QVBoxLayout);

        view->page()->setBackgroundColor(QColor(Qt::transparent));

        QWidget *container = new QWidget;
        container->setLayout( new QVBoxLayout );
        container->layout()->setContentsMargins(0,0,0,0);
        container->layout()->addWidget( view );
        this->layout()->addWidget( container );

        QSlider *slider = new QSlider;
        slider->setOrientation(Qt::Horizontal);
        slider->setFixedWidth(200);
        slider->setMinimum(20);
        slider->setValue(20);
        slider->setMaximum(100);
        connect(slider,&QSlider::valueChanged,this,
                [this](int value){
            this->setWindowOpacity(1.0 * value / 100.0);
        });
        slider->show();

        this->setAttribute(Qt::WA_TranslucentBackground,true);
        Qt::WindowFlags flags = 0;
        flags |= Qt::SplashScreen;
        flags |= Qt::FramelessWindowHint;
        setWindowFlags(flags);

        QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect;
        shadow->setBlurRadius(10);
        shadow->setOffset(0,2);
        shadow->setEnabled(true);
        setGraphicsEffect(shadow);
    }

    ~TestWidget(){}
};

#endif // MAINWINDOW_H

pro file:

QT       += core gui webenginewidgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = transparent-webpage-over-widget
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += main.cpp

HEADERS  += mainwindow.h
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
user2366975
  • 4,350
  • 9
  • 47
  • 87
  • Interesting. I wonder if the Blink engine even supports transparent windows? I've never seen a browser that had this feature. – MrEricSir Apr 01 '17 at 00:27
  • If you remove the window attribute, changing the opacity works, but then you get a black border. but it might still be related to blink... – user2366975 Apr 01 '17 at 09:34
  • I noticed it even does not work if I set a parent to the webview, without adding the webview to a layout. – user2366975 Apr 06 '17 at 19:04
  • If you don't need any interaction with content, you may render a webpage to an image and show it as you want. – Dmitry Sazonov Apr 10 '17 at 10:29
  • Interaction is the main point, so this is no solution for me. In the meantime I figured out that it works with WebKit. Too bad it has been removed from Qt in favor of Blink, the latter using even more memory, too make things worse. From a user's perspective this was a bad decision. Moreover I noticed that with WebKit, I get clear and crisp fonts for free, which was also a problem I had with blink (see this [post](http://stackoverflow.com/questions/43161662/rendered-text-looks-very-different-in-qt-and-blink-although-same-font-is-set)) – user2366975 Apr 10 '17 at 14:09

1 Answers1

2

As mentioned in https://bugreports.qt.io/browse/QTBUG-41960, this is now working by simply using this line:

webEngineView->page()->setBackgroundColor(Qt::transparent);

I've tried it in Qt 5.6 and it works well.

In order to make this answer more helpful, let me show all relevant code.

In MainWindow, I have set this:

setAttribute(Qt::WA_TranslucentBackground);
setAutoFillBackground(true);
setWindowFlags(Qt::FramelessWindowHint);

For the webEngineView object, I have set these attributes:

webEngineView->setAttribute(Qt::WA_TranslucentBackground);
webEngineView->setStyleSheet("background:transparent");
webEnginePage = webEngineView->page();
// https://bugreports.qt.io/browse/QTBUG-41960
webEnginePage->setBackgroundColor(Qt::transparent);

In your HTML, use transparent background in your CSS, like this:

body { background: transparent; }

otherwise, I think by default the HTML would have a white background

I hope it helps.

  • If you really used my code to verify your answer, please update your answer with a working copy **of the complete header file**. Basically I don't see any difference, and it does not work. – user2366975 Apr 13 '17 at 22:20