0

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.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Cesar
  • 41
  • 2
  • 5
  • 16

1 Answers1

0

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.

Franco
  • 3
  • 7
  • This makes the window completely invisible including her children. I would like only the background to get transparent. – Cesar Feb 13 '23 at 14:03
  • Set the background color of the children: `m_childWidget->setStyleSheet("background-color: grey");` In my case it works – Franco Feb 13 '23 at 15:55
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 14 '23 at 08:16