使QWidget透明

27

我有一个基于 QWidget 的叠加小部件,它应该绘制一些文本并覆盖在我的应用程序的中央小部件上。问题是我无法将叠加小部件的背景设置为透明。我已经尝试了以下方法:

  1. setPalette(Qt::transparent);
  2. setAttribute(Qt::WA_TranslucentBackground, true);
  3. setAttribute(Qt::WA_OpaquePaintEvent, true);
  4. setAutoFillBackground(false);
  5. setStyleSheet("QWidget{background-color: transparent;}");
  6. setAttribute(Qt::WA_NoSystemBackground);

你尝试过使用 QWidget::setWindowOpacity() 吗? - vahancho
@vahancho 它不起作用。 - sorush-r
为什么在这种情况下实现自己的 paintEvent() 不是一个解决方案? - Ilya
4个回答

25

我认为展示一个叠加式小部件的最佳方法是将小部件转换为窗口,将其调整大小到内容的大小,并手动将它们移动到所需的位置。

MainWindow示例,在视频小部件中心显示叠加式小部件:

Mwindow::Mwindow()
{
    widget = new Widget(this);
}

void Mwindow::widgetSizeMove()
{
    if (widget->width() <= videoWidget->width() && widget->height() <= videoWidget->height())
    {
        widget->setWindowOpacity(1); // Show the widget
        QPoint p = videoWidget->mapToGlobal(videoWidget->pos());
        int x = p.x() + (videoWidget->width() - widget->width()) / 2;
        int y = p.y() + (videoWidget->height() - widget->height()) / 2;
        widget->move(x, y);
        widget->raise();
    }
    else
    {
        widget->setWindowOpacity(0); // Hide the widget
    }
}

bool Mwindow::event(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::Show:
        widget->show();
        QTimer::singleShot(50, this, SLOT(widgetSizeMove())); 
        //Wait until the Main Window be shown
        break;
    case QEvent::WindowActivate:
    case QEvent::Resize:
    case QEvent::Move:
        widgetSizeMove();
        break;
    default:
        break;
    }

    return QMainWindow::event(event);
}

小部件示例:

Widget::Widget(QWidget *parent) : QWidget(parent)
{
    setWindowFlags(Qt::Window | Qt::FramelessWindowHint);

    setAttribute(Qt::WA_NoSystemBackground);
    setAttribute(Qt::WA_TranslucentBackground);
    setAttribute(Qt::WA_PaintOnScreen);

    setAttribute(Qt::WA_TransparentForMouseEvents);
}

void Widget::paintEvent(QPaintEvent*)
{
    QPainter p(this);
    QString text = "Some foo goes here";
    QFontMetrics metrics(p.font());
    resize(metrics.size(0, text));
    p.drawText(rect(), Qt::AlignCenter, text);
}

使用LibVLC显示视频的示例:

基于VLC的播放器


16

这篇文章中,Gökmen Göksel 在评论中提供了最佳解决方案。

setStyleSheet("background-color: rgba(0,0,0,0)");

这是唯一一个使背景透明的解决方案,但它也破坏了小部件的本地样式。 - Violet Giraffe

16

在Linux上适用于:

setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_TransparentForMouseEvents);

2
我有一个类似的用例,只使用 setAttribute(Qt::WA_TranslucentBackground); 就可以了! - Taiguara Tupinambás

0
在样式表中编写:

\

background: transparent;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接