yasb Power Menu 小组件完全指南:全屏电源面板与紧凑弹窗的双模式配置
桌面应用【免费下载链接】yasbA highly configurable Windows status bar written in Python.项目地址https://gitcode.com/gh_mirrors/yas/yasb点击查看免费下载导读本文聚焦 yasb一个高度可配置的 Windows 状态栏使用 Python 编写内置的 Power Menu 小组件完整讲解如何通过config.yaml为状态栏添加关机、重启、睡眠、休眠、锁定、注销等电源操作入口并配置全屏模糊遮罩或紧凑弹窗两种展示形态。读完本文你将掌握 Power Menu 的全部配置项、电源按钮动作与底层系统调用、鼠标回调与全局快捷键绑定以及两套完整可用的 CSS 样式方案可直接在自己的状态栏配置中落地部署。功能概览与适用场景Power Menu 小组件在状态栏上渲染一个电源图标按钮点击后弹出一个电源操作面板提供关机、重启、睡眠、锁定、注销等快捷按钮同时支持显示当前用户头像、用户名、账户类型管理员/标准用户、邮箱以及系统已运行时长uptime。它主要解决三类场景将系统电源操作入口整合进状态栏避免每次呼出 Windows 开始菜单在无键盘场景触屏/遥控下通过鼠标快速完成电源动作通过全屏遮罩或紧凑弹窗 模糊效果融入整体状态栏视觉风格。从源码结构看该小组件由三层组成详见 src/core/widgets/yasb/power_menu.py层级文件职责界面层yasb/power_menu.py按钮、菜单窗口、动画、键盘导航、hover 样式动作层services/power_menu/power_commands.py执行关机/重启/睡眠/锁定等系统命令用户信息层services/power_menu/user_info.py获取头像、用户名、账户类型、邮箱配置校验由 src/core/validation/widgets/yasb/power_menu.py 中的PowerMenuConfigPydantic 模型完成它决定了各选项的类型、默认值与取值范围。快速上手最小配置Power Menu 使用与其他 yasb 小组件相同的方式注册在config.yaml的widgets段定义一个键如power_menu指定type为yasb.power_menu.PowerMenuWidget然后在options中配置各项参数。小组件类通过BaseWidget.__init_subclass__自动注册到WIDGET_REGISTRY见 src/core/widgets/registry.py因此type字符串必须与模块路径一致。最小可用配置如下widgets: power_menu: type: yasb.power_menu.PowerMenuWidget options: label: \uf011随后在bars段中把power_menu加入某个栏的left/center/right列表即可参考 docs/Configuration.md 中的多栏配置示例例如right: [volume, power_menu]。默认情况下鼠标左键点击该图标即可呼出电源菜单无需额外配置。核心配置选项总览以下选项由 PowerMenuConfig 定义默认值与取值范围以源码为准选项类型默认值说明labelstringpower状态栏上显示的标签图标。uptimebooleantrue是否在全屏模式下显示系统运行时长。show_userbooleanfalse是否在按钮上方显示用户资料信息源码默认false文档表格按示例通常写true两者均合法以你的配置为准。blurbooleanfalse是否对菜单按钮/窗口背景启用模糊效果仅全屏模式生效。blur_backgroundbooleantrue是否对全屏遮罩背景启用模糊仅全屏模式生效。animation_durationinteger200淡入淡出动画时长单位毫秒取值范围 0–2000仅全屏模式生效。button_rowinteger3全屏模式下每行按钮数量取值范围 1–6仅全屏模式生效。menu_stylestringfullscreen菜单形态fullscreen全屏遮罩居中面板或popup锚定在栏按钮旁的紧凑弹窗。popupdict见下节紧凑弹窗的外观与定位选项仅当menu_style为popup时生效。profile_image_sizeinteger64用户头像尺寸单位像素取值范围 16–256。buttonsdict{}定义菜单中出现的按钮及其图标/文案。callbacksdicton_left: toggle_power_menu,on_middle/on_right: do_nothing鼠标事件回调。keybindingslist[]全局快捷键列表见后文。值得注意animation_duration与button_row在源码中通过Field(ge..., le...)做了边界约束配置超出范围会触发 Pydantic 校验错误menu_style被声明为Literal[fullscreen, popup]只能取这两个值。Popup 子配置menu_style: popup时生效对应源码中的 PowerMenuPopupConfig选项类型默认值说明blurbooleantrue是否对弹窗应用模糊效果。round_cornersbooleantrue是否圆角。round_corners_typestringnormal圆角类型normal或small。border_colorstringSystem弹窗边框颜色。alignmentstringright相对栏按钮的水平对齐left、right或center。directionstringup弹出方向up或down。offset_topinteger6垂直偏移像素。offset_leftinteger0水平偏移像素。这些定位参数最终交给通用弹窗基类 PopupWidget.setPosition 计算全局坐标并自动做屏幕边界钳制确保弹窗不会超出当前屏幕边缘。电源按钮可用动作详解buttons是一个字典键为动作名值为[icon, label]形式的列表分别对应按钮图标与显示文案。buttons的合法键由 PowerMenuButtonsConfig 决定按钮键是否必需说明对应底层命令见 power_commands.pyshutdown必需混合关机shutdown /s /hybrid /t 0先隐藏窗口将命令挂到aboutToQuit后退出 yasb 进程。restart必需重启shutdown /r /t 0。cancel必需关闭电源菜单弹窗全屏模式淡出窗口弹窗模式自动关闭不会渲染该按钮。lock可选锁定工作站rundll32.exe user32.dll,LockWorkStation。signout可选注销shutdown /l。sleep可选睡眠优先通过SetSuspendState提升进程令牌权限后调用见 bindings/powrprof.py失败时回退到rundll32.exe powrprof.dll,SetSuspendState。hibernate可选休眠shutdown /h。force_shutdown可选强制关机不保存应用shutdown /s /f /t 0。force_restart可选强制重启不保存应用shutdown /r /f /t 0。源码中按钮执行采用名称到方法的动态映射action getattr(power_operations, button_name, None)因此只有上表列出的键有效同时shutdown、restart、cancel为 Pydantic 必填字段配置中缺失会直接报错。关于关闭/重启等动作值得了解的实现细节是PowerOperations会先隐藏窗口再把真正的系统命令通过QCoreApplication.aboutToQuit信号挂到进程退出流程中最后调用exit_application()干净地退出 yasb见 src/core/utils/controller.py避免状态栏常驻进程干扰系统关机的关闭后重启流程。完整配置示例示例一全屏模式默认形态power_menu: type: yasb.power_menu.PowerMenuWidget options: label: \uf011 uptime: true show_user: true blur: false blur_background: true animation_duration: 120 # 毫秒 button_row: 3 # 每行按钮数1-6 profile_image_size: 80 # 头像尺寸像素 buttons: restart: [\uead2, Restart] shutdown: [\uf011, Shut Down] signout: [\udb80\udf43, Sign out] hibernate: [\uf28e, Hibernate] lock: [\uea75, Lock] cancel: [\udb81\udf3a, Cancel]该配置会生成一个覆盖当前屏幕的全屏遮罩半透明黑色可用样式控制深浅面板居中显示用户头像、用户名与账户类型、系统运行时长以及每行 3 个的电源按钮。示例二紧凑弹窗模式power_menu: type: yasb.power_menu.PowerMenuWidget options: label: \uf011 uptime: true show_user: true menu_style: popup popup: blur: true round_corners: true round_corners_type: normal border_color: System alignment: right direction: down offset_top: 6 offset_left: 0 profile_image_size: 64 buttons: lock: [\uea75, Lock] signout: [\udb80\udf43, Sign out] sleep: [\u23fe, Sleep] hibernate: [\uf28e, Hibernate] restart: [\uead2, Restart] shutdown: [\uf011, Shut Down] cancel: [, Cancel]紧凑弹窗模式下需要注意cancel按钮不会在弹窗中渲染弹窗点击外部区域即自动关闭且弹窗按钮按纵向列表排列不参与button_row分组。示例中图标使用字体图标Nerd Fonts 等的 Unicode 码点cancel留空字符串表示不显示图标。用户信息与头像的底层实现show_user: true时面板会展示用户资料区块。其数据来源集中在 services/power_menu/user_info.py全部使用cache缓存避免重复查询系统用户名优先win32api.GetUserNameEx(3)显示名失败回退GetUserName()账户类型打开当前进程令牌并检查S-1-5-32-544Administrators 组的 SID 是否在 TokenGroups 中返回Administrator或Standard User邮箱优先GetUserNameEx(8)UPN失败则读取注册表HKEY_CURRENT_USER\Software\Microsoft\IdentityCRL\UserExtendedProperties的账户键头像根据进程令牌的 SID 读取HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\{SID}下分辨率最高的Image*值找不到时回退到C:\ProgramData\Microsoft\User Account Pictures\user-192.png。头像在界面层会被缩放并裁剪为圆形QPixmap.scaled 椭圆QPainterPath裁剪见 yasb/power_menu.py。紧凑弹窗模式额外支持 Manage accounts 按钮点击后调用os.startfile(ms-settings:accounts)打开 Windows 账户设置页。回调与全局快捷键鼠标回调callbacks支持on_left、on_middle、on_right三个键默认{on_left: toggle_power_menu, on_middle: do_nothing, on_right: do_nothing}见 PowerMenuCallbacksConfig。可用取值toggle_power_menu切换电源菜单的显示/隐藏do_nothing不执行任何操作exec command执行任意外部程序/命令由 BaseWidget._cb_execute_subprocess 承载。全局快捷键yasb 的快捷键机制基于原生 WindowsRegisterHotKeyAPI按小组件实例注册无第三方依赖且支持screen目标active/cursor/primary详见 docs/Keybindings.md。Power Menu 的快捷键示例power_menu: type: yasb.power_menu.PowerMenuWidget options: keybindings: - keys: winp action: toggle_power_menu按键组合语法支持win、ctrl、alt、shift修饰键例如ctrlshiftf1。若快捷键与其他应用冲突RegisterHotKey采用先到先得策略需更换组合键。样式系统可用 CSS 类Power Menu 的样式类分为全屏fullscreen与紧凑弹窗popup两套。menu_style决定运行时使用哪一套。全屏模式可用类.power-menu-overlay {} /* 全屏遮罩层 */ .power-menu-overlay .uptime {} /* 系统运行时长文本 */ .power-menu-widget .label {} /* 状态栏上的图标 */ .power-menu-popup {} /* 居中面板容器 */ .power-menu-popup .profile-info {} /* 用户资料区块 */ .power-menu-popup .profile-info .profile-avatar {} .power-menu-popup .profile-info .profile-username {} .power-menu-popup .profile-info .profile-account-type {} .power-menu-popup .buttons {} /* 按钮容器 */ .power-menu-popup .button {} /* 单个按钮 */ .power-menu-popup .button.hover {} /* 悬停态 */ .power-menu-popup .button .label {} .power-menu-popup .button .icon {} /* 特定按钮 */ .power-menu-popup .button.cancel {} .power-menu-popup .button.shutdown {} .power-menu-popup .button.restart {} .power-menu-popup .button.signout {} .power-menu-popup .button.hibernate {} .power-menu-popup .button.sleep {} .power-menu-popup .button.lock {} .power-menu-popup .button.force-shutdown {} .power-menu-popup .button.force-restart {}注意按钮类名由动作名中的_替换为-生成button_name.replace(_, -)见 yasb/power_menu.py因此force_shutdown对应.button.force-shutdown。紧凑弹窗模式可用类.power-menu-compact {} /* 弹窗根容器 */ .power-menu-compact .profile-info {} .power-menu-compact .profile-info .profile-avatar {} .power-menu-compact .profile-info .profile-username {} .power-menu-compact .profile-info .profile-account-type {} .power-menu-compact .profile-info .profile-email {} .power-menu-compact .profile-info .manage-accounts {} .power-menu-compact .buttons {} /* 按钮容器 */ .power-menu-compact .button {} .power-menu-compact .button.hover {} .power-menu-compact .button .icon {} .power-menu-compact .button .label {} /* 特定按钮 */ .power-menu-compact .button.shutdown {} .power-menu-compact .button.restart {} .power-menu-compact .button.signout {} .power-menu-compact .button.hibernate {} .power-menu-compact .button.sleep {} .power-menu-compact .button.lock {} .power-menu-compact .button.force-shutdown {} .power-menu-compact .button.force-restart {}悬停态由界面层的事件过滤器动态追加hover类并触发样式刷新refresh_widget_style因此你只需在样式表中为.button.hover编写高亮规则即可。完整样式示例全屏模式示例样式.power-menu-widget .label { color: #f38ba8; font-size: 13px; } .power-menu-popup { background-color: rgba(255, 255, 255, 0.04); padding: 32px; } .power-menu-popup .button { padding: 0; min-width: 140px; max-width: 140px; min-height: 80px; border-radius: 12px; background-color: #ffffff11; border: 8px solid rgba(255, 255, 255, 0) } .power-menu-popup .button.hover { background-color: #0969b8; border: 8px solid #0969b8; } .power-menu-popup .button .label { font-size: 13px; font-weight: 600; font-family: Segoe UI; color: #a9a9ac; } .power-menu-popup .button .icon { font-size: 32px; color: rgba(255, 255, 255, 0.4) } .power-menu-popup .button.hover .label, .power-menu-popup .button.hover .icon { color: #ffffff } .power-menu-popup .profile-info { padding: 0 0 16px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.1); background-color: transparent; margin-bottom: 16px; } .power-menu-popup .profile-info .profile-username { font-size: 24px; font-weight: 600; color: #cdd6f4; margin-top: 0; font-family: Segoe UI; } .power-menu-popup .profile-info .profile-account-type { font-size: 13px; color: #cdd6f493; margin-top: 4px; font-family: Segoe UI } .power-menu-overlay { background-color: rgba(0, 0, 0, 0.15); } .power-menu-overlay .uptime { font-size: 16px; margin-bottom: 20px; color: #9ea2b4; font-weight: 600; }紧凑弹窗模式示例样式.power-menu-widget .label { color: #f38ba8; font-size: 13px; } .power-menu-compact { min-width: 260px; background-color: rgba(55, 58, 65, 0.6); } .power-menu-compact .profile-info { padding: 12px 0 24px 0; } .power-menu-compact .profile-info .profile-username { font-size: 16px; font-weight: 600; color: #e0e3ee; font-family: Segoe UI; margin-top: 4px; } .power-menu-compact .profile-info .profile-account-type { font-size: 12px; color: #ffffff; font-weight: 600; margin-top: 8px; font-family: Segoe UI; background-color: #0f68dd; padding: 2px 6px; border-radius: 6px; } .power-menu-compact .profile-info .profile-email { font-size: 13px; color: rgba(205, 214, 244, 0.6); margin-top: 2px; font-family: Segoe UI; } .power-menu-compact .manage-accounts { font-size: 12px; background-color: rgba(255, 255, 255, 0.08); font-family: Segoe UI; font-weight: 600; padding: 2px 8px; margin-top: 16px; border-radius: 6px; border: 1px solid rgba(255, 255, 255, 0.1); } .power-menu-compact .manage-accounts:hover { background-color: rgba(255, 255, 255, 0.15); } .power-menu-compact .buttons { background-color: rgba(255, 255, 255, 0.05); margin: 0 12px 12px 12px; border-radius: 8px; } .power-menu-compact .button { padding: 8px 16px; background-color: transparent; border: none; border-radius: 0; } .power-menu-compact .button.hover { background-color: rgba(255, 255, 255, 0.1); } .power-menu-compact .button.lock.hover { border-top-right-radius: 8px; border-top-left-radius: 8px; } .power-menu-compact .button.shutdown.hover { border-bottom-right-radius: 8px; border-bottom-left-radius: 8px; } .power-menu-compact .button .icon { font-size: 14px; color: rgba(255, 255, 255, 0.4); padding-right: 10px; min-width: 20px; } .power-menu-compact .button .label { font-size: 13px; font-weight: 500; font-family: Segoe UI; color: #bebec0; } .power-menu-compact .icon.hover, .power-menu-compact .label.hover { color: #ffffff; }底层实现与行为细节两种形态的运行时切换PowerMenuWidget在构造函数中只注册一个动作入口toggle_power_menu实际展示逻辑由menu_style分支决定yasb/power_menu.pyfullscreen创建MainWindow无边框、置顶、应用级模态窗口OverlayWidget全屏遮罩两者都是AnimatedWidget通过QPropertyAnimation控制windowOpacity完成淡入淡出模糊开启时调用enable_blur见 src/core/utils/win32/backdrop.py弹出后通过force_foreground_focus抢占前台焦点src/core/utils/win32/window_actions.py。popup复用通用 PopupWidget无边框、半透明、Popup 类型窗口支持模糊、圆角、边框颜色每次展开前根据alignment/direction/offset_*重新计算位置并钳制在屏幕范围内点击弹窗外部自动隐藏WindowDeactivate事件触发hide_animated。系统运行时长uptime的来源OverlayWidget.boot_time通过GetTickCount64()封装在 src/core/utils/win32/bindings/kernel32.py获取自系统启动以来的毫秒数换算为X day(s) X hour(s) X min格式的文本并在遮罩顶部居中显示。全屏模式的键盘导航MainWindow设置了StrongFocus策略并实现了keyPressEvent方向键←/→在同行内循环移动↑/↓按button_row跨行移动Enter/Space触发当前按钮Esc关闭菜单。行列导航逻辑见 navigate_focus越界时会回绕到首行或最后一个有效按钮。弹窗模式的按钮构建紧凑弹窗模式遍历buttons字典时跳过cancel键每个动作通过getattr(power_operations, button_name)解析为PowerOperations上的方法每个按钮由PopupActionFrame承载mousePressEvent即触发动作并通过eventFilter在鼠标进入/离开时追加/移除hover类。常见问题与排错建议配置报错字段缺失/字段非法buttons必须包含shutdown、restart、cancel三项animation_duration需在 0–2000、button_row需在 1–6、profile_image_size需在 16–256 之间超出即触发 Pydantic 校验失败。弹窗模式下找不到 cancel 按钮这是预期行为——弹窗通过外部点击自动关闭cancel仅在fullscreen模式下渲染。快捷键无响应确认按键组合语法如winp在 docs/Keybindings.md 的支持范围内且没有被其他应用占用同时该 widget 名称在配置中唯一。头像未显示user_info.get_user_avatar_path依赖注册表中按 SID 存储的账户图片若本机未配置账户图片将回退到系统默认头像文件仍不存在则头像区域留空。睡眠/休眠对硬件无效果睡眠依赖SetSuspendState成功返回失败时会回退rundll32方式并在日志记录错误部分设备需在 Windows 电源设置中开启对应功能。小结Power Menu 小组件以一个状态栏按钮 两种弹出形态覆盖了日常电源操作的全部入口。配置层面掌握menu_style、buttons、popup、callbacks/keybindings与两套 CSS 类即可完成从功能到视觉的完整定制原理层面其动作层直接封装 Windows 原生shutdown/rundll32/SetSuspendState调用用户信息层通过 Win32 API 与注册表动态获取界面层则以 Qt 窗口 动画 事件过滤器实现交互与模糊效果。建议对照 配置总览 与 快捷键文档将本文示例整合进自己的config.yaml逐步调优。赞分享桌面应用【免费下载链接】yasbA highly configurable Windows status bar written in Python.项目地址https://gitcode.com/gh_mirrors/yas/yasb点击查看免费下载相关推荐yasb Media Lite 媒体控件配置指南紧凑竖版封面栏与弹出式播放器的完整实战yasb Media Lite 媒体控件配置指南紧凑竖版封面栏与弹出式播放器的完整实战 本文是 yasb基于 Python 与 Qt 的高度可配置 Wind桌面应用YASB CPU 组件完全指南配置、直方图与弹窗监控的源码级解析YASB CPU 组件完全指南配置、直方图与弹窗监控的源码级解析 YASBYet Another Status Bar是一款使用 Python 编写的高可桌面应用YASB 蓝牙组件BluetoothWidget完全指南配置、弹窗菜单与连接断开原理YASB 蓝牙组件BluetoothWidget完全指南配置、弹窗菜单与连接断开原理 本指南面向使用 YASB一款高度可配置的 Windows 状态栏桌面应用上一篇dynamic-datasource异步事务多数据源协调下一篇终极指南使用Skeleton.dev从零构建完整的管理后台系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考