dbus 工具

十二月 23, 2025 #dbus

学习项目

GitHub 实战项目(可直接运行/贡献)

system76-scheduler调度器 GUI,用 DBus 控制 systemd/CPUPython + pydbusorg.freedesktop.systemd1, logind
gnome-shell-screenshot类 Flameshot 工具JS + DBusportal.Screenshot, portal.Clipboard
blueman蓝牙管理器(Python)pydbus + GTKorg.bluez, obex 协议
udisks2-wrapper磁盘挂载示例pydbusorg.freedesktop.UDisks2

DBus 工具类

项目描述
d-spyGTK DBus Inspector(看接口/发请求) ✅ 强烈推荐安装
dbus-next纯 Python async DBus 实现(兼容性好)
xdg-desktop-portal官方测试用例(含 Python)→ 学 a{sv} 参数构造
portal-test专测 portal 接口的工具

快速上手:5 个常用服务实战代码

# notify.py
from pydbus import SessionBus

bus = SessionBus()
notif = bus.get('.Notifications')

# 发送通知
notif.Notify(
    "MyApp",   # app_name
    0,         # replaces_id
    "",        # app_icon
    "标题",    # summary
    "消息内容", # body
    [],        # actions
    {"urgency": 1},  # hints (a{sv})
    5000       # timeout ms
)

✅ 运行:python3 notify.py → 右上角弹出通知

# bluetooth.py
from pydbus import SystemBus

bus = SystemBus()
# 获取默认适配器(如 hci0)
adapter = bus.get('org.bluez', '/org/bluez/hci0')

print("Powered:", adapter.Powered)
adapter.Powered = False  # 关闭蓝牙
# adapter.Powered = True  # 开启

⚠️ 需权限:sudo usermod -aG bluetooth $USER + 重登

# battery.py
from pydbus import SystemBus

bus = SystemBus()
upower = bus.get('org.freedesktop.UPower', '/org/freedesktop/UPower')

for dev_path in upower.EnumerateDevices():
    dev = bus.get('org.freedesktop.UPower', dev_path)
    if dev.Type == 2:  # 2 = Battery
        print(f"电量: {dev.Percentage:.1f}% | 状态: {dev.State}")
# portal_screenshot.py
from pydbus import SessionBus
import time

bus = SessionBus()
portal = bus.get('org.freedesktop.portal.Desktop',
                 '/org/freedesktop/portal/desktop')

# 创建 Request 对象
request = bus.get('org.freedesktop.portal.Desktop',
                  portal.Request.CreateRequest('', '')[0])

# 触发截图(interactive 模式)
opts = {
    'modal': True,
    'interactive': True
}
portal.Screenshot(request, opts)

# 监听 Response(简化版)
def on_response(response, results):
    if response == 0:  # 0 = success
        print("截图保存路径:", results.get('uri'))
    else:
        print("用户取消或失败")

request.onResponse = on_response
time.sleep(10)  # 等待用户操作

✅ 运行后弹出 GNOME 截图界面 → 标注后保存路径打印到终端

# restart_service.py
from pydbus import SessionBus

bus = SessionBus()
systemd = bus.get('.systemd1')

# 重启 flameshot 服务(若配置了 autostart)
systemd.RestartUnit('flameshot.service', 'replace')
print("Flameshot 服务已重启")

调试技巧(结合你之前的环境)

# 1. 监控 portal 通信
busctl --session monitor --match="interface='org.freedesktop.portal.*'"

# 2. 检查 polkit 规则
pkaction --verbose --action-id org.freedesktop.portal.desktop.screenshot

# 3. 手动测试权限
gdbus call --session \
  --dest org.freedesktop.portal.Desktop \
  --object-path /org/freedesktop/portal/desktop \