如何使 QWidget 阿尔法透明

发布于 2024-11-28 15:01:48 字数 846 浏览 2 评论 0原文

我需要创建一个 alpha 透明小部件,它基本上是一个带有阴影的导航栏,下面的小部件需要通过阴影部分可见。该小部件加载一个 PNG,然后在绘制事件中绘制它。问题是阴影全黑并且不是 alpha 透明的。

这是我当前正在使用的代码:

NavigationBar::NavigationBar(QWidget *parent) : XQWidget(parent) {
    backgroundPixmap_ = new QPixmap();
    backgroundPixmap_->load(FilePaths::skinFile("NavigationBarBackground.png"), "png");

    setAttribute(Qt::WA_NoBackground, true); // This is supposed to remove the background but there's still a (black) background
}


void NavigationBar::paintEvent(QPaintEvent* event) {
    QWidget::paintEvent(event);

    QPainter painter(this);
    int x = 0;
    while (x < width()) {
        painter.drawPixmap(x, 0, backgroundPixmap_->width(), backgroundPixmap_->height(), *backgroundPixmap_);
        x += backgroundPixmap_->width();
    }
}

有人知道我需要更改什么才能确保小部件真正透明吗?

I need to create an alpha transparent widget, it's basically a navigation bar with a shadow and the widgets below need to be partially visible through the shadow. The widget loads a PNG then draws it on the paint event. The problem is that the shadow is all black and is not alpha-transparent.

This is the code I'm currently using:

NavigationBar::NavigationBar(QWidget *parent) : XQWidget(parent) {
    backgroundPixmap_ = new QPixmap();
    backgroundPixmap_->load(FilePaths::skinFile("NavigationBarBackground.png"), "png");

    setAttribute(Qt::WA_NoBackground, true); // This is supposed to remove the background but there's still a (black) background
}


void NavigationBar::paintEvent(QPaintEvent* event) {
    QWidget::paintEvent(event);

    QPainter painter(this);
    int x = 0;
    while (x < width()) {
        painter.drawPixmap(x, 0, backgroundPixmap_->width(), backgroundPixmap_->height(), *backgroundPixmap_);
        x += backgroundPixmap_->width();
    }
}

Does anybody know what I need to change to make sure the widget is really transparent?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撧情箌佬 2024-12-05 15:01:48

您做了太多工作:-)

没有必要调用 setAttribute 。默认情况下,小部件不会在其背景上绘制任何内容(假设 Qt >= 4.1)。调用 QWidget::paintEvent 也是不必要的 - 您不希望它执行任何操作。

不要自己填充图案,而是让 Qt 使用 QBrush 来完成:

NavigationBar::NavigationBar(QWidget *parent) : XQWidget(parent) {
    backgroundPixmap_ = new QPixmap();
    backgroundPixmap_->load(FilePaths::skinFile("NavigationBarBackground.png"), "png");
    // debug check here:
    if (!backgroundPixmap_->hasAlphaChannel()) {
      // won't work
    }
}


void NavigationBar::paintEvent(QPaintEvent* event) {
    QPainter painter(this);
    painter.fillRect(0, 0, width(), height(), QBrush(*backgroundPixmap));
}    

如果您不希望图案垂直重复,请调整高度参数。

You're doing too much work :-)

The setAttribute call is not necessary. By default, a widget will not draw anything on its background (assuming Qt >= 4.1). Calling QWidget::paintEvent is also unnecessary - you don't want it to do anything.

Rather than doing the pattern fill yourself, let Qt do it with a QBrush:

NavigationBar::NavigationBar(QWidget *parent) : XQWidget(parent) {
    backgroundPixmap_ = new QPixmap();
    backgroundPixmap_->load(FilePaths::skinFile("NavigationBarBackground.png"), "png");
    // debug check here:
    if (!backgroundPixmap_->hasAlphaChannel()) {
      // won't work
    }
}


void NavigationBar::paintEvent(QPaintEvent* event) {
    QPainter painter(this);
    painter.fillRect(0, 0, width(), height(), QBrush(*backgroundPixmap));
}    

Adjust the height parameter if you don't want the pattern to repeat vertically.

避讳 2024-12-05 15:01:48

您确定您的 PNG 文件实际上是透明的吗?以下内容(本质上就是您正在做的事情)对我有用。如果这在您的计算机上失败,也许请包括您正在使用的 Qt 版本以及平台。

#include <QtGui>

class TransparentWidget : public QWidget {
public:
  TransparentWidget()
    : QWidget(),
      background_pixmap_(":/semi_transparent.png") {
    setFixedSize(400, 100);
  }
protected:
  void paintEvent(QPaintEvent *) {
    QPainter painter(this);
    int x = 0;
    while (x < width()) {
      painter.drawPixmap(x, 0, background_pixmap_);
      x += background_pixmap_.width();
    }
  }
private:
  QPixmap background_pixmap_;
};

class ParentWidget : public QWidget {
public:
  ParentWidget() : QWidget() {
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(new TransparentWidget);
    layout->addWidget(new QPushButton("Button"));
    setLayout(layout);
    setBackgroundRole(QPalette::Dark);
    setAutoFillBackground(true);
  }
};

int main(int argc, char **argv) {
  QApplication app(argc, argv);
  ParentWidget w;
  w.show();
  return app.exec();
}

Are you sure your PNG file is actually transparent? The following (which is essentially what you are doing) is working for me. If this fails on your machine, perhaps include what version of Qt you are using, and what platform.

#include <QtGui>

class TransparentWidget : public QWidget {
public:
  TransparentWidget()
    : QWidget(),
      background_pixmap_(":/semi_transparent.png") {
    setFixedSize(400, 100);
  }
protected:
  void paintEvent(QPaintEvent *) {
    QPainter painter(this);
    int x = 0;
    while (x < width()) {
      painter.drawPixmap(x, 0, background_pixmap_);
      x += background_pixmap_.width();
    }
  }
private:
  QPixmap background_pixmap_;
};

class ParentWidget : public QWidget {
public:
  ParentWidget() : QWidget() {
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(new TransparentWidget);
    layout->addWidget(new QPushButton("Button"));
    setLayout(layout);
    setBackgroundRole(QPalette::Dark);
    setAutoFillBackground(true);
  }
};

int main(int argc, char **argv) {
  QApplication app(argc, argv);
  ParentWidget w;
  w.show();
  return app.exec();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文