
桌面应用操作系统【免费下载链接】qtile:cookie: A full-featured, hackable tiling window manager written and configured in Python (X11 Wayland)项目地址https://gitcode.com/gh_mirrors/qt/qtile点击查看免费下载Lazy objects惰性对象是 Qtile 配置文件中最核心的编程模型之一它以命令引用的形式包装 Qtile 命令 API 中的任意命令在按键、鼠标事件真正触发时才执行。读完本文你将掌握 lazy 对象的底层原理、全部常用函数清单以及如何用它绑定按键、注入自定义函数和实现条件触发。Lazy 是什么先创建引用事件触发时才执行在 Qtile 的命令体系中几乎所有可执行操作——切换布局、移动窗口、重启 Qtile——都被抽象为 Commands API 中的命令。Lazy objects 正是以任意命令为执行目标的通用载体Lazy objects are a way of executing any of the commands available in Qtiles commands API。Lazy惰性一词点明了其核心语义命令不会在调用lazy.xxx()的那一刻执行。lazy 对象只创建对相关命令的一个引用reference这个引用要等到相应事件被触发时例如一次按键按下才会真正被执行。因此配置文件里最常见的用法就是把 lazy 调用绑定到按键、mouse_callbacks和鼠标事件上用来操作窗口、布局和分组以及执行退出shutdown、重启restart、重载配置reload_config等应用级命令。一个最经典的入门示例from libqtile.config import Key from libqtile.lazy import lazy keys [ Key( [mod1], k, lazy.layout.down() ), Key( [mod1], j, lazy.layout.up() ) ][!NOTE] 如文首所述lazy调用并不会调用相应命令而只是创建对它的引用。虽然这使它非常适合绑定到按键和 widget 的mouse_callbacks但同时也意味着lazy 调用不能被包含在用户自定义函数中例如不能在def my_func(): lazy.window.kill()这样的函数体内直接书写 lazy 调用。需要函数式自定义逻辑时请使用后文介绍的lazy.function。底层机制命令图 惰性命令接口从源码层面看lazy 机制建立在 Qtile 的命令图command graph抽象之上。command/graph.py 定义了CommandGraphRoot、CommandGraphNode、CommandGraphCall等对象。命令图的根节点包含bar、group、layout、screen、widget、window、core这七类子对象——这正好解释了为什么lazy.后可以直接跟layout、window、group、screen等命名空间。真正的入口在 libqtile/lazy.py 的最底部lazy InteractiveCommandClient(LazyCommandInterface())InteractiveCommandClient定义于 command/client.py通过__getattr__魔法方法把lazy.layout.down()这样的链式属性访问解析为对命令图的一次导航与定位。关键的惰性由LazyCommandInterface提供class LazyCommandInterface(CommandInterface): def execute(self, call: CommandGraphCall, args: tuple, kwargs: dict) - LazyCall: Lazily evaluate the given call return LazyCall(call, args, kwargs) def has_command(self, node: CommandGraphNode, command: str) - bool: return True def has_item(self, node: CommandGraphNode, object_type: str, item: str | int) - bool: return True对比 command/interface.py 中另外两种实现——进程内直接调用的QtileCommandInterface和跨进程 IPC 调用的IPCCommandInterface——可以清楚看出LazyCommandInterface并不真正执行命令它只是把CommandGraphCall命令图中要调用的命令节点、位置参数和关键字参数封装进一个LazyCall对象并原样返回。而has_command/has_item一律返回True意味着合法性校验被推迟到运行时这也正是惰性的源码级体现。一个LazyCall实例就是你在按键回调里拿到的东西它保存着命令名name、定位该命令的命令图路径selectors、参数args与关键字参数kwargs。当按键事件触发、Qtile 执行该回调时才会沿命令图解析并真正调用底层命令。常用 Lazy 函数一览以下函数均可从命令树上的对象如lazy.layout、lazy.window调用。下面按用途分组列出最常用的函数完整命令列表请参阅 Commands API 索引。通用函数General functions函数说明lazy.spawn(application)运行application程序lazy.spawncmd()在栏bar上打开命令提示符配合 prompt widget 使用参见 prompt 相关 widget 文档lazy.reload_config()重载配置文件lazy.restart()重启 Qtile。在 X11 后端下不会关闭你的窗口lazy.shutdown()关闭整个 Qtile这五个函数几乎出现在每一个 Qtile 配置里典型的按键绑定组合是mod ctrl r重载配置、mod ctrl q退出、mod shift r重启。组与布局函数Group functions函数说明lazy.next_layout()在当前组使用下一个布局lazy.prev_layout()在当前组使用上一个布局lazy.screen.next_group()切换到右侧的组lazy.screen.prev_group()切换到左侧的组lazy.screen.toggle_group()切换到上次访问的组lazy.group.next_window()将窗口焦点切换到组内的下一个窗口lazy.group.prev_window()将窗口焦点切换到组内的上一个窗口lazy.group[group_name].toscreen()切换到名为group_name的组。可接受可选参数toggle默认为False若该组已在本屏幕默认不做任何事传入toggleTrue则可与上次使用的组来回切换lazy.layout.increase_ratio()增大主窗口master所占空间挤压从窗口slavelazy.layout.decrease_ratio()减小主窗口所占空间扩大从窗口其中toscreen(toggleTrue)是在两组之间快速往返的经典技巧很多用户会把它绑定到某个按键上用作回到上一个工作区。窗口函数Window functions函数说明lazy.window.kill()关闭当前聚焦的窗口lazy.layout.next()将窗口焦点切换到栈stack布局的其他窗格lazy.window.togroup(group_name)把当前聚焦窗口移动到名为group_name的组lazy.window.toggle_floating()在当前窗口的浮动floating与非浮动模式间切换lazy.window.toggle_fullscreen()在当前窗口的全屏与非全屏模式间切换lazy.window.move_up()把当前窗口移到栈中其上方窗口之上lazy.window.move_down()把当前窗口移到栈中其下方窗口之下lazy.window.move_to_top()把当前窗口移到所有同等优先级窗口之上普通窗口不会被移到kept_above窗口之上lazy.window.move_to_bottom()把当前窗口移到所有同等优先级窗口之下普通窗口不会被移到kept_below窗口之下lazy.window.keep_above()让当前窗口保持在其他窗口之上lazy.window.keep_below()让当前窗口保持在其他窗口之下lazy.window.bring_to_front()把当前窗口带到所有窗口之上忽略kept_above优先级move_to_top/move_to_bottom与bring_to_front的差别值得注意前两者尊重kept_above/kept_below的分层语义只在同层窗口内排序后者则无视优先级强制置顶。屏幕函数Screen functions函数说明lazy.screen.set_wallpaper(path, modeNone)将壁纸设置为指定的图片。mode可选值None不缩放、fill居中并缩放以填满屏幕、stretch拉伸以填满屏幕一个完整示例Key([mod4], w, lazy.screen.set_wallpaper(/path/to/wallpaper.png, modefill))ScratchPad DropDown 函数ScratchPad 是 Qtile 的便签板机制实现位于 libqtile/scratchpad.py允许以 DropDown 形式把进程收纳为可随时唤出的浮窗。以下 lazy 函数专用于操作 DropDown函数说明lazy.group[group_name].dropdown_toggle(name)切换指定 DropDown 窗口的可见性首次使用时会启动该 DropDown 配置的进程lazy.group[group_name].hide_all()隐藏该组下所有 DropDown 窗口lazy.group[group_name].dropdown_reconfigure(name, **configuration)更新指定 DropDown 的运行时配置在源码层面scratchpad.py 中分别以dropdown_toggle第 335 行、hide_all第 350 行、dropdown_reconfigure第 358 行实现了这三个命令并被expose_command暴露到命令接口命令暴露机制见 command/base.py 中的expose_command装饰器因此它们既能被 lazy 调用也能通过 IPC 与 qtile shell 调用。用户自定义函数User-defined functions函数说明lazy.function(func, *args, **kwargs)调用func(qtile, *args, **kwargs)。注意qtile对象会被自动作为第一个参数传入lazy.function是让自定义逻辑进入键绑定的官方入口。由于 lazy 调用本身不能写进自定义函数体正确姿势是把自定义函数作为lazy.function的参数包装起来。深入实践lazy.function 的两种传参方式lazy.function还可以用作函数装饰器。此时函数签名中的第一个参数依然是自动注入的qtile对象from libqtile.config import Key from libqtile.lazy import lazy lazy.function def my_function(qtile): ... keys [ Key( [mod1], k, my_function ) ]除了无参用法还可以通过以下两种方式向自定义函数传递参数。方式一内联定义直接把参数附加在lazy.function调用上from libqtile.config import Key from libqtile.lazy import lazy from libqtile.log_utils import logger def multiply(qtile, value, multiplier10): logger.warning(fMultiplication results: {value * multiplier}) keys [ Key( [mod1], k, lazy.function(multiply, 10, multiplier2) ) ]方式二装饰器参数也可以传给被装饰后的函数对象注意此时调用的是multiply(10, multiplier2)的返回值它同样是一个LazyCallfrom libqtile.config import Key from libqtile.lazy import lazy from libqtile.log_utils import logger lazy.function def multiply(qtile, value, multiplier10): logger.warning(fMultiplication results: {value * multiplier}) keys [ Key( [mod1], k, multiply(10, multiplier2) ) ]这两种方式在底层是等价的。从 libqtile/lazy.py 中LazyCall.__call__的实现可以看到装饰器形式之所以能写成multiply(10, multiplier2)是因为LazyCall实现了__call__def __call__(self, *args, **kwargs): # We need to return a new object so the arguments are not shared between # a single instance of the LazyCall object. return LazyCall(self._call, (*self._args, *args), {**self._kwargs, **kwargs})注意注释强调的要点调用会返回一个新的LazyCall从而避免同一个LazyCall实例在多处复用时参数互相污染。条件触发when() 方法限定执行场景很多高级配置需要只在特定条件下才触发按键。为此LazyCall提供了when()方法同样定义于 libqtile/lazy.py支持以下筛选条件参数类型说明focusedMatch或None限定当前窗口必须满足的匹配条件if_no_focusedbool是否让focused条件在没有聚焦窗口时也视为匹配。默认False即无聚焦窗口时focused条件不生效当focused是正则且希望在无窗口时也放行时设为Truelayoutstr/Iterable[str]或None限定一个或多个布局名None表示所有布局均可when_floatingboolTrue时仅在当前窗口为浮动状态触发False时仅在非浮动状态触发funccallable回调函数返回True时才触发每次按键时求值conditionbool一个布尔值决定 lazy 对象是否运行。与func不同它在配置文件首次加载时只求值一次对应的判定逻辑在LazyCall.check(self, q)中逐项实现分别检查条件condition、聚焦窗口Match配合if_no_focused、浮动状态when_floating、布局白名单_layouts以及可调用对象func任何一项不满足即返回False只有全部通过才真正执行命令。以下是 keys.rst 中给出的实战组合from libqtile.config import Key keys [ # 仅在特定布局下触发 Key( [mod, shift], j, lazy.layout.grow().when(layoutverticaltile), lazy.layout.grow_down().when(layoutcolumns) ), # 限定当前窗口非浮动时才触发 Key([mod], f, lazy.window.toggle_fullscreen().when(when_floatingFalse)), # 限定当前窗口为浮动时才触发 Key([mod], f, lazy.window.toggle_fullscreen().when(when_floatingTrue)), # 用 Match 匹配当前窗口属性如 wm_class Key([mod], f, lazy.window.toggle_fullscreen().when(focusedMatch(wm_classyourclasshere))) ]Match对象的完整用法支持按title、wm_class、role、wm_type、wm_instance_class、net_wm_pid、wid匹配以及、|、~、^逻辑组合请参阅 Matching windows 文档。结合鼠标绑定与默认配置中的真实用法lazy 调用同样大量出现在 mouse.rst 描述的Drag/Click鼠标绑定中例如经典的三键方案from libqtile.config import Click, Drag mouse [ Drag([mod], Button1, lazy.window.set_position_floating(), startlazy.window.get_position()), Drag([mod], Button3, lazy.window.set_size_floating(), startlazy.window.get_size()), Click([mod], Button2, lazy.window.bring_to_front()) ]在随包分发的 默认配置文件 里可以看到 lazy 调用与Key结合的真实样板lazy.layout.down()/lazy.layout.up()绑定到mod j/k移动焦点lazy.layout.next()绑定到mod space切换窗口焦点lazy.layout.grow_left()/grow_right()/grow_down()/grow_up()绑定到mod ctrl h/l/j/k调整窗口大小另有lazy.spawncmd()、lazy.spawn(...)、lazy.reload_config()、lazy.restart()、lazy.shutdown()等通用绑定。如果你刚开始配置 Qtile这份文件是观察 lazy 对象组织方式的绝佳参照。小结Lazy objects 是 Qtile配置即 Python 程序理念的枢纽通过lazy InteractiveCommandClient(LazyCommandInterface())每一次lazy.xxx()调用都被转换为命令图上的一个引用事件触发时才沿bar / group / layout / screen / widget / window / core路径解析并执行。掌握本文介绍的常用函数、lazy.function的两种参数注入方式、when()条件触发以及Match、Drag/Click的配合用法你就能写出既能覆盖日常操作、又具备精细条件控制的高质量 Qtile 配置。更多命令的完整清单请继续查阅 Commands API 索引 与 Keys 配置文档。赞分享桌面应用操作系统【免费下载链接】qtile:cookie: A full-featured, hackable tiling window manager written and configured in Python (X11 Wayland)项目地址https://gitcode.com/gh_mirrors/qt/qtile点击查看免费下载相关推荐Qtile 鼠标绑定完全指南深入理解 Click / Drag / EzClick / EzDrag 配置Qtile 鼠标绑定完全指南深入理解 Click / Drag / EzClick / EzDrag 配置 导读 Qtile 作为一款使用 Python 编写桌面应用操作系统WezTerm show-keys 命令完全指南导出并校验你的按键与鼠标绑定配置WezTerm show keys 命令完全指南导出并校验你的按键与鼠标绑定配置 wezterm show keys 是 WezTerm 提供的一个命令行工具桌面应用开发工具跨平台Qtile 命令图接口Interfaces全解析lazy、qtile shell、cmd-obj 与 Python 命令客户端Qtile 命令图接口Interfaces全解析lazy、qtile shell、cmd obj 与 Python 命令客户端 导读 Qtile 是一款用桌面应用操作系统上一篇4 步搭好 PotPlayer 字幕翻译插件外挂字幕实时双语同屏下一篇洛雪音乐六音音源失效手把手3步修复指南2026版创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考