如何让Linux下的Python3应用始终显示在活动桌面并作为Root窗口
实现Linux下跨工作区的无装饰桌面小部件(Python3)
核心思路
要实现需求,关键是通过设置X11窗口属性,让应用满足三个核心特性:
- 作为桌面根窗口的子窗口,脱离窗口管理器装饰
- 标记为跨所有工作区显示
- 处于桌面层级,让其他窗口可叠加在上方
方案一:PyQt5/PySide2实现(推荐)
Qt对X11窗口属性封装完善,代码简洁易维护。
步骤1:安装依赖
pip install pyqt5
步骤2:核心代码示例
import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtCore import Qt class DesktopWidget(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): # 移除所有窗口装饰(标题栏、边框) self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnBottomHint) # 绕过窗口管理器,直接作为根窗口子窗口 self.setWindowFlags(self.windowFlags() | Qt.X11BypassWindowManagerHint) # 标记窗口在所有工作区显示(X11标准属性) self.setProperty("_NET_WM_DESKTOP", 0xFFFFFFFF) # 设置窗口位置大小(示例为屏幕右下角) screen = QApplication.desktop().screenGeometry() self.setGeometry(screen.width() - 300, screen.height() - 200, 300, 200) # 开启透明背景,适配桌面背景 self.setAttribute(Qt.WA_TranslucentBackground) # 自定义样式与内容 self.setStyleSheet("background-color: rgba(0,0,0,120); color: white; font-size: 16px;") self.show() if __name__ == "__main__": app = QApplication(sys.argv) widget = DesktopWidget() sys.exit(app.exec_())
关键属性说明
Qt.FramelessWindowHint:移除窗口装饰元素Qt.WindowStaysOnBottomHint:固定窗口在桌面最底层Qt.X11BypassWindowManagerHint:跳过窗口管理器管控,直接关联根窗口_NET_WM_DESKTOP:X11属性,0xFFFFFFFF表示窗口在所有工作区可见
方案二:GTK+实现
若熟悉GTK生态,可采用GTK3实现:
步骤1:安装依赖
pip install pycairo pygobject
步骤2:核心代码示例
import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk class DesktopWidget(Gtk.Window): def __init__(self): super().__init__() self.init_ui() def init_ui(self): # 关闭窗口装饰 self.set_decorated(False) # 设置窗口类型为桌面组件 self.set_type_hint(Gdk.WindowTypeHint.DESKTOP) # 固定窗口在最底层 self.set_keep_below(True) # 设置跨工作区显示的X11属性 screen = self.get_screen() window = self.get_window() atom = Gdk.atom_intern("_NET_WM_DESKTOP", False) window.set_property(atom, Gdk.Atom.INTERNET, 0xFFFFFFFF, 32) # 设置位置大小与透明背景 screen_size = screen.get_monitor_geometry(0) self.move(screen_size.width - 300, screen_size.height - 200) self.set_size_request(300, 200) self.set_app_paintable(True) self.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0,0,0,0.5)) # 添加自定义内容 label = Gtk.Label(label="桌面小部件示例") label.override_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(1,1,1,1)) self.add(label) self.show_all() if __name__ == "__main__": app = Gtk.Application() app.connect("activate", lambda app: DesktopWidget()) app.run(None)
注意事项
- 部分窗口管理器(如GNOME Shell)可能需额外配置,允许窗口绕过管理器管控
- 若需动态更新内容(如系统监控),可使用
QTimer(Qt)或Gtk.Timeout(GTK)定时刷新 - 透明背景效果依赖窗口管理器支持RGBA合成,现代桌面环境(GNOME/KDE/Xfce)均支持
内容的提问来源于stack exchange,提问作者Dustin Brooks
相关产品推荐
相关产品推荐

