Hiding widgets in a QMainWindow layout with a translucent background on macOS

52 Views Asked by At

Using Qt 6.5.1, I got QMainWindow with WA_TranslucentBackground. I want to hide and show some elements in its layout. It looks like the layout or background doesn't repaint after hiding the widget.

Before hiding btn2:

After hiding btn2:

I made a sample to demonstrate this:

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "QtWidgets/qboxlayout.h"
#include "QtWidgets/qpushbutton.h"
#include "ui_mainwindow.h"
#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
    QWidget *centralWidget;
    QVBoxLayout *btnsLayout;
    QPushButton *btn1;
    QPushButton *btn2;

    Ui::MainWindow *ui;

  public:
    MainWindow(QWidget *parent = nullptr)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);

        setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint | Qt::Window);
        setAttribute(Qt::WA_NoSystemBackground, true);
        setAttribute(Qt::WA_TranslucentBackground, true);

        btn1 = new QPushButton("btn1", this);
        btn2 = new QPushButton("btn2", this);
        btnsLayout = new QVBoxLayout;
        btnsLayout->addWidget(btn1);
        btnsLayout->addWidget(btn2);

        connect(btn1, &QPushButton::clicked, this, &MainWindow::onBtnClick);

        centralWidget = new QWidget(this);
        centralWidget->setLayout(btnsLayout);

        setCentralWidget(centralWidget);
    }
    ~MainWindow() { delete ui; }

  public slots:
    void onBtnClick(bool)
    {
        btn2->hide();

        // works!
        // setVisible(false);
        // setVisible(true);
        //}
    }
};
#endif // MAINWINDOW_H

I'm ok with the layout moving btn1, but I need to get rid of the "shadows" of the buttons.

I tried removeWidget, delete btn2, btnsLayout->update(), MainWindow::update(), and repaint, nothing helps.

The only workaround I found is to hide and show the entire mainwindow, but I think there's a better way.

0

There are 0 best solutions below