Reputation: 10878
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:
setPalette(Qt::transparent);
setAttribute( Qt::WA_TranslucentBackground, true );
setAttribute( Qt::WA_OpaquePaintEvent, true );
setAutoFillBackground(false);
setStyleSheet("QWidget{background-color: transparent;}");
setAttribute(Qt::WA_NoSystemBackground);
Upvotes: 27
Views: 49620
Reputation: 498
Here it is how you create a transparent QWidget. The important thing is if you remove Qt::FramelessWindowHint then the transparency removes the contents inside. So if you want the title bar too, then you need to create a custom title bar, there is no workaround. Or you could use QML which supports transparency with the standard title bar.
#include <QApplication>
#include <QLabel>
#include <QPainter>
class PaintEventFilter : public QObject {
protected:
bool eventFilter(QObject* obj, QEvent* event) override {
if (event->type() == QEvent::Paint) {
QWidget* widget = qobject_cast<QWidget*>(obj);
if (widget) {
QPainter painter(widget);
painter.setBrush(QBrush(QColor(0, 0, 255, 128)));
painter.drawRect(50, 100, 200, 100);
painter.setPen(Qt::white);
painter.drawText(widget->rect(), Qt::AlignCenter, "Transparent Window Test");
}
return true;
}
return QObject::eventFilter(obj, event);
}
};
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QWidget* wid = new QWidget();
wid->setWindowTitle("test");
wid->setGeometry({ 0,0,300,300 });
wid->setWindowFlags(Qt::Window | Qt::FramelessWindowHint); // If you remove Qt::FramelessWindowHint, the transparency will remove the content inside!
wid->setAttribute(Qt::WA_TranslucentBackground);
QLabel* label = new QLabel("This is a transparent window", wid);
label->setStyleSheet("QLabel { color : white; font-size: 16px; }");
label->setGeometry(50, 50, 200, 50);
// Install the event filter
PaintEventFilter* filter = new PaintEventFilter();
wid->installEventFilter(filter);
wid->show();
return app.exec();
}
Upvotes: 1
Reputation: 819
The best solution is provided by Gökmen Göksel in one of the comments of this article
setStyleSheet("background-color: rgba(0,0,0,0)");
Upvotes: 16
Reputation: 707
On Linux works with:
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_TransparentForMouseEvents);
Upvotes: 16
Reputation: 2881
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:
Upvotes: 26