如何在QT中将QMDIArea设置为完全透明?
如何实现QMDIArea完全透明
我之前也碰到过这个问题,QMDIArea的透明设置确实有点棘手——因为它继承自QAbstractScrollArea,默认的背景绘制逻辑和普通控件不一样,单纯设置background:transparent和Qt::WA_TranslucentBackground根本不生效,它的灰色背景是内部视口(viewport)自动填充的。
下面给你两种可行的修改方案:
方案一:直接修改现有代码(无需子类化)
只需要在你的原有代码中添加几行关键设置,针对QMDIArea的视口和自动填充背景做调整:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QMdiArea *area = new QMdiArea(); // 1. 禁用QMDIArea的自动填充背景,避免它默认绘制灰色 area->setAutoFillBackground(false); // 2. 给内部视口设置透明属性,视口才是实际显示内容的区域 area->viewport()->setAttribute(Qt::WA_TranslucentBackground); // 3. 用样式表确保QMDIArea和它的视口都透明 area->setStyleSheet(R"( QMdiArea { background: transparent; } QMdiArea > QWidget { background: transparent; } )"); this->setCentralWidget(area); MyChildScreenDialog *dlg = new MyChildScreenDialog(); area->addSubWindow(dlg); }
方案二:子类化QMDIArea(更灵活,适合复杂场景)
如果后续需要对QMDIArea的绘制做更多自定义,可以子类化它,重写paintEvent来跳过背景绘制:
首先创建自定义的透明QMdiArea子类:
#include <QMdiArea> class TransparentMdiArea : public QMdiArea { Q_OBJECT public: explicit TransparentMdiArea(QWidget *parent = nullptr) : QMdiArea(parent) { // 基础透明设置 setAutoFillBackground(false); viewport()->setAttribute(Qt::WA_TranslucentBackground); } protected: void paintEvent(QPaintEvent *event) override { // 注释掉父类的paintEvent调用,就不会绘制默认的灰色背景 // QMdiArea::paintEvent(event); // 子窗口会自动被绘制,无需额外处理 } };
然后在MainWindow中使用这个子类:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); TransparentMdiArea *area = new TransparentMdiArea(); this->setCentralWidget(area); MyChildScreenDialog *dlg = new MyChildScreenDialog(); area->addSubWindow(dlg); }
注意事项
- 确保你的
MainWindow本身的背景不是灰色,否则QMDIArea透明后会显示MainWindow的背景;如果需要整个窗口透明,也要给MainWindow设置Qt::WA_TranslucentBackground和对应的样式表。 - 子窗口
MyChildScreenDialog如果需要透明,也要给它设置setAttribute(Qt::WA_TranslucentBackground)和background:transparent的样式表,否则它会显示不透明的背景。
内容的提问来源于stack exchange,提问作者GUI-Novice
相关产品推荐
相关产品推荐

