Cesar
Cesar

Reputation: 389

How to make WA_TranslucentBackground work on Windows without using FramelessWindowHint?

Im using setAttribute(Qt::WA_TranslucentBackground); to make my QMainWindow background transparent, however, this attribute only work if:

I also set: setWindowFlag(Qt::FramelessWindowHint); or, have at least one QOpenGLWidget in my GUI.

I have no experience with QOpenGlWidget, i wonder if its possible to use QSurfaceFormat or something like, to achieve the same 'thing' QOpenGL does when added to a QMainWindow, that makes the attribute work.

Or if there's any other 'option' than setting the FramelessWindowHint flag or creating an QOpenGL widget.

Example code:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    /*
    QSurfaceFormat format;
    format.setAlphaBufferSize(8);
    QSurfaceFormat::setDefaultFormat(format);


    QSurfaceFormat format;
    format.setAlphaBufferSize(8);
    format.setSamples(16);
    format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
    format.setRenderableType(QSurfaceFormat::OpenGL);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);
    */

    MainWindow w;

    w.show();
    return a.exec();
}

//mainwindow.h
#include <QtWidgets/QMainWindow>
#include "ui_MainWindow.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindowClass; };
QT_END_NAMESPACE

class MainWindow : public QMainWindow{
    Q_OBJECT
public:
    MainWindow(QWidget* parent = nullptr);
}

//mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) 
    : QMainWindow(parent), ui(new Ui::MainWindowClass())
{
    ui->setupUi(this);

    setAttribute(Qt::WA_TranslucentBackground);

    QGridLayout* layout = new QGridLayout();
    ui->centralWidget->setStyleSheet("background-color: transparent;");
    ui->centralWidget->setLayout(layout);
    QWidget* widget = new QWidget(this);
    widget->setStyleSheet("background-color: green; border-radius: 32px;");
    layout->addWidget(widget);
    
    //QOpenGLWidget* opengl = new QOpenGLWidget(this);
    //opengl->deleteLater();
}

Creating the QOpenGlWidget and calling opengl->deleteLater() the WA_TranslucentBackground works, however, it make the application use 50mb more of ram compared to not creating the QOpenGLWidget.

This is not much if i were creating just one GUI, but I'm creating multiples.

Upvotes: 0

Views: 633

Answers (1)

Franco
Franco

Reputation: 15

Unfortunately this is not possible on Windows. You can set transparency for widget with color with alpha-channel like this: setStyleSheet("background-color: rgba(255,0,0,50%);"); But this doesn't work for top level widget until you set the WA_TranslucentBackground flag. Without this flag alpha-channel doesn't work and you get black window. So the only solution is use WA_TranslucentBackground. And then do OpenGL painting like Qt documentation says:

To work around this issue you can either just use Qt to render everything and not OpenGL, or you can render the OpenGL into a pixmap and draw that onto your widget instead.

Upvotes: 0

Related Questions