Qt 5.11: transparent window, no border, on Linux

This has taken quite sometime to get right hence the post.

The following code displays a border-less, transparent window with something drawn inside.

Header:

#ifndef TRANSPARENTWIDGET_H
#define TRANSPARENTWIDGET_H

#include <QObject>
#include <QWidget>

class TransparentWidget : public QWidget
{
    Q_OBJECT
  public:
    explicit TransparentWidget(QWidget *parent = nullptr);
    virtual void mouseMoveEvent(QMouseEvent *e) override;
    virtual void paintEvent(QPaintEvent *event) override;
};

#endif // TRANSPARENTWIDGET_H


Source:

#include "transparentwidget.h"
#include <iostream>
#include <QPainter>

TransparentWidget::TransparentWidget(QWidget *parent) : QWidget(parent)
{
  setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
  setAttribute(Qt::WA_NoSystemBackground, true);
  setAttribute(Qt::WA_TranslucentBackground, true);
}

void TransparentWidget::paintEvent(QPaintEvent* event )
{
  std::cout << "trans paint\n";
  QPainter p(this);
  QString text("Test drawing some text");
  QFontMetrics metrics(p.font());
  resize(metrics.size(0, text));
  p.drawText(rect(), Qt::AlignCenter, text);
}

void TransparentWidget::mouseMoveEvent(QMouseEvent *e)
{
  std::cout << "trans move\n";
  QWidget::mouseMoveEvent(e);
}


Setup in main:

  TransparentWidget *trans = new TransparentWidget(pqw);
  trans->resize(720, 576);
  trans->setFixedSize(trans->size());
  trans->show();
  trans->raise();


The above sets the window to a particular size and stops it from resizing.

My use case is quite complex.

I have a QtQuick display into which I need to embed two ffmpeg windows. The ffmpeg windows are started from the command line. This part works well with some quirkiness.

Over the top of the embedded windows I want to display a Qt window and capture mouse and keyboard input, hence this widget.

The reason for using ffmpeg from the command line to that I found that using QtAV caused too much latency with playing a live stream of the order of seconds. Using the ffmpeg command line gave me a delay of less than 400ms.

Technically I could figure out what the issue with QtAV is or write my own integration using ffmpeg tool as a starting point however time is money and timescales are also very short.

Comments