c++qtqt4

Make QWidget transparent


I have a QWidget-based overlay widget which should paint some text and take place over the central widget of my application. The problem is that I can't set background of overlay widget to be transparent. What I already tried:

  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);

Solution

  • My best guess to show an overlay widget, is convert the widget to a window, resize it to it's contents and move them to the desired position manually.

    MainWindow Example, showing the overlay widget in the center of the video widget:

    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 Example:

    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);
    }
    

    Example when showing a video with LibVLC:

    VLC based player