编程 Fabric:用 Python 打造你的专属桌面小部件

2026-08-30 23:49:00

写桌面小部件经常是一件繁琐的事:要处理窗口、事件循环,还要靠轮询拉状态,最后用一堆 bash 脚本把 UI 粘起来。Fabric 换了个思路:用 Python 定义部件,用信号驱动更新。本文从一个具体问题切入,记录它的信号工作流、取舍和可复现的启动配置片段。

它解决什么问题

Fabric 是一个 Python 的桌面小部件系统,目标明确:提供高级的、基于信号的工作流,让基本任务不再依赖轮询或 bash 脚本。

  • 跨平台:支持 X11 和 Wayland。
  • Python 集成:直接复用 Python 生态里的模块。
  • 开发者体验:类型支持完整,代码可读性和可维护性都更好。
  • 资源占用低:设计上刻意控制开销。
  • 用 Python 代码替代 shell 脚本:减少资源密集的 bash 调用,维护也简单。

信号式工作流

Fabric 的事件处理基于信号。信号定义在 __gsignals__ 里,传入 SignalContainer,里面包着 Signal 对象。信号需要指定名称、运行标志、回调返回值类型和参数类型。

这段代码是可复现的最小示例:

from fabric.service import *

class MyUsefulService(Service):
    __gsignals__ = SignalContainer(
        Signal("my-really-useful-signal", "run-first", None, (object,))
        # 信号名称,运行标志,回调函数返回值,回调函数参数类型
    )

    def __init__(self):
        self.emit("my-really-useful-signal", "this is my super useful argument")

注意:继承 Service 类时,用 @Property(来自 fabric.service)替代 @property 装饰器,属性才是可通知的。

核心组件:Widget 和 Service

Fabric 的构建块是 Widget 和 Service。

  • Widget:核心基类是 Widget(fabric.widgets.widget),其他 Widget 都继承它。改基类属性或方法,所有子类跟着变,维护成本低。
  • Service:新服务应该继承 Service 基类,用来封装状态和信号。

写 Widget 之前先查 GTK

如果 GTK 已经实现了你需要的 Widget,直接用,或者把它“Fabric化”。

直接使用 GTK Widget 简单方便,但失去 Fabric 特性,比如在构造函数里设置样式。Fabric化之后就能用整套 Fabric API。

普通 Widget 的 Fabric 化,继承 Widget 基类:

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from fabric.widgets.widget import Widget

class MyFabricatedWidget(Gtk.MyWidget, Widget):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

容器 Widget 则继承 Container 基类。

取舍

原文没有提供 Bar 与 Widget 的取舍说明。不过原文明确指出了另一组取舍:直接使用 GTK Widget,还是将其 Fabric 化。

  • 直接使用:上手快,但没法用 Fabric 的构造期样式和信号机制。
  • Fabric 化:要写继承关系,但换来统一的对象模型和完整的 Fabric 能力。

适用场景:想避开轮询和 bash,用 Python 统一逻辑,能接受学习信号机制的成本。不适用场景:原文未提供。Fabric 目前还在开发阶段,稳定性需要自己评估。

配置启动

原文只提到要准备开发环境:读文档、装依赖、配工具。具体的启动命令和配置文件原文未提供。上面的信号定义和 Widget 继承片段可以作为入手的最小骨架。

项目地址:https://github.com/Fabric-Development/fabric

复制全文 生成海报 Fabric 桌面小部件 Python 信号工作流

推荐文章

程序员茄子在线接单