I have a task.
I need to show the window. This window should be on top of all windows, without a frame, transparent and let all events pass through it. It should also contain some widgets that must not be transparent and that must handle mouse and keyboard events if they are in focus, i.e. you can interact with them in a standard way.
How can I do this in Qt/c++
? I tried following code, that works perfectly on Windows, but doesn’t work on Linux:
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QEvent>
#include <QMouseEvent>
class TransparentOverlay : public QWidget
{
public:
TransparentOverlay(QWidget *parent = nullptr) : QWidget(parent)
{
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_TransparentForMouseEvents, true);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setMargin(0);
QLabel *label = new QLabel("This is a label", this);
QPushButton *button = new QPushButton("This is a button", this);
layout->addWidget(label);
layout->addWidget(button);
label->setAttribute(Qt::WA_TransparentForMouseEvents, false);
button->setAttribute(Qt::WA_TransparentForMouseEvents, false);
}
protected:
bool event(QEvent *event) override
{
if (event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonRelease ||
event->type() == QEvent::MouseButtonDblClick ||
event->type() == QEvent::MouseMove ||
event->type() == QEvent::KeyPress ||
event->type() == QEvent::KeyRelease)
{
QWidget *child = childAt(static_cast<QMouseEvent *>(event)->pos());
if (child && child != this)
{
return QWidget::event(event);
}
return false;
}
return QWidget::event(event);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TransparentOverlay overlay;
overlay.resize(400, 300);
overlay.show();
return a.exec();
}
When running this code, I have a transparent window and clickable button as I wanted. But transparent main window area doesn’t forward events through it: for example, I can’t select text under it, press on folders, make seldections etc.
I am using Ubuntu 22.04.4 LTS
and Qt 5.15.3
.