Make Qwidget Transparent

Make QWidget transparent

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

How to create a transparent QWidget on top of a sibling QVideoWidget?

Demo of transparent background overlay on the video:

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsVideoItem>
#include <QMediaPlayer>
#include <QFileDialog>
#include <QPushButton>
#include <QLabel>
#include <QGraphicsProxyWidget>

const QSizeF VideoItemSize(500, 500);

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QMediaPlayer player;
QGraphicsView v;
QGraphicsScene scene;
QGraphicsVideoItem video;
v.setScene(&scene);
video.setSize(VideoItemSize);
scene.setSceneRect(QRectF(QPointF(0, 0), VideoItemSize)); // VideoItem full fill the scene
scene.addItem(&video);
player.setVideoOutput(&video);
player.setMedia(QMediaContent(QFileDialog::getOpenFileUrl()));

// Recommend using QGraphicsItems for overlay component
QGraphicsTextItem text("Loading...",&video);
text.setPos(100, 150);

// If you need a button...
QPushButton button("ButtonTest");
QGraphicsProxyWidget* proxyButton = scene.addWidget(&button);
proxyButton->setPos(100, 200);

// Instead of QGraphicsItems, if you really need a QWidget...
QLabel label("LabelTest");
label.setAttribute(Qt::WA_TranslucentBackground); // You can delete this line to see different
QGraphicsProxyWidget* proxyLabel = scene.addWidget(&label);
proxyLabel->setPos(100, 250);

v.show();
player.play();

return a.exec();
}

QWidget transparent background (but not the children)

It is all well-explained in QWidget documentation:
http://doc.qt.io/qt-5/qwidget.html#transparency-and-double-buffering

A qt widget with fully transparent background

By default in Qt4, a QWidget will draw nothing for its own background, and only its children will be drawn. If you want to override that, you specifically have to tell the widget to draw its background via one of its properties. Note that some widgets derived from QWidget will automatically draw backgrounds.

QWidget background transparent

With the background-color present and set to any of the following:

    background-color:white;width:100%;height:100%;

or

    background-color:#ffffff;width:100%;height:100%;

or my original:

    background-color:#ffeeeeee;width:100%;height:100%;

The property, autoFillBackground is set to false and the background of the widget is transparent at run-time.

However removing any background-color style and leaving the style as just:

    width:100%;height:100%

The property, autoFillBackground is set to true and the widget is opaque.

As far as I can see there is no error in the styles, I believe this may be an error in Qt.



Related Topics



Leave a reply



Submit