You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux(Lubuntu 20.04)下QtQuick透明窗口实现:显示桌面及后台应用

在Lubuntu 20.04下实现QtQuick透明窗口显示桌面的解决方案

我明白你在Lubuntu 20.04上用QtQuick做透明窗口时遇到的困扰——试了各种opacitycolor组合,结果要么是灰黑背景,要么完全看不到内容。这其实是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

火山引擎 最新活动