Linux(Lubuntu 20.04)下QtQuick透明窗口实现:显示桌面及后台应用
在Lubuntu 20.04下实现QtQuick透明窗口显示桌面的解决方案
我明白你在Lubuntu 20.04上用QtQuick做透明窗口时遇到的困扰——试了各种opacity和color组合,结果要么是灰黑背景,要么完全看不到内容。这其实是Linux X11环境下QtQuick窗口透明的几个关键设置没踩对,我来给你梳理下最佳方案:
核心问题分析
在X11桌面(Lubuntu用的是Openbox+X11)下,QtQuick窗口默认不支持Alpha通道透明,必须手动配置缓冲格式,同时启用特定的窗口属性。另外,你之前用的opacity: 0.0是把整个窗口(包括子控件)都变透明了,这不是你要的“背景透明、控件正常显示”的效果。
分步解决方案
1. 配置C++代码,启用Alpha缓冲和透明属性
在main.cpp里,我们需要先设置窗口的表面格式,确保Alpha通道可用,然后给窗口添加Qt::WA_TranslucentBackground属性:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickWindow> #include <QSurfaceFormat> int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif // 强制启用Alpha缓冲,这是X11下透明的前提 QSurfaceFormat format; format.setAlphaBufferSize(8); QSurfaceFormat::setDefaultFormat(format); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); // 给窗口添加半透明背景属性 if (auto window = qobject_cast<QQuickWindow*>(obj)) { window->setAttribute(Qt::WA_TranslucentBackground); // 如果需要无边框窗口,可以取消下面的注释 // window->setFlags(window->flags() | Qt::FramelessWindowHint); } }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
2. 修正QML代码,实现背景透明+控件正常显示
不要用全局opacity,只需要把窗口的color设为transparent。另外,优先用Window而非ApplicationWindow——因为ApplicationWindow默认带了一个不透明的内容容器,容易覆盖透明设置。如果一定要用ApplicationWindow,需要额外设置contentItem.color: "transparent"。
针对你第一个示例的修正版(Window版本):
import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 Window { id: transparentWindowTest visible: true width: 500 height: 500 x: (Screen.width - width) / 2 y: (Screen.height - height) / 2 color: "transparent" // 仅窗口背景透明,子控件不受影响 // 蓝色右侧窗口(非透明) Rectangle { id: rightWindow anchors.left: parent.left anchors.top: parent.top width: 200 height: parent.height color: "blue" } // 红色底部窗口(非透明) Rectangle { id: bottomWindow anchors.left: parent.left anchors.top: parent.top anchors.topMargin: 300 width: parent.width height: 200 color: "red" } // 中间区域不需要额外的透明Rectangle,窗口背景已经是透明的,直接显示桌面 }
针对你第二个示例的修正版:
import QtQuick 2.15 import QtQuick.Window 2.15 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") color: "transparent" // 去掉全局opacity,只设置背景透明 Rectangle { id: root width: 250 height: 250 color: "#00FFFFFF" // 完全透明的背景 border.color: "#F00" border.width: 2 Rectangle { id: ball height: 50; width: 50 x: 100 color: "#990000FF" // 半透明蓝色球,正常显示 radius: height / 2 } SequentialAnimation { running: true; loops: Animation.Infinite NumberAnimation { target: ball; property: "y"; to: root.height - ball.height; duration: 1000; easing.type: Easing.OutBounce } PauseAnimation { duration: 1000 } NumberAnimation { target: ball; property: "y"; to: 0; duration: 700 } PauseAnimation { duration: 1000 } } } }
3. 确保桌面合成器已启用
X11本身不支持窗口透明,需要依赖合成器。Lubuntu 20.04默认应该已经启用了合成器,如果你的系统还是不行,可以手动安装compton:
sudo apt install compton
安装后运行compton &测试,透明窗口应该就能正常显示桌面了。
内容的提问来源于stack exchange,提问作者Simon Bagley




